blob: 6faae818bc183f481a5c0d551a3b0d9407c07ab5 [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) {
323 // Prefer a public header over a private header.
324 if ((New.getRole() & ModuleMap::PrivateHeader) !=
325 (Old.getRole() & ModuleMap::PrivateHeader))
326 return !(New.getRole() & ModuleMap::PrivateHeader);
327
328 // Prefer a non-textual header over a textual header.
329 if ((New.getRole() & ModuleMap::TextualHeader) !=
330 (Old.getRole() & ModuleMap::TextualHeader))
331 return !(New.getRole() & ModuleMap::TextualHeader);
332
333 // Don't have a reason to choose between these. Just keep the first one.
334 return false;
335}
336
Sean Silva4881e8b2015-06-10 01:37:59 +0000337ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Richard Smith306d8922014-10-22 23:50:56 +0000338 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Sean Silva8230e5e2015-06-04 23:38:11 +0000339 if (R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000340 return ModuleMap::KnownHeader();
341 return R;
342 };
343
Sean Silva4881e8b2015-06-10 01:37:59 +0000344 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000345 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000346 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000347 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000348 for (KnownHeader &H : Known->second) {
Richard Smith2f633e72015-06-22 22:20:47 +0000349 // Prefer a header from the current module over all others.
Richard Smith8692a4d2015-07-10 20:09:49 +0000350 if (H.getModule()->getTopLevelModule() == CompilingModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000351 return MakeResult(H);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000352 // Cannot use a module if it is unavailable.
Sean Silva4881e8b2015-06-10 01:37:59 +0000353 if (!H.getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000354 continue;
Sean Silva4881e8b2015-06-10 01:37:59 +0000355 if (!Result || isBetterKnownHeader(H, Result))
356 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000357 }
Richard Smith306d8922014-10-22 23:50:56 +0000358 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000359 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000360
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000361 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000362 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
363 if (H) {
364 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000365
Ben Langmuir44691382014-04-10 00:39:10 +0000366 // Search up the module stack until we find a module with an umbrella
367 // directory.
368 Module *UmbrellaModule = Result;
369 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
370 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000371
Ben Langmuir44691382014-04-10 00:39:10 +0000372 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000373 const FileEntry *UmbrellaModuleMap =
374 getModuleMapFileForUniquing(UmbrellaModule);
375
Ben Langmuir44691382014-04-10 00:39:10 +0000376 // Infer submodules for each of the directories we found between
377 // the directory of the umbrella header and the directory where
378 // the actual header is located.
379 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000380
Ben Langmuir44691382014-04-10 00:39:10 +0000381 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
382 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000383 SmallString<32> NameBuf;
384 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000385 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000386 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
387 Explicit).first;
388 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000389 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000390
391 // Associate the module and the directory.
392 UmbrellaDirs[SkippedDirs[I-1]] = Result;
393
394 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000395 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000396 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000397 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000398 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000399
Ben Langmuir44691382014-04-10 00:39:10 +0000400 // Infer a submodule with the same name as this header file.
401 SmallString<32> NameBuf;
402 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000403 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000404 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
405 Explicit).first;
406 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000407 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000408 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000409
Ben Langmuir44691382014-04-10 00:39:10 +0000410 // If inferred submodules export everything they import, add a
411 // wildcard to the set of exports.
412 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000413 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000414 } else {
415 // Record each of the directories we stepped through as being part of
416 // the module we found, since the umbrella header covers them all.
417 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
418 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000419 }
Ben Langmuir44691382014-04-10 00:39:10 +0000420
421 Headers[File].push_back(KnownHeader(Result, NormalHeader));
422
423 // If a header corresponds to an unavailable module, don't report
424 // that it maps to anything.
425 if (!Result->isAvailable())
426 return KnownHeader();
427
Richard Smith306d8922014-10-22 23:50:56 +0000428 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000429 }
Richard Smith306d8922014-10-22 23:50:56 +0000430
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000431 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000432}
433
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000434bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000435 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000436}
437
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000438bool
439ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
440 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000441 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000442 if (Known != Headers.end()) {
443 for (SmallVectorImpl<KnownHeader>::const_iterator
444 I = Known->second.begin(),
445 E = Known->second.end();
446 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000447 if (I->isAvailable() && (!RequestingModule ||
448 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000449 return false;
450 }
451 return true;
452 }
Richard Smith50996ce2014-04-08 13:13:04 +0000453
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000454 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000455 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000456 StringRef DirName = Dir->getName();
457
Richard Smith50996ce2014-04-08 13:13:04 +0000458 auto IsUnavailable = [&](const Module *M) {
459 return !M->isAvailable() && (!RequestingModule ||
460 M->isSubModuleOf(RequestingModule));
461 };
462
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000463 // Keep walking up the directory hierarchy, looking for a directory with
464 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000465 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000466 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000467 = UmbrellaDirs.find(Dir);
468 if (KnownDir != UmbrellaDirs.end()) {
469 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000470 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000471 return true;
472
473 // Search up the module stack until we find a module with an umbrella
474 // directory.
475 Module *UmbrellaModule = Found;
476 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
477 UmbrellaModule = UmbrellaModule->Parent;
478
479 if (UmbrellaModule->InferSubmodules) {
480 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
481 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000482 SmallString<32> NameBuf;
483 StringRef Name = sanitizeFilenameAsIdentifier(
484 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
485 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000486 Found = lookupModuleQualified(Name, Found);
487 if (!Found)
488 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000489 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 return true;
491 }
492
493 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000494 SmallString<32> NameBuf;
495 StringRef Name = sanitizeFilenameAsIdentifier(
496 llvm::sys::path::stem(Header->getName()),
497 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000498 Found = lookupModuleQualified(Name, Found);
499 if (!Found)
500 return false;
501 }
502
Richard Smith50996ce2014-04-08 13:13:04 +0000503 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000504 }
505
506 SkippedDirs.push_back(Dir);
507
508 // Retrieve our parent path.
509 DirName = llvm::sys::path::parent_path(DirName);
510 if (DirName.empty())
511 break;
512
513 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000514 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000515 } while (Dir);
516
517 return false;
518}
519
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000520Module *ModuleMap::findModule(StringRef Name) const {
521 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000522 if (Known != Modules.end())
523 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000524
525 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000526}
527
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000528Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
529 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000530 for(; Context; Context = Context->Parent) {
531 if (Module *Sub = lookupModuleQualified(Name, Context))
532 return Sub;
533 }
534
535 return findModule(Name);
536}
537
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000538Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000539 if (!Context)
540 return findModule(Name);
541
Douglas Gregoreb90e832012-01-04 23:32:19 +0000542 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000543}
544
Douglas Gregorde3ef502011-11-30 23:21:26 +0000545std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000546ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000547 bool IsExplicit) {
548 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000549 if (Module *Sub = lookupModuleQualified(Name, Parent))
550 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000551
552 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000553 Module *Result = new Module(Name, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000554 IsFramework, IsExplicit, NumCreatedModules++);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000555 if (LangOpts.CurrentModule == Name) {
556 SourceModule = Result;
557 SourceModuleName = Name;
558 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000559 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000560 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000561 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
562 Name == LangOpts.CurrentModule) {
563 CompilingModule = Result;
564 }
565 }
Douglas Gregor69021972011-11-30 17:33:56 +0000566 return std::make_pair(Result, true);
567}
568
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000569/// \brief For a framework module, infer the framework against which we
570/// should link.
571static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
572 FileManager &FileMgr) {
573 assert(Mod->IsFramework && "Can only infer linking for framework modules");
574 assert(!Mod->isSubFramework() &&
575 "Can only infer linking for top-level frameworks");
576
577 SmallString<128> LibName;
578 LibName += FrameworkDir->getName();
579 llvm::sys::path::append(LibName, Mod->Name);
580 if (FileMgr.getFile(LibName)) {
581 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
582 /*IsFramework=*/true));
583 }
584}
585
Ben Langmuira5254002015-07-02 13:19:48 +0000586Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
587 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000588 Attributes Attrs;
589 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000590 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000591}
592
Ben Langmuira5254002015-07-02 13:19:48 +0000593Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000594 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000595 // Note: as an egregious but useful hack we use the real path here, because
596 // we might be looking at an embedded framework that symlinks out to a
597 // top-level framework, and we need to infer as if we were naming the
598 // top-level framework.
599 StringRef FrameworkDirName =
600 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
601
602 // In case this is a case-insensitive filesystem, use the canonical
603 // directory name as the ModuleName, since modules are case-sensitive.
604 // FIXME: we should be able to give a fix-it hint for the correct spelling.
605 SmallString<32> ModuleNameStorage;
606 StringRef ModuleName = sanitizeFilenameAsIdentifier(
607 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000608
Douglas Gregor56c64012011-11-17 01:41:17 +0000609 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000610 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
611 return Mod;
612
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000613 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000614
615 // If the framework has a parent path from which we're allowed to infer
616 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000617 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000618 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000619 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000620 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000621 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000622 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000623 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000624 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
625 // Check whether we have already looked into the parent directory
626 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000627 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000628 inferred = InferredDirectories.find(ParentDir);
629 if (inferred == InferredDirectories.end()) {
630 // We haven't looked here before. Load a module map, if there is
631 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000632 bool IsFrameworkDir = Parent.endswith(".framework");
633 if (const FileEntry *ModMapFile =
634 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000635 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000636 inferred = InferredDirectories.find(ParentDir);
637 }
638
639 if (inferred == InferredDirectories.end())
640 inferred = InferredDirectories.insert(
641 std::make_pair(ParentDir, InferredDirectory())).first;
642 }
643
644 if (inferred->second.InferModules) {
645 // We're allowed to infer for this directory, but make sure it's okay
646 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000647 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000648 canInfer = std::find(inferred->second.ExcludedModules.begin(),
649 inferred->second.ExcludedModules.end(),
650 Name) == inferred->second.ExcludedModules.end();
651
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000652 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
653 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
654 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000655 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000656 }
657 }
658 }
659
660 // If we're not allowed to infer a framework module, don't.
661 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000662 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000663 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000664 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000665
666
Douglas Gregor56c64012011-11-17 01:41:17 +0000667 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000668 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000669 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000670 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000671
672 // FIXME: If there's no umbrella header, we could probably scan the
673 // framework to load *everything*. But, it's not clear that this is a good
674 // idea.
675 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000676 return nullptr;
677
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000678 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000679 /*IsFramework=*/true, /*IsExplicit=*/false,
680 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000681 InferredModuleAllowedBy[Result] = ModuleMapFile;
682 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000683 if (LangOpts.CurrentModule == ModuleName) {
684 SourceModule = Result;
685 SourceModuleName = ModuleName;
686 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000687
688 Result->IsSystem |= Attrs.IsSystem;
689 Result->IsExternC |= Attrs.IsExternC;
690 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Richard Smith2b63d152015-05-16 02:28:53 +0000691 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000692
Douglas Gregoreb90e832012-01-04 23:32:19 +0000693 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000694 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000695
Douglas Gregor322f6332011-12-08 18:00:48 +0000696 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000697 //
698 // The "Headers/" component of the name is implied because this is
699 // a framework module.
700 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000701
702 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000703 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
704
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000705 // module * { export * }
706 Result->InferSubmodules = true;
707 Result->InferExportWildcard = true;
708
Douglas Gregore89dbc12011-12-06 19:39:29 +0000709 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000710 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000711 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000712 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000713 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000714 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000715 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(".framework"))
718 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000719
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 if (const DirectoryEntry *SubframeworkDir
721 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000722 // Note: as an egregious but useful hack, we use the real path here and
723 // check whether it is actually a subdirectory of the parent directory.
724 // This will not be the case if the 'subframework' is actually a symlink
725 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000726 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
727 bool FoundParent = false;
728 do {
729 // Get the parent directory name.
730 SubframeworkDirName
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
733 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000734
Douglas Gregore00c8b22013-01-26 00:55:12 +0000735 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
736 FoundParent = true;
737 break;
738 }
739 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000740
Douglas Gregore00c8b22013-01-26 00:55:12 +0000741 if (!FoundParent)
742 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000743
Douglas Gregore89dbc12011-12-06 19:39:29 +0000744 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000745 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000746 }
747 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000748
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000749 // If the module is a top-level framework, automatically link against the
750 // framework.
751 if (!Result->isSubFramework()) {
752 inferFrameworkLink(Result, FrameworkDir, FileMgr);
753 }
754
Douglas Gregor56c64012011-11-17 01:41:17 +0000755 return Result;
756}
757
Richard Smith2b63d152015-05-16 02:28:53 +0000758void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
759 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000760 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000761 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000762 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000763 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000764}
765
Richard Smith2b63d152015-05-16 02:28:53 +0000766void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
767 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000768 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000769 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000770 UmbrellaDirs[UmbrellaDir] = Mod;
771}
772
Richard Smith3c1a41a2014-12-02 00:08:08 +0000773static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000774 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000775 default: llvm_unreachable("unknown header role");
776 case ModuleMap::NormalHeader:
777 return Module::HK_Normal;
778 case ModuleMap::PrivateHeader:
779 return Module::HK_Private;
780 case ModuleMap::TextualHeader:
781 return Module::HK_Textual;
782 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
783 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000784 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000785}
786
Richard Smith3c1a41a2014-12-02 00:08:08 +0000787void ModuleMap::addHeader(Module *Mod, Module::Header Header,
788 ModuleHeaderRole Role) {
789 if (!(Role & TextualHeader)) {
790 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
791 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
792 isCompilingModuleHeader);
793 }
794 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
Richard Smithfeb54b62014-10-23 02:01:19 +0000795
Richard Smith3c1a41a2014-12-02 00:08:08 +0000796 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
797}
798
799void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000800 // Add this as a known header so we won't implicitly add it to any
801 // umbrella directory module.
802 // FIXME: Should we only exclude it from umbrella modules within the
803 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000804 (void) Headers[Header.Entry];
805
806 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000807}
808
Douglas Gregor514b6362011-11-29 19:06:37 +0000809const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000810ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000811 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000812 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000813
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000814 return SourceMgr.getFileEntryForID(
815 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000816}
817
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000818const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000819 if (M->IsInferred) {
820 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
821 return InferredModuleAllowedBy.find(M)->second;
822 }
823 return getContainingModuleMapFile(M);
824}
825
826void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
827 assert(M->IsInferred && "module not inferred");
828 InferredModuleAllowedBy[M] = ModMap;
829}
830
Douglas Gregor718292f2011-11-11 19:10:28 +0000831void ModuleMap::dump() {
832 llvm::errs() << "Modules:";
833 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
834 MEnd = Modules.end();
835 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000836 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000837
838 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000839 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000840 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000841 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
842 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
843 E = H->second.end();
844 I != E; ++I) {
845 if (I != H->second.begin())
846 llvm::errs() << ",";
847 llvm::errs() << I->getModule()->getFullModuleName();
848 }
849 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000850 }
851}
852
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000853bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000854 auto Unresolved = std::move(Mod->UnresolvedExports);
855 Mod->UnresolvedExports.clear();
856 for (auto &UE : Unresolved) {
857 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000858 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000859 Mod->Exports.push_back(Export);
860 else
Richard Smith42413142015-05-15 20:05:43 +0000861 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000862 }
Richard Smith42413142015-05-15 20:05:43 +0000863 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000864}
865
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000866bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000867 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
868 Mod->UnresolvedDirectUses.clear();
869 for (auto &UDU : Unresolved) {
870 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000871 if (DirectUse)
872 Mod->DirectUses.push_back(DirectUse);
873 else
Richard Smith42413142015-05-15 20:05:43 +0000874 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000875 }
Richard Smith42413142015-05-15 20:05:43 +0000876 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000877}
878
Douglas Gregorfb912652013-03-20 21:10:35 +0000879bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000880 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000881 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000882 for (auto &UC : Unresolved) {
883 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
884 Module::Conflict Conflict;
885 Conflict.Other = OtherMod;
886 Conflict.Message = UC.Message;
887 Mod->Conflicts.push_back(Conflict);
888 } else
889 Mod->UnresolvedConflicts.push_back(UC);
890 }
891 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000892}
893
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000894Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
895 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000896 return nullptr;
897
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000898 // Use the expansion location to determine which module we're in.
899 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
900 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000901 return nullptr;
902
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000903 const SourceManager &SrcMgr = Loc.getManager();
904 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000905
Douglas Gregor224d8a72012-01-06 17:19:32 +0000906 while (const FileEntry *ExpansionFile
907 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
908 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000909 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000910 return Mod;
911
912 // No module owns this header, so look up the inclusion chain to see if
913 // any included header has an associated module.
914 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
915 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000916 return nullptr;
917
Douglas Gregor224d8a72012-01-06 17:19:32 +0000918 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
919 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000920
921 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000922}
923
Douglas Gregor718292f2011-11-11 19:10:28 +0000924//----------------------------------------------------------------------------//
925// Module map file parser
926//----------------------------------------------------------------------------//
927
928namespace clang {
929 /// \brief A token in a module map file.
930 struct MMToken {
931 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000932 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000933 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000934 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000935 EndOfFile,
936 HeaderKeyword,
937 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000938 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000939 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000940 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000941 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000942 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000943 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000944 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000945 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000946 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000947 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000948 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000949 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000950 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000951 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000952 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000953 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000954 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000955 RBrace,
956 LSquare,
957 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000958 } Kind;
959
960 unsigned Location;
961 unsigned StringLength;
962 const char *StringData;
963
964 void clear() {
965 Kind = EndOfFile;
966 Location = 0;
967 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000968 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000969 }
970
971 bool is(TokenKind K) const { return Kind == K; }
972
973 SourceLocation getLocation() const {
974 return SourceLocation::getFromRawEncoding(Location);
975 }
976
977 StringRef getString() const {
978 return StringRef(StringData, StringLength);
979 }
980 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000981
Douglas Gregor718292f2011-11-11 19:10:28 +0000982 class ModuleMapParser {
983 Lexer &L;
984 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000985
986 /// \brief Default target information, used only for string literal
987 /// parsing.
988 const TargetInfo *Target;
989
Douglas Gregor718292f2011-11-11 19:10:28 +0000990 DiagnosticsEngine &Diags;
991 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000992
993 /// \brief The current module map file.
994 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +0000995
Richard Smith9acb99e32014-12-10 03:09:48 +0000996 /// \brief The directory that file names in this module map file should
997 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +0000998 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000999
1000 /// \brief The directory containing Clang-supplied headers.
1001 const DirectoryEntry *BuiltinIncludeDir;
1002
Douglas Gregor963c5532013-06-21 16:28:10 +00001003 /// \brief Whether this module map is in a system header directory.
1004 bool IsSystem;
1005
Douglas Gregor718292f2011-11-11 19:10:28 +00001006 /// \brief Whether an error occurred.
1007 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001008
Douglas Gregor718292f2011-11-11 19:10:28 +00001009 /// \brief Stores string data for the various string literals referenced
1010 /// during parsing.
1011 llvm::BumpPtrAllocator StringData;
1012
1013 /// \brief The current token.
1014 MMToken Tok;
1015
1016 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001017 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001018
1019 /// \brief Consume the current token and return its location.
1020 SourceLocation consumeToken();
1021
1022 /// \brief Skip tokens until we reach the a token with the given kind
1023 /// (or the end of the file).
1024 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001025
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001026 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001027 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001028 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001029 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001030 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001031 void parseHeaderDecl(clang::MMToken::TokenKind,
1032 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001033 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001034 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001035 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001036 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001037 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001038 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001039 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001040
1041 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001042 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001043
Douglas Gregor718292f2011-11-11 19:10:28 +00001044 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001045 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001046 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001047 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001048 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001049 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001050 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001051 const DirectoryEntry *BuiltinIncludeDir,
1052 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001053 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001054 ModuleMapFile(ModuleMapFile), Directory(Directory),
1055 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001056 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001057 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001058 Tok.clear();
1059 consumeToken();
1060 }
1061
1062 bool parseModuleMapFile();
1063 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001064}
Douglas Gregor718292f2011-11-11 19:10:28 +00001065
1066SourceLocation ModuleMapParser::consumeToken() {
1067retry:
1068 SourceLocation Result = Tok.getLocation();
1069 Tok.clear();
1070
1071 Token LToken;
1072 L.LexFromRawLexer(LToken);
1073 Tok.Location = LToken.getLocation().getRawEncoding();
1074 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001075 case tok::raw_identifier: {
1076 StringRef RI = LToken.getRawIdentifier();
1077 Tok.StringData = RI.data();
1078 Tok.StringLength = RI.size();
1079 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001080 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001081 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001082 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001084 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001085 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001086 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001087 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001088 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001089 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001090 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001091 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001092 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001093 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001094 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001095 .Default(MMToken::Identifier);
1096 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001097 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001098
1099 case tok::comma:
1100 Tok.Kind = MMToken::Comma;
1101 break;
1102
Douglas Gregor718292f2011-11-11 19:10:28 +00001103 case tok::eof:
1104 Tok.Kind = MMToken::EndOfFile;
1105 break;
1106
1107 case tok::l_brace:
1108 Tok.Kind = MMToken::LBrace;
1109 break;
1110
Douglas Gregora686e1b2012-01-27 19:52:33 +00001111 case tok::l_square:
1112 Tok.Kind = MMToken::LSquare;
1113 break;
1114
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001115 case tok::period:
1116 Tok.Kind = MMToken::Period;
1117 break;
1118
Douglas Gregor718292f2011-11-11 19:10:28 +00001119 case tok::r_brace:
1120 Tok.Kind = MMToken::RBrace;
1121 break;
1122
Douglas Gregora686e1b2012-01-27 19:52:33 +00001123 case tok::r_square:
1124 Tok.Kind = MMToken::RSquare;
1125 break;
1126
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001127 case tok::star:
1128 Tok.Kind = MMToken::Star;
1129 break;
1130
Richard Smitha3feee22013-10-28 22:18:19 +00001131 case tok::exclaim:
1132 Tok.Kind = MMToken::Exclaim;
1133 break;
1134
Douglas Gregor718292f2011-11-11 19:10:28 +00001135 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001136 if (LToken.hasUDSuffix()) {
1137 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1138 HadError = true;
1139 goto retry;
1140 }
1141
Douglas Gregor718292f2011-11-11 19:10:28 +00001142 // Parse the string literal.
1143 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001144 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001145 if (StringLiteral.hadError)
1146 goto retry;
1147
1148 // Copy the string literal into our string data allocator.
1149 unsigned Length = StringLiteral.GetStringLength();
1150 char *Saved = StringData.Allocate<char>(Length + 1);
1151 memcpy(Saved, StringLiteral.GetString().data(), Length);
1152 Saved[Length] = 0;
1153
1154 // Form the token.
1155 Tok.Kind = MMToken::StringLiteral;
1156 Tok.StringData = Saved;
1157 Tok.StringLength = Length;
1158 break;
1159 }
1160
1161 case tok::comment:
1162 goto retry;
1163
1164 default:
1165 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1166 HadError = true;
1167 goto retry;
1168 }
1169
1170 return Result;
1171}
1172
1173void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1174 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001175 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001176 do {
1177 switch (Tok.Kind) {
1178 case MMToken::EndOfFile:
1179 return;
1180
1181 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001182 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001183 return;
1184
1185 ++braceDepth;
1186 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001187
1188 case MMToken::LSquare:
1189 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1190 return;
1191
1192 ++squareDepth;
1193 break;
1194
Douglas Gregor718292f2011-11-11 19:10:28 +00001195 case MMToken::RBrace:
1196 if (braceDepth > 0)
1197 --braceDepth;
1198 else if (Tok.is(K))
1199 return;
1200 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001201
1202 case MMToken::RSquare:
1203 if (squareDepth > 0)
1204 --squareDepth;
1205 else if (Tok.is(K))
1206 return;
1207 break;
1208
Douglas Gregor718292f2011-11-11 19:10:28 +00001209 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001210 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001211 return;
1212 break;
1213 }
1214
1215 consumeToken();
1216 } while (true);
1217}
1218
Douglas Gregore7ab3662011-12-07 02:23:45 +00001219/// \brief Parse a module-id.
1220///
1221/// module-id:
1222/// identifier
1223/// identifier '.' module-id
1224///
1225/// \returns true if an error occurred, false otherwise.
1226bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1227 Id.clear();
1228 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001229 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001230 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1231 consumeToken();
1232 } else {
1233 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1234 return true;
1235 }
1236
1237 if (!Tok.is(MMToken::Period))
1238 break;
1239
1240 consumeToken();
1241 } while (true);
1242
1243 return false;
1244}
1245
Douglas Gregora686e1b2012-01-27 19:52:33 +00001246namespace {
1247 /// \brief Enumerates the known attributes.
1248 enum AttributeKind {
1249 /// \brief An unknown attribute.
1250 AT_unknown,
1251 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001252 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001253 /// \brief The 'extern_c' attribute.
1254 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001255 /// \brief The 'exhaustive' attribute.
1256 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001257 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001258}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001259
Douglas Gregor718292f2011-11-11 19:10:28 +00001260/// \brief Parse a module declaration.
1261///
1262/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001263/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001264/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1265/// { module-member* }
1266///
Douglas Gregor718292f2011-11-11 19:10:28 +00001267/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001268/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001269/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001270/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001271/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001272/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001273///
1274/// submodule-declaration:
1275/// module-declaration
1276/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001277void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001278 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001279 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1280 if (Tok.is(MMToken::ExternKeyword)) {
1281 parseExternModuleDecl();
1282 return;
1283 }
1284
Douglas Gregorf2161a72011-12-06 17:16:41 +00001285 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001286 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001287 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001288 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001289
Douglas Gregorf2161a72011-12-06 17:16:41 +00001290 // Parse 'explicit' keyword, if present.
1291 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001292 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001293 Explicit = true;
1294 }
1295
1296 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001297 if (Tok.is(MMToken::FrameworkKeyword)) {
1298 consumeToken();
1299 Framework = true;
1300 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001301
1302 // Parse 'module' keyword.
1303 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001304 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001305 consumeToken();
1306 HadError = true;
1307 return;
1308 }
1309 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001310
1311 // If we have a wildcard for the module name, this is an inferred submodule.
1312 // Parse it.
1313 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001314 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001315
1316 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001317 ModuleId Id;
1318 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001319 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001320 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001321 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001322
Douglas Gregore7ab3662011-12-07 02:23:45 +00001323 if (ActiveModule) {
1324 if (Id.size() > 1) {
1325 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1326 << SourceRange(Id.front().second, Id.back().second);
1327
1328 HadError = true;
1329 return;
1330 }
1331 } else if (Id.size() == 1 && Explicit) {
1332 // Top-level modules can't be explicit.
1333 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1334 Explicit = false;
1335 ExplicitLoc = SourceLocation();
1336 HadError = true;
1337 }
1338
1339 Module *PreviousActiveModule = ActiveModule;
1340 if (Id.size() > 1) {
1341 // This module map defines a submodule. Go find the module of which it
1342 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001343 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001344 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001345 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1346 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001347 if (I == 0)
1348 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001349 ActiveModule = Next;
1350 continue;
1351 }
1352
1353 if (ActiveModule) {
1354 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001355 << Id[I].first
1356 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001357 } else {
1358 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1359 }
1360 HadError = true;
1361 return;
1362 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001363
1364 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1365 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1366 "submodule defined in same file as 'module *' that allowed its "
1367 "top-level module");
1368 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1369 }
1370 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001371
1372 StringRef ModuleName = Id.back().first;
1373 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001374
Douglas Gregora686e1b2012-01-27 19:52:33 +00001375 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001376 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001377 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001378
Douglas Gregor718292f2011-11-11 19:10:28 +00001379 // Parse the opening brace.
1380 if (!Tok.is(MMToken::LBrace)) {
1381 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1382 << ModuleName;
1383 HadError = true;
1384 return;
1385 }
1386 SourceLocation LBraceLoc = consumeToken();
1387
1388 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001389 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001390 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1391 // Skip the module definition.
1392 skipUntil(MMToken::RBrace);
1393 if (Tok.is(MMToken::RBrace))
1394 consumeToken();
1395 else {
1396 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1397 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1398 HadError = true;
1399 }
1400 return;
1401 }
1402
Douglas Gregor718292f2011-11-11 19:10:28 +00001403 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1404 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001405 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001406
1407 // Skip the module definition.
1408 skipUntil(MMToken::RBrace);
1409 if (Tok.is(MMToken::RBrace))
1410 consumeToken();
1411
1412 HadError = true;
1413 return;
1414 }
1415
1416 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001417 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1418 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001419 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001420 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001421 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001422 if (Attrs.IsExternC)
1423 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001424 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001425
Douglas Gregor718292f2011-11-11 19:10:28 +00001426 bool Done = false;
1427 do {
1428 switch (Tok.Kind) {
1429 case MMToken::EndOfFile:
1430 case MMToken::RBrace:
1431 Done = true;
1432 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001433
1434 case MMToken::ConfigMacros:
1435 parseConfigMacros();
1436 break;
1437
Douglas Gregorfb912652013-03-20 21:10:35 +00001438 case MMToken::Conflict:
1439 parseConflict();
1440 break;
1441
Douglas Gregor718292f2011-11-11 19:10:28 +00001442 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001443 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001444 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001445 case MMToken::ModuleKeyword:
1446 parseModuleDecl();
1447 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001448
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001449 case MMToken::ExportKeyword:
1450 parseExportDecl();
1451 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001452
1453 case MMToken::UseKeyword:
1454 parseUseDecl();
1455 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001456
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001457 case MMToken::RequiresKeyword:
1458 parseRequiresDecl();
1459 break;
1460
Richard Smith202210b2014-10-24 20:23:01 +00001461 case MMToken::TextualKeyword:
1462 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001463 break;
Richard Smith306d8922014-10-22 23:50:56 +00001464
Douglas Gregor524e33e2011-12-08 19:11:24 +00001465 case MMToken::UmbrellaKeyword: {
1466 SourceLocation UmbrellaLoc = consumeToken();
1467 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001468 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001469 else
1470 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001471 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001472 }
Richard Smith202210b2014-10-24 20:23:01 +00001473
1474 case MMToken::ExcludeKeyword:
1475 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001476 break;
Richard Smith202210b2014-10-24 20:23:01 +00001477
1478 case MMToken::PrivateKeyword:
1479 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001480 break;
Richard Smith202210b2014-10-24 20:23:01 +00001481
Douglas Gregor322f6332011-12-08 18:00:48 +00001482 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001483 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001484 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001485
1486 case MMToken::LinkKeyword:
1487 parseLinkDecl();
1488 break;
1489
Douglas Gregor718292f2011-11-11 19:10:28 +00001490 default:
1491 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1492 consumeToken();
1493 break;
1494 }
1495 } while (!Done);
1496
1497 if (Tok.is(MMToken::RBrace))
1498 consumeToken();
1499 else {
1500 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1501 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1502 HadError = true;
1503 }
1504
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001505 // If the active module is a top-level framework, and there are no link
1506 // libraries, automatically link against the framework.
1507 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1508 ActiveModule->LinkLibraries.empty()) {
1509 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1510 }
1511
Ben Langmuirec8c9752014-04-18 22:07:31 +00001512 // If the module meets all requirements but is still unavailable, mark the
1513 // whole tree as unavailable to prevent it from building.
1514 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1515 ActiveModule->Parent) {
1516 ActiveModule->getTopLevelModule()->markUnavailable();
1517 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1518 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1519 }
1520
Douglas Gregore7ab3662011-12-07 02:23:45 +00001521 // We're done parsing this module. Pop back to the previous module.
1522 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001523}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001524
Daniel Jasper97292842013-09-11 07:20:44 +00001525/// \brief Parse an extern module declaration.
1526///
1527/// extern module-declaration:
1528/// 'extern' 'module' module-id string-literal
1529void ModuleMapParser::parseExternModuleDecl() {
1530 assert(Tok.is(MMToken::ExternKeyword));
1531 consumeToken(); // 'extern' keyword
1532
1533 // Parse 'module' keyword.
1534 if (!Tok.is(MMToken::ModuleKeyword)) {
1535 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1536 consumeToken();
1537 HadError = true;
1538 return;
1539 }
1540 consumeToken(); // 'module' keyword
1541
1542 // Parse the module name.
1543 ModuleId Id;
1544 if (parseModuleId(Id)) {
1545 HadError = true;
1546 return;
1547 }
1548
1549 // Parse the referenced module map file name.
1550 if (!Tok.is(MMToken::StringLiteral)) {
1551 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1552 HadError = true;
1553 return;
1554 }
1555 std::string FileName = Tok.getString();
1556 consumeToken(); // filename
1557
1558 StringRef FileNameRef = FileName;
1559 SmallString<128> ModuleMapFileName;
1560 if (llvm::sys::path::is_relative(FileNameRef)) {
1561 ModuleMapFileName += Directory->getName();
1562 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001563 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001564 }
1565 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001566 Map.parseModuleMapFile(
1567 File, /*IsSystem=*/false,
1568 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1569 ? Directory
1570 : File->getDir());
Daniel Jasper97292842013-09-11 07:20:44 +00001571}
1572
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001573/// \brief Parse a requires declaration.
1574///
1575/// requires-declaration:
1576/// 'requires' feature-list
1577///
1578/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001579/// feature ',' feature-list
1580/// feature
1581///
1582/// feature:
1583/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001584void ModuleMapParser::parseRequiresDecl() {
1585 assert(Tok.is(MMToken::RequiresKeyword));
1586
1587 // Parse 'requires' keyword.
1588 consumeToken();
1589
1590 // Parse the feature-list.
1591 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001592 bool RequiredState = true;
1593 if (Tok.is(MMToken::Exclaim)) {
1594 RequiredState = false;
1595 consumeToken();
1596 }
1597
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001598 if (!Tok.is(MMToken::Identifier)) {
1599 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1600 HadError = true;
1601 return;
1602 }
1603
1604 // Consume the feature name.
1605 std::string Feature = Tok.getString();
1606 consumeToken();
1607
1608 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001609 ActiveModule->addRequirement(Feature, RequiredState,
1610 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001611
1612 if (!Tok.is(MMToken::Comma))
1613 break;
1614
1615 // Consume the comma.
1616 consumeToken();
1617 } while (true);
1618}
1619
Douglas Gregorf2161a72011-12-06 17:16:41 +00001620/// \brief Append to \p Paths the set of paths needed to get to the
1621/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001622static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001623 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001624 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001625 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001626 for (; Mod; Mod = Mod->Parent) {
1627 if (Mod->IsFramework)
1628 Paths.push_back(Mod->Name);
1629 }
1630
1631 if (Paths.empty())
1632 return;
1633
1634 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001635 for (unsigned I = Paths.size() - 1; I != 0; --I)
1636 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001637}
1638
Douglas Gregor718292f2011-11-11 19:10:28 +00001639/// \brief Parse a header declaration.
1640///
1641/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001642/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001643/// 'private' 'textual'[opt] 'header' string-literal
1644/// 'exclude' 'header' string-literal
1645/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001646///
1647/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001648void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1649 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001650 // We've already consumed the first token.
1651 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1652 if (LeadingToken == MMToken::PrivateKeyword) {
1653 Role = ModuleMap::PrivateHeader;
1654 // 'private' may optionally be followed by 'textual'.
1655 if (Tok.is(MMToken::TextualKeyword)) {
1656 LeadingToken = Tok.Kind;
1657 consumeToken();
1658 }
1659 }
1660 if (LeadingToken == MMToken::TextualKeyword)
1661 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1662
1663 if (LeadingToken != MMToken::HeaderKeyword) {
1664 if (!Tok.is(MMToken::HeaderKeyword)) {
1665 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1666 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1667 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1668 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1669 return;
1670 }
1671 consumeToken();
1672 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001673
Douglas Gregor718292f2011-11-11 19:10:28 +00001674 // Parse the header name.
1675 if (!Tok.is(MMToken::StringLiteral)) {
1676 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1677 << "header";
1678 HadError = true;
1679 return;
1680 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001681 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001682 Header.FileName = Tok.getString();
1683 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001684
Douglas Gregor524e33e2011-12-08 19:11:24 +00001685 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001686 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001687 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001688 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001689 HadError = true;
1690 return;
1691 }
1692
Douglas Gregor5257fc62011-11-11 21:55:48 +00001693 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001694 const FileEntry *File = nullptr;
1695 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001696 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001697 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001698 RelativePathName = Header.FileName;
1699 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001700 } else {
1701 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001702 SmallString<128> FullPathName(Directory->getName());
1703 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001704
Douglas Gregorf2161a72011-12-06 17:16:41 +00001705 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001706 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001707
1708 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001709 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001710 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001711 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001712
1713 if (!File) {
1714 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001715 // FIXME: Should we retain the subframework paths here?
1716 RelativePathName.clear();
1717 FullPathName.resize(FullPathLength);
1718 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1719 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001720 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001721 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001722 }
1723 } else {
1724 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001725 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001726 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001727 File = SourceMgr.getFileManager().getFile(FullPathName);
1728
Douglas Gregor3ec66632012-02-02 18:42:48 +00001729 // If this is a system module with a top-level header, this header
1730 // may have a counterpart (or replacement) in the set of headers
1731 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001732 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1733 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001734 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001735 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001736 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001737 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001738
Douglas Gregor3ec66632012-02-02 18:42:48 +00001739 // If Clang supplies this header but the underlying system does not,
1740 // just silently swap in our builtin version. Otherwise, we'll end
1741 // up adding both (later).
Richard Smith42413142015-05-15 20:05:43 +00001742 //
1743 // For local visibility, entirely replace the system file with our
1744 // one and textually include the system one. We need to pass macros
1745 // from our header to the system one if we #include_next it.
1746 //
1747 // FIXME: Can we do this in all cases?
1748 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001749 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001750 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001751 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001752 }
1753 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001754 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001755 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001756
Douglas Gregor5257fc62011-11-11 21:55:48 +00001757 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1758 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001759 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001760 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001761 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001762 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001763 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001764 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001765 HadError = true;
1766 } else {
1767 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001768 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001769 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001770 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001771 Module::Header H = {RelativePathName.str(), File};
1772 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001773 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001774 // If there is a builtin counterpart to this file, add it now, before
1775 // the "real" header, so we build the built-in one first when building
1776 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001777 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001778 // FIXME: Taking the name from the FileEntry is unstable and can give
1779 // different results depending on how we've previously named that file
1780 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001781 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1782 Map.addHeader(ActiveModule, H, Role);
1783 }
Richard Smith25d50752014-10-20 00:15:49 +00001784
Richard Smith202210b2014-10-24 20:23:01 +00001785 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001786 Module::Header H = { RelativePathName.str(), File };
1787 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001788 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001789 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001790 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001791
1792 // If we find a module that has a missing header, we mark this module as
1793 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001794 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001795 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001796 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001797 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001798}
1799
Douglas Gregor524e33e2011-12-08 19:11:24 +00001800/// \brief Parse an umbrella directory declaration.
1801///
1802/// umbrella-dir-declaration:
1803/// umbrella string-literal
1804void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1805 // Parse the directory name.
1806 if (!Tok.is(MMToken::StringLiteral)) {
1807 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1808 << "umbrella";
1809 HadError = true;
1810 return;
1811 }
1812
1813 std::string DirName = Tok.getString();
1814 SourceLocation DirNameLoc = consumeToken();
1815
1816 // Check whether we already have an umbrella.
1817 if (ActiveModule->Umbrella) {
1818 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1819 << ActiveModule->getFullModuleName();
1820 HadError = true;
1821 return;
1822 }
1823
1824 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001825 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001826 if (llvm::sys::path::is_absolute(DirName))
1827 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1828 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001829 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001830 PathName = Directory->getName();
1831 llvm::sys::path::append(PathName, DirName);
1832 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1833 }
1834
1835 if (!Dir) {
1836 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1837 << DirName;
1838 HadError = true;
1839 return;
1840 }
1841
1842 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1843 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1844 << OwningModule->getFullModuleName();
1845 HadError = true;
1846 return;
1847 }
1848
1849 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00001850 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001851}
1852
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001853/// \brief Parse a module export declaration.
1854///
1855/// export-declaration:
1856/// 'export' wildcard-module-id
1857///
1858/// wildcard-module-id:
1859/// identifier
1860/// '*'
1861/// identifier '.' wildcard-module-id
1862void ModuleMapParser::parseExportDecl() {
1863 assert(Tok.is(MMToken::ExportKeyword));
1864 SourceLocation ExportLoc = consumeToken();
1865
1866 // Parse the module-id with an optional wildcard at the end.
1867 ModuleId ParsedModuleId;
1868 bool Wildcard = false;
1869 do {
Richard Smith306d8922014-10-22 23:50:56 +00001870 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001871 if (Tok.is(MMToken::Identifier)) {
1872 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1873 Tok.getLocation()));
1874 consumeToken();
1875
1876 if (Tok.is(MMToken::Period)) {
1877 consumeToken();
1878 continue;
1879 }
1880
1881 break;
1882 }
1883
1884 if(Tok.is(MMToken::Star)) {
1885 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001886 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001887 break;
1888 }
1889
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001890 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001891 HadError = true;
1892 return;
1893 } while (true);
1894
1895 Module::UnresolvedExportDecl Unresolved = {
1896 ExportLoc, ParsedModuleId, Wildcard
1897 };
1898 ActiveModule->UnresolvedExports.push_back(Unresolved);
1899}
1900
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001901/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001902///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001903/// use-declaration:
1904/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001905void ModuleMapParser::parseUseDecl() {
1906 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001907 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001908 // Parse the module-id.
1909 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001910 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001911
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001912 if (ActiveModule->Parent)
1913 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
1914 else
1915 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001916}
1917
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001918/// \brief Parse a link declaration.
1919///
1920/// module-declaration:
1921/// 'link' 'framework'[opt] string-literal
1922void ModuleMapParser::parseLinkDecl() {
1923 assert(Tok.is(MMToken::LinkKeyword));
1924 SourceLocation LinkLoc = consumeToken();
1925
1926 // Parse the optional 'framework' keyword.
1927 bool IsFramework = false;
1928 if (Tok.is(MMToken::FrameworkKeyword)) {
1929 consumeToken();
1930 IsFramework = true;
1931 }
1932
1933 // Parse the library name
1934 if (!Tok.is(MMToken::StringLiteral)) {
1935 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1936 << IsFramework << SourceRange(LinkLoc);
1937 HadError = true;
1938 return;
1939 }
1940
1941 std::string LibraryName = Tok.getString();
1942 consumeToken();
1943 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1944 IsFramework));
1945}
1946
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001947/// \brief Parse a configuration macro declaration.
1948///
1949/// module-declaration:
1950/// 'config_macros' attributes[opt] config-macro-list?
1951///
1952/// config-macro-list:
1953/// identifier (',' identifier)?
1954void ModuleMapParser::parseConfigMacros() {
1955 assert(Tok.is(MMToken::ConfigMacros));
1956 SourceLocation ConfigMacrosLoc = consumeToken();
1957
1958 // Only top-level modules can have configuration macros.
1959 if (ActiveModule->Parent) {
1960 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1961 }
1962
1963 // Parse the optional attributes.
1964 Attributes Attrs;
1965 parseOptionalAttributes(Attrs);
1966 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1967 ActiveModule->ConfigMacrosExhaustive = true;
1968 }
1969
1970 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001971 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001972 if (!Tok.is(MMToken::Identifier))
1973 return;
1974
1975 // Consume the first identifier.
1976 if (!ActiveModule->Parent) {
1977 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1978 }
1979 consumeToken();
1980
1981 do {
1982 // If there's a comma, consume it.
1983 if (!Tok.is(MMToken::Comma))
1984 break;
1985 consumeToken();
1986
1987 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00001988 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001989 if (!Tok.is(MMToken::Identifier)) {
1990 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1991 break;
1992 }
1993
1994 // Consume the macro name.
1995 if (!ActiveModule->Parent) {
1996 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1997 }
1998 consumeToken();
1999 } while (true);
2000}
2001
Douglas Gregorfb912652013-03-20 21:10:35 +00002002/// \brief Format a module-id into a string.
2003static std::string formatModuleId(const ModuleId &Id) {
2004 std::string result;
2005 {
2006 llvm::raw_string_ostream OS(result);
2007
2008 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2009 if (I)
2010 OS << ".";
2011 OS << Id[I].first;
2012 }
2013 }
2014
2015 return result;
2016}
2017
2018/// \brief Parse a conflict declaration.
2019///
2020/// module-declaration:
2021/// 'conflict' module-id ',' string-literal
2022void ModuleMapParser::parseConflict() {
2023 assert(Tok.is(MMToken::Conflict));
2024 SourceLocation ConflictLoc = consumeToken();
2025 Module::UnresolvedConflict Conflict;
2026
2027 // Parse the module-id.
2028 if (parseModuleId(Conflict.Id))
2029 return;
2030
2031 // Parse the ','.
2032 if (!Tok.is(MMToken::Comma)) {
2033 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2034 << SourceRange(ConflictLoc);
2035 return;
2036 }
2037 consumeToken();
2038
2039 // Parse the message.
2040 if (!Tok.is(MMToken::StringLiteral)) {
2041 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2042 << formatModuleId(Conflict.Id);
2043 return;
2044 }
2045 Conflict.Message = Tok.getString().str();
2046 consumeToken();
2047
2048 // Add this unresolved conflict.
2049 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2050}
2051
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002052/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002053///
2054/// module-declaration:
2055/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2056/// { inferred-module-member* }
2057///
2058/// inferred-module-member:
2059/// 'export' '*'
2060/// 'exclude' identifier
2061void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002062 assert(Tok.is(MMToken::Star));
2063 SourceLocation StarLoc = consumeToken();
2064 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002065
Douglas Gregor73441092011-12-05 22:27:44 +00002066 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002067 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002068 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2069 Failed = true;
2070 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002071
2072 if (ActiveModule) {
2073 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002074 if (!Failed && ActiveModule->IsAvailable &&
2075 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002076 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2077 Failed = true;
2078 }
2079
2080 // Check for redefinition of an inferred module.
2081 if (!Failed && ActiveModule->InferSubmodules) {
2082 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2083 if (ActiveModule->InferredSubmoduleLoc.isValid())
2084 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2085 diag::note_mmap_prev_definition);
2086 Failed = true;
2087 }
2088
2089 // Check for the 'framework' keyword, which is not permitted here.
2090 if (Framework) {
2091 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2092 Framework = false;
2093 }
2094 } else if (Explicit) {
2095 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2096 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002097 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002098
Douglas Gregor73441092011-12-05 22:27:44 +00002099 // If there were any problems with this inferred submodule, skip its body.
2100 if (Failed) {
2101 if (Tok.is(MMToken::LBrace)) {
2102 consumeToken();
2103 skipUntil(MMToken::RBrace);
2104 if (Tok.is(MMToken::RBrace))
2105 consumeToken();
2106 }
2107 HadError = true;
2108 return;
2109 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002110
2111 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002112 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002113 parseOptionalAttributes(Attrs);
2114
2115 if (ActiveModule) {
2116 // Note that we have an inferred submodule.
2117 ActiveModule->InferSubmodules = true;
2118 ActiveModule->InferredSubmoduleLoc = StarLoc;
2119 ActiveModule->InferExplicitSubmodules = Explicit;
2120 } else {
2121 // We'll be inferring framework modules for this directory.
2122 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002123 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002124 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002125 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002126 }
2127
Douglas Gregor73441092011-12-05 22:27:44 +00002128 // Parse the opening brace.
2129 if (!Tok.is(MMToken::LBrace)) {
2130 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2131 HadError = true;
2132 return;
2133 }
2134 SourceLocation LBraceLoc = consumeToken();
2135
2136 // Parse the body of the inferred submodule.
2137 bool Done = false;
2138 do {
2139 switch (Tok.Kind) {
2140 case MMToken::EndOfFile:
2141 case MMToken::RBrace:
2142 Done = true;
2143 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002144
2145 case MMToken::ExcludeKeyword: {
2146 if (ActiveModule) {
2147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002148 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002149 consumeToken();
2150 break;
2151 }
2152
2153 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002154 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002155 if (!Tok.is(MMToken::Identifier)) {
2156 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2157 break;
2158 }
2159
2160 Map.InferredDirectories[Directory].ExcludedModules
2161 .push_back(Tok.getString());
2162 consumeToken();
2163 break;
2164 }
2165
2166 case MMToken::ExportKeyword:
2167 if (!ActiveModule) {
2168 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002169 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002170 consumeToken();
2171 break;
2172 }
2173
Douglas Gregor73441092011-12-05 22:27:44 +00002174 consumeToken();
2175 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002176 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002177 else
2178 Diags.Report(Tok.getLocation(),
2179 diag::err_mmap_expected_export_wildcard);
2180 consumeToken();
2181 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002182
Douglas Gregor73441092011-12-05 22:27:44 +00002183 case MMToken::ExplicitKeyword:
2184 case MMToken::ModuleKeyword:
2185 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002186 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002187 case MMToken::UmbrellaKeyword:
2188 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002189 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002190 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002191 consumeToken();
2192 break;
2193 }
2194 } while (!Done);
2195
2196 if (Tok.is(MMToken::RBrace))
2197 consumeToken();
2198 else {
2199 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2200 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2201 HadError = true;
2202 }
2203}
2204
Douglas Gregor9194a912012-11-06 19:39:40 +00002205/// \brief Parse optional attributes.
2206///
2207/// attributes:
2208/// attribute attributes
2209/// attribute
2210///
2211/// attribute:
2212/// [ identifier ]
2213///
2214/// \param Attrs Will be filled in with the parsed attributes.
2215///
2216/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002217bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002218 bool HadError = false;
2219
2220 while (Tok.is(MMToken::LSquare)) {
2221 // Consume the '['.
2222 SourceLocation LSquareLoc = consumeToken();
2223
2224 // Check whether we have an attribute name here.
2225 if (!Tok.is(MMToken::Identifier)) {
2226 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2227 skipUntil(MMToken::RSquare);
2228 if (Tok.is(MMToken::RSquare))
2229 consumeToken();
2230 HadError = true;
2231 }
2232
2233 // Decode the attribute name.
2234 AttributeKind Attribute
2235 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002236 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002237 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002238 .Case("system", AT_system)
2239 .Default(AT_unknown);
2240 switch (Attribute) {
2241 case AT_unknown:
2242 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2243 << Tok.getString();
2244 break;
2245
2246 case AT_system:
2247 Attrs.IsSystem = true;
2248 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002249
Richard Smith77944862014-03-02 05:58:18 +00002250 case AT_extern_c:
2251 Attrs.IsExternC = true;
2252 break;
2253
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002254 case AT_exhaustive:
2255 Attrs.IsExhaustive = true;
2256 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002257 }
2258 consumeToken();
2259
2260 // Consume the ']'.
2261 if (!Tok.is(MMToken::RSquare)) {
2262 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2263 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2264 skipUntil(MMToken::RSquare);
2265 HadError = true;
2266 }
2267
2268 if (Tok.is(MMToken::RSquare))
2269 consumeToken();
2270 }
2271
2272 return HadError;
2273}
2274
Douglas Gregor718292f2011-11-11 19:10:28 +00002275/// \brief Parse a module map file.
2276///
2277/// module-map-file:
2278/// module-declaration*
2279bool ModuleMapParser::parseModuleMapFile() {
2280 do {
2281 switch (Tok.Kind) {
2282 case MMToken::EndOfFile:
2283 return HadError;
2284
Douglas Gregore7ab3662011-12-07 02:23:45 +00002285 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002286 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002287 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002288 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002289 parseModuleDecl();
2290 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002291
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002292 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002293 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002294 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002295 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002296 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002297 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002298 case MMToken::HeaderKeyword:
2299 case MMToken::Identifier:
2300 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002301 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002302 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002303 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002304 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002305 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002306 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002307 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002308 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002309 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002310 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002311 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002312 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002313 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2314 HadError = true;
2315 consumeToken();
2316 break;
2317 }
2318 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002319}
2320
Richard Smith9acb99e32014-12-10 03:09:48 +00002321bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2322 const DirectoryEntry *Dir) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002323 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2324 = ParsedModuleMap.find(File);
2325 if (Known != ParsedModuleMap.end())
2326 return Known->second;
2327
Craig Topperd2d442c2014-05-17 23:10:59 +00002328 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002329 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2330 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002331 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002332 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002333 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002334
Douglas Gregor718292f2011-11-11 19:10:28 +00002335 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002336 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002337 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002338 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002339 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002340 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002341 return Result;
2342}