blob: c66bd70487fd85b39d17f65afb4e9d516a7109b6 [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
Manuel Klimeke8bd0db2015-11-05 15:24:47 +0000234 return IsPrivateRole && (!RequestingModule ||
235 RequestedModule->getTopLevelModule() !=
236 RequestingModule->getTopLevelModule());
Daniel Jasper92669ee2013-12-20 12:09:36 +0000237}
238
Ben Langmuir71e1a642014-05-05 21:44:13 +0000239static Module *getTopLevelOrNull(Module *M) {
240 return M ? M->getTopLevelModule() : nullptr;
241}
242
Daniel Jasper92669ee2013-12-20 12:09:36 +0000243void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
244 SourceLocation FilenameLoc,
245 StringRef Filename,
246 const FileEntry *File) {
247 // No errors for indirect modules. This may be a bit of a problem for modules
248 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000249 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000250 return;
251
252 if (RequestingModule)
253 resolveUses(RequestingModule, /*Complain=*/false);
254
Ben Langmuir71e1a642014-05-05 21:44:13 +0000255 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000256 Module *Private = nullptr;
257 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000258
Ben Langmuir71e1a642014-05-05 21:44:13 +0000259 HeadersMap::iterator Known = findKnownHeader(File);
260 if (Known != Headers.end()) {
261 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000262 // Remember private headers for later printing of a diagnostic.
263 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
264 Header.getModule())) {
265 Private = Header.getModule();
266 continue;
267 }
268
269 // If uses need to be specified explicitly, we are only allowed to return
270 // modules that are explicitly used by the requesting module.
271 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000272 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000273 NotUsed = Header.getModule();
274 continue;
275 }
276
277 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000278 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000279 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000280
281 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000282 }
283
284 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000285 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000286 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000287 << Filename;
288 return;
289 }
290
291 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000292 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000293 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000294 << RequestingModule->getFullModuleName() << Filename;
295 return;
296 }
297
Ben Langmuir71e1a642014-05-05 21:44:13 +0000298 if (Excluded || isHeaderInUmbrellaDirs(File))
299 return;
300
301 // At this point, only non-modular includes remain.
302
303 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000304 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000305 << RequestingModule->getFullModuleName() << Filename;
306 } else if (RequestingModule) {
307 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
308 diag::warn_non_modular_include_in_framework_module :
309 diag::warn_non_modular_include_in_module;
310 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000311 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000312}
313
Richard Smithec87a502015-02-13 23:50:20 +0000314static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
315 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000316 // Prefer available modules.
317 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
318 return true;
319
Richard Smithec87a502015-02-13 23:50:20 +0000320 // Prefer a public header over a private header.
321 if ((New.getRole() & ModuleMap::PrivateHeader) !=
322 (Old.getRole() & ModuleMap::PrivateHeader))
323 return !(New.getRole() & ModuleMap::PrivateHeader);
324
325 // Prefer a non-textual header over a textual header.
326 if ((New.getRole() & ModuleMap::TextualHeader) !=
327 (Old.getRole() & ModuleMap::TextualHeader))
328 return !(New.getRole() & ModuleMap::TextualHeader);
329
330 // Don't have a reason to choose between these. Just keep the first one.
331 return false;
332}
333
Sean Silva4881e8b2015-06-10 01:37:59 +0000334ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Richard Smith306d8922014-10-22 23:50:56 +0000335 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Sean Silva8230e5e2015-06-04 23:38:11 +0000336 if (R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000337 return ModuleMap::KnownHeader();
338 return R;
339 };
340
Sean Silva4881e8b2015-06-10 01:37:59 +0000341 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000342 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000343 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000344 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000345 for (KnownHeader &H : Known->second) {
Richard Smith2f633e72015-06-22 22:20:47 +0000346 // Prefer a header from the current module over all others.
Richard Smith8692a4d2015-07-10 20:09:49 +0000347 if (H.getModule()->getTopLevelModule() == CompilingModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000348 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000349 if (!Result || isBetterKnownHeader(H, Result))
350 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000351 }
Richard Smith306d8922014-10-22 23:50:56 +0000352 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000353 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000354
Richard Smith386bb072015-08-18 23:42:23 +0000355 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
356}
357
358ModuleMap::KnownHeader
359ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
360 assert(!Headers.count(File) && "already have a module for this header");
361
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000362 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000363 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
364 if (H) {
365 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000366
Ben Langmuir44691382014-04-10 00:39:10 +0000367 // Search up the module stack until we find a module with an umbrella
368 // directory.
369 Module *UmbrellaModule = Result;
370 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
371 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000372
Ben Langmuir44691382014-04-10 00:39:10 +0000373 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000374 const FileEntry *UmbrellaModuleMap =
375 getModuleMapFileForUniquing(UmbrellaModule);
376
Ben Langmuir44691382014-04-10 00:39:10 +0000377 // Infer submodules for each of the directories we found between
378 // the directory of the umbrella header and the directory where
379 // the actual header is located.
380 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000381
Ben Langmuir44691382014-04-10 00:39:10 +0000382 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
383 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000384 SmallString<32> NameBuf;
385 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000386 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000387 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
388 Explicit).first;
389 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000390 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000391
392 // Associate the module and the directory.
393 UmbrellaDirs[SkippedDirs[I-1]] = Result;
394
395 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000396 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000397 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000398 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000399 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000400
Ben Langmuir44691382014-04-10 00:39:10 +0000401 // Infer a submodule with the same name as this header file.
402 SmallString<32> NameBuf;
403 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000404 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000405 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
406 Explicit).first;
407 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000408 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000409 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000410
Ben Langmuir44691382014-04-10 00:39:10 +0000411 // If inferred submodules export everything they import, add a
412 // wildcard to the set of exports.
413 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000414 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000415 } else {
416 // Record each of the directories we stepped through as being part of
417 // the module we found, since the umbrella header covers them all.
418 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
419 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000420 }
Ben Langmuir44691382014-04-10 00:39:10 +0000421
Richard Smith386bb072015-08-18 23:42:23 +0000422 KnownHeader Header(Result, NormalHeader);
423 Headers[File].push_back(Header);
424 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000425 }
Richard Smith306d8922014-10-22 23:50:56 +0000426
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000427 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000428}
429
Richard Smith386bb072015-08-18 23:42:23 +0000430ArrayRef<ModuleMap::KnownHeader>
431ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
432 auto It = Headers.find(File);
433 if (It == Headers.end())
434 return None;
435 return It->second;
436}
437
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000438bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000439 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000440}
441
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000442bool
443ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
444 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000445 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000446 if (Known != Headers.end()) {
447 for (SmallVectorImpl<KnownHeader>::const_iterator
448 I = Known->second.begin(),
449 E = Known->second.end();
450 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000451 if (I->isAvailable() && (!RequestingModule ||
452 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000453 return false;
454 }
455 return true;
456 }
Richard Smith50996ce2014-04-08 13:13:04 +0000457
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000458 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000459 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000460 StringRef DirName = Dir->getName();
461
Richard Smith50996ce2014-04-08 13:13:04 +0000462 auto IsUnavailable = [&](const Module *M) {
463 return !M->isAvailable() && (!RequestingModule ||
464 M->isSubModuleOf(RequestingModule));
465 };
466
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000467 // Keep walking up the directory hierarchy, looking for a directory with
468 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000469 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000470 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000471 = UmbrellaDirs.find(Dir);
472 if (KnownDir != UmbrellaDirs.end()) {
473 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000474 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000475 return true;
476
477 // Search up the module stack until we find a module with an umbrella
478 // directory.
479 Module *UmbrellaModule = Found;
480 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
481 UmbrellaModule = UmbrellaModule->Parent;
482
483 if (UmbrellaModule->InferSubmodules) {
484 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
485 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000486 SmallString<32> NameBuf;
487 StringRef Name = sanitizeFilenameAsIdentifier(
488 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
489 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 Found = lookupModuleQualified(Name, Found);
491 if (!Found)
492 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000493 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000494 return true;
495 }
496
497 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000498 SmallString<32> NameBuf;
499 StringRef Name = sanitizeFilenameAsIdentifier(
500 llvm::sys::path::stem(Header->getName()),
501 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000502 Found = lookupModuleQualified(Name, Found);
503 if (!Found)
504 return false;
505 }
506
Richard Smith50996ce2014-04-08 13:13:04 +0000507 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000508 }
509
510 SkippedDirs.push_back(Dir);
511
512 // Retrieve our parent path.
513 DirName = llvm::sys::path::parent_path(DirName);
514 if (DirName.empty())
515 break;
516
517 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000518 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000519 } while (Dir);
520
521 return false;
522}
523
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000524Module *ModuleMap::findModule(StringRef Name) const {
525 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000526 if (Known != Modules.end())
527 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000528
529 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000530}
531
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000532Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
533 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000534 for(; Context; Context = Context->Parent) {
535 if (Module *Sub = lookupModuleQualified(Name, Context))
536 return Sub;
537 }
538
539 return findModule(Name);
540}
541
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000542Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000543 if (!Context)
544 return findModule(Name);
545
Douglas Gregoreb90e832012-01-04 23:32:19 +0000546 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000547}
548
Douglas Gregorde3ef502011-11-30 23:21:26 +0000549std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000550ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000551 bool IsExplicit) {
552 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000553 if (Module *Sub = lookupModuleQualified(Name, Parent))
554 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000555
556 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000557 Module *Result = new Module(Name, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000558 IsFramework, IsExplicit, NumCreatedModules++);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000559 if (LangOpts.CurrentModule == Name) {
560 SourceModule = Result;
561 SourceModuleName = Name;
562 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000563 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000564 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000565 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
566 Name == LangOpts.CurrentModule) {
567 CompilingModule = Result;
568 }
569 }
Douglas Gregor69021972011-11-30 17:33:56 +0000570 return std::make_pair(Result, true);
571}
572
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000573/// \brief For a framework module, infer the framework against which we
574/// should link.
575static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
576 FileManager &FileMgr) {
577 assert(Mod->IsFramework && "Can only infer linking for framework modules");
578 assert(!Mod->isSubFramework() &&
579 "Can only infer linking for top-level frameworks");
580
581 SmallString<128> LibName;
582 LibName += FrameworkDir->getName();
583 llvm::sys::path::append(LibName, Mod->Name);
584 if (FileMgr.getFile(LibName)) {
585 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
586 /*IsFramework=*/true));
587 }
588}
589
Ben Langmuira5254002015-07-02 13:19:48 +0000590Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
591 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000592 Attributes Attrs;
593 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000594 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000595}
596
Ben Langmuira5254002015-07-02 13:19:48 +0000597Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000598 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000599 // Note: as an egregious but useful hack we use the real path here, because
600 // we might be looking at an embedded framework that symlinks out to a
601 // top-level framework, and we need to infer as if we were naming the
602 // top-level framework.
603 StringRef FrameworkDirName =
604 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
605
606 // In case this is a case-insensitive filesystem, use the canonical
607 // directory name as the ModuleName, since modules are case-sensitive.
608 // FIXME: we should be able to give a fix-it hint for the correct spelling.
609 SmallString<32> ModuleNameStorage;
610 StringRef ModuleName = sanitizeFilenameAsIdentifier(
611 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000612
Douglas Gregor56c64012011-11-17 01:41:17 +0000613 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000614 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
615 return Mod;
616
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000617 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000618
619 // If the framework has a parent path from which we're allowed to infer
620 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000621 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000622 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000623 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000624 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000625 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000626 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000627 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000628 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
629 // Check whether we have already looked into the parent directory
630 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000631 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000632 inferred = InferredDirectories.find(ParentDir);
633 if (inferred == InferredDirectories.end()) {
634 // We haven't looked here before. Load a module map, if there is
635 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000636 bool IsFrameworkDir = Parent.endswith(".framework");
637 if (const FileEntry *ModMapFile =
638 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000639 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000640 inferred = InferredDirectories.find(ParentDir);
641 }
642
643 if (inferred == InferredDirectories.end())
644 inferred = InferredDirectories.insert(
645 std::make_pair(ParentDir, InferredDirectory())).first;
646 }
647
648 if (inferred->second.InferModules) {
649 // We're allowed to infer for this directory, but make sure it's okay
650 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000651 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000652 canInfer = std::find(inferred->second.ExcludedModules.begin(),
653 inferred->second.ExcludedModules.end(),
654 Name) == inferred->second.ExcludedModules.end();
655
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000656 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
657 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
658 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000659 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000660 }
661 }
662 }
663
664 // If we're not allowed to infer a framework module, don't.
665 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000666 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000667 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000668 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000669
670
Douglas Gregor56c64012011-11-17 01:41:17 +0000671 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000672 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000673 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000674 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000675
676 // FIXME: If there's no umbrella header, we could probably scan the
677 // framework to load *everything*. But, it's not clear that this is a good
678 // idea.
679 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000680 return nullptr;
681
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000682 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000683 /*IsFramework=*/true, /*IsExplicit=*/false,
684 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000685 InferredModuleAllowedBy[Result] = ModuleMapFile;
686 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000687 if (LangOpts.CurrentModule == ModuleName) {
688 SourceModule = Result;
689 SourceModuleName = ModuleName;
690 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000691
692 Result->IsSystem |= Attrs.IsSystem;
693 Result->IsExternC |= Attrs.IsExternC;
694 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Richard Smith2b63d152015-05-16 02:28:53 +0000695 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000696
Douglas Gregoreb90e832012-01-04 23:32:19 +0000697 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000698 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000699
Douglas Gregor322f6332011-12-08 18:00:48 +0000700 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000701 //
702 // The "Headers/" component of the name is implied because this is
703 // a framework module.
704 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000705
706 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000707 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
708
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000709 // module * { export * }
710 Result->InferSubmodules = true;
711 Result->InferExportWildcard = true;
712
Douglas Gregore89dbc12011-12-06 19:39:29 +0000713 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000714 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000715 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000716 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000717 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000718 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000719 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 Dir != DirEnd && !EC; Dir.increment(EC)) {
721 if (!StringRef(Dir->path()).endswith(".framework"))
722 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000723
Douglas Gregore89dbc12011-12-06 19:39:29 +0000724 if (const DirectoryEntry *SubframeworkDir
725 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000726 // Note: as an egregious but useful hack, we use the real path here and
727 // check whether it is actually a subdirectory of the parent directory.
728 // This will not be the case if the 'subframework' is actually a symlink
729 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000730 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
731 bool FoundParent = false;
732 do {
733 // Get the parent directory name.
734 SubframeworkDirName
735 = llvm::sys::path::parent_path(SubframeworkDirName);
736 if (SubframeworkDirName.empty())
737 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000738
Douglas Gregore00c8b22013-01-26 00:55:12 +0000739 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
740 FoundParent = true;
741 break;
742 }
743 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000744
Douglas Gregore00c8b22013-01-26 00:55:12 +0000745 if (!FoundParent)
746 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000747
Douglas Gregore89dbc12011-12-06 19:39:29 +0000748 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000749 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000750 }
751 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000752
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000753 // If the module is a top-level framework, automatically link against the
754 // framework.
755 if (!Result->isSubFramework()) {
756 inferFrameworkLink(Result, FrameworkDir, FileMgr);
757 }
758
Douglas Gregor56c64012011-11-17 01:41:17 +0000759 return Result;
760}
761
Richard Smith2b63d152015-05-16 02:28:53 +0000762void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
763 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000764 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000765 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000766 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000767 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000768}
769
Richard Smith2b63d152015-05-16 02:28:53 +0000770void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
771 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000772 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000773 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000774 UmbrellaDirs[UmbrellaDir] = Mod;
775}
776
Richard Smith3c1a41a2014-12-02 00:08:08 +0000777static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000778 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000779 default: llvm_unreachable("unknown header role");
780 case ModuleMap::NormalHeader:
781 return Module::HK_Normal;
782 case ModuleMap::PrivateHeader:
783 return Module::HK_Private;
784 case ModuleMap::TextualHeader:
785 return Module::HK_Textual;
786 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
787 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000788 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000789}
790
Richard Smith3c1a41a2014-12-02 00:08:08 +0000791void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000792 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000793 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000794
Richard Smith386bb072015-08-18 23:42:23 +0000795 // Only add each header to the headers list once.
796 // FIXME: Should we diagnose if a header is listed twice in the
797 // same module definition?
798 auto &HeaderList = Headers[Header.Entry];
799 for (auto H : HeaderList)
800 if (H == KH)
801 return;
802
803 HeaderList.push_back(KH);
Richard Smith3c1a41a2014-12-02 00:08:08 +0000804 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
Richard Smith386bb072015-08-18 23:42:23 +0000805
806 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000807 if (!Imported || isCompilingModuleHeader) {
808 // When we import HeaderFileInfo, the external source is expected to
809 // set the isModuleHeader flag itself.
810 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
811 isCompilingModuleHeader);
812 }
Richard Smith3c1a41a2014-12-02 00:08:08 +0000813}
814
815void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000816 // Add this as a known header so we won't implicitly add it to any
817 // umbrella directory module.
818 // FIXME: Should we only exclude it from umbrella modules within the
819 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000820 (void) Headers[Header.Entry];
821
822 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000823}
824
Douglas Gregor514b6362011-11-29 19:06:37 +0000825const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000826ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000827 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000828 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000829
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000830 return SourceMgr.getFileEntryForID(
831 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000832}
833
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000834const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000835 if (M->IsInferred) {
836 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
837 return InferredModuleAllowedBy.find(M)->second;
838 }
839 return getContainingModuleMapFile(M);
840}
841
842void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
843 assert(M->IsInferred && "module not inferred");
844 InferredModuleAllowedBy[M] = ModMap;
845}
846
Douglas Gregor718292f2011-11-11 19:10:28 +0000847void ModuleMap::dump() {
848 llvm::errs() << "Modules:";
849 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
850 MEnd = Modules.end();
851 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000852 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000853
854 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000855 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000856 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000857 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
858 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
859 E = H->second.end();
860 I != E; ++I) {
861 if (I != H->second.begin())
862 llvm::errs() << ",";
863 llvm::errs() << I->getModule()->getFullModuleName();
864 }
865 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000866 }
867}
868
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000869bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000870 auto Unresolved = std::move(Mod->UnresolvedExports);
871 Mod->UnresolvedExports.clear();
872 for (auto &UE : Unresolved) {
873 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000874 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000875 Mod->Exports.push_back(Export);
876 else
Richard Smith42413142015-05-15 20:05:43 +0000877 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000878 }
Richard Smith42413142015-05-15 20:05:43 +0000879 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000880}
881
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000882bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000883 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
884 Mod->UnresolvedDirectUses.clear();
885 for (auto &UDU : Unresolved) {
886 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000887 if (DirectUse)
888 Mod->DirectUses.push_back(DirectUse);
889 else
Richard Smith42413142015-05-15 20:05:43 +0000890 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000891 }
Richard Smith42413142015-05-15 20:05:43 +0000892 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000893}
894
Douglas Gregorfb912652013-03-20 21:10:35 +0000895bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000896 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000897 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000898 for (auto &UC : Unresolved) {
899 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
900 Module::Conflict Conflict;
901 Conflict.Other = OtherMod;
902 Conflict.Message = UC.Message;
903 Mod->Conflicts.push_back(Conflict);
904 } else
905 Mod->UnresolvedConflicts.push_back(UC);
906 }
907 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000908}
909
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000910Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
911 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000912 return nullptr;
913
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000914 // Use the expansion location to determine which module we're in.
915 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
916 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000917 return nullptr;
918
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000919 const SourceManager &SrcMgr = Loc.getManager();
920 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000921
Douglas Gregor224d8a72012-01-06 17:19:32 +0000922 while (const FileEntry *ExpansionFile
923 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
924 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000925 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000926 return Mod;
927
928 // No module owns this header, so look up the inclusion chain to see if
929 // any included header has an associated module.
930 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
931 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000932 return nullptr;
933
Douglas Gregor224d8a72012-01-06 17:19:32 +0000934 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
935 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000936
937 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000938}
939
Douglas Gregor718292f2011-11-11 19:10:28 +0000940//----------------------------------------------------------------------------//
941// Module map file parser
942//----------------------------------------------------------------------------//
943
944namespace clang {
945 /// \brief A token in a module map file.
946 struct MMToken {
947 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000948 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000949 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000950 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000951 EndOfFile,
952 HeaderKeyword,
953 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000954 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000955 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000956 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000957 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000958 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000959 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000960 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000961 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000962 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000963 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000965 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000966 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000967 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000968 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000969 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000970 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000971 RBrace,
972 LSquare,
973 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000974 } Kind;
975
976 unsigned Location;
977 unsigned StringLength;
978 const char *StringData;
979
980 void clear() {
981 Kind = EndOfFile;
982 Location = 0;
983 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000984 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000985 }
986
987 bool is(TokenKind K) const { return Kind == K; }
988
989 SourceLocation getLocation() const {
990 return SourceLocation::getFromRawEncoding(Location);
991 }
992
993 StringRef getString() const {
994 return StringRef(StringData, StringLength);
995 }
996 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000997
Douglas Gregor718292f2011-11-11 19:10:28 +0000998 class ModuleMapParser {
999 Lexer &L;
1000 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001001
1002 /// \brief Default target information, used only for string literal
1003 /// parsing.
1004 const TargetInfo *Target;
1005
Douglas Gregor718292f2011-11-11 19:10:28 +00001006 DiagnosticsEngine &Diags;
1007 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001008
1009 /// \brief The current module map file.
1010 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001011
Richard Smith9acb99e32014-12-10 03:09:48 +00001012 /// \brief The directory that file names in this module map file should
1013 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001014 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001015
1016 /// \brief The directory containing Clang-supplied headers.
1017 const DirectoryEntry *BuiltinIncludeDir;
1018
Douglas Gregor963c5532013-06-21 16:28:10 +00001019 /// \brief Whether this module map is in a system header directory.
1020 bool IsSystem;
1021
Douglas Gregor718292f2011-11-11 19:10:28 +00001022 /// \brief Whether an error occurred.
1023 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001024
Douglas Gregor718292f2011-11-11 19:10:28 +00001025 /// \brief Stores string data for the various string literals referenced
1026 /// during parsing.
1027 llvm::BumpPtrAllocator StringData;
1028
1029 /// \brief The current token.
1030 MMToken Tok;
1031
1032 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001033 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001034
1035 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1036 /// contents as 'textual'.
1037 ///
1038 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1039 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1040 /// non-modular headers. For backwards compatibility, we continue to
1041 /// support this idiom for just these modules, and map the headers to
1042 /// 'textual' to match the original intent.
1043 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1044
Douglas Gregor718292f2011-11-11 19:10:28 +00001045 /// \brief Consume the current token and return its location.
1046 SourceLocation consumeToken();
1047
1048 /// \brief Skip tokens until we reach the a token with the given kind
1049 /// (or the end of the file).
1050 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001051
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001052 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001053 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001054 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001055 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001056 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001057 void parseHeaderDecl(clang::MMToken::TokenKind,
1058 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001059 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001060 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001061 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001062 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001063 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001064 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001065 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001066
1067 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001068 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001069
Douglas Gregor718292f2011-11-11 19:10:28 +00001070 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001071 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001072 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001073 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001074 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001075 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001076 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001077 const DirectoryEntry *BuiltinIncludeDir,
1078 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001079 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001080 ModuleMapFile(ModuleMapFile), Directory(Directory),
1081 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001082 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001084 Tok.clear();
1085 consumeToken();
1086 }
1087
1088 bool parseModuleMapFile();
1089 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001090}
Douglas Gregor718292f2011-11-11 19:10:28 +00001091
1092SourceLocation ModuleMapParser::consumeToken() {
1093retry:
1094 SourceLocation Result = Tok.getLocation();
1095 Tok.clear();
1096
1097 Token LToken;
1098 L.LexFromRawLexer(LToken);
1099 Tok.Location = LToken.getLocation().getRawEncoding();
1100 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001101 case tok::raw_identifier: {
1102 StringRef RI = LToken.getRawIdentifier();
1103 Tok.StringData = RI.data();
1104 Tok.StringLength = RI.size();
1105 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001106 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001107 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001108 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001109 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001110 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001111 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001112 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001113 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001114 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001115 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001116 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001117 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001118 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001119 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001120 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001121 .Default(MMToken::Identifier);
1122 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001123 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001124
1125 case tok::comma:
1126 Tok.Kind = MMToken::Comma;
1127 break;
1128
Douglas Gregor718292f2011-11-11 19:10:28 +00001129 case tok::eof:
1130 Tok.Kind = MMToken::EndOfFile;
1131 break;
1132
1133 case tok::l_brace:
1134 Tok.Kind = MMToken::LBrace;
1135 break;
1136
Douglas Gregora686e1b2012-01-27 19:52:33 +00001137 case tok::l_square:
1138 Tok.Kind = MMToken::LSquare;
1139 break;
1140
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001141 case tok::period:
1142 Tok.Kind = MMToken::Period;
1143 break;
1144
Douglas Gregor718292f2011-11-11 19:10:28 +00001145 case tok::r_brace:
1146 Tok.Kind = MMToken::RBrace;
1147 break;
1148
Douglas Gregora686e1b2012-01-27 19:52:33 +00001149 case tok::r_square:
1150 Tok.Kind = MMToken::RSquare;
1151 break;
1152
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001153 case tok::star:
1154 Tok.Kind = MMToken::Star;
1155 break;
1156
Richard Smitha3feee22013-10-28 22:18:19 +00001157 case tok::exclaim:
1158 Tok.Kind = MMToken::Exclaim;
1159 break;
1160
Douglas Gregor718292f2011-11-11 19:10:28 +00001161 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001162 if (LToken.hasUDSuffix()) {
1163 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1164 HadError = true;
1165 goto retry;
1166 }
1167
Douglas Gregor718292f2011-11-11 19:10:28 +00001168 // Parse the string literal.
1169 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001170 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001171 if (StringLiteral.hadError)
1172 goto retry;
1173
1174 // Copy the string literal into our string data allocator.
1175 unsigned Length = StringLiteral.GetStringLength();
1176 char *Saved = StringData.Allocate<char>(Length + 1);
1177 memcpy(Saved, StringLiteral.GetString().data(), Length);
1178 Saved[Length] = 0;
1179
1180 // Form the token.
1181 Tok.Kind = MMToken::StringLiteral;
1182 Tok.StringData = Saved;
1183 Tok.StringLength = Length;
1184 break;
1185 }
1186
1187 case tok::comment:
1188 goto retry;
1189
1190 default:
1191 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1192 HadError = true;
1193 goto retry;
1194 }
1195
1196 return Result;
1197}
1198
1199void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1200 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001201 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001202 do {
1203 switch (Tok.Kind) {
1204 case MMToken::EndOfFile:
1205 return;
1206
1207 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001208 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001209 return;
1210
1211 ++braceDepth;
1212 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001213
1214 case MMToken::LSquare:
1215 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1216 return;
1217
1218 ++squareDepth;
1219 break;
1220
Douglas Gregor718292f2011-11-11 19:10:28 +00001221 case MMToken::RBrace:
1222 if (braceDepth > 0)
1223 --braceDepth;
1224 else if (Tok.is(K))
1225 return;
1226 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001227
1228 case MMToken::RSquare:
1229 if (squareDepth > 0)
1230 --squareDepth;
1231 else if (Tok.is(K))
1232 return;
1233 break;
1234
Douglas Gregor718292f2011-11-11 19:10:28 +00001235 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001236 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 return;
1238 break;
1239 }
1240
1241 consumeToken();
1242 } while (true);
1243}
1244
Douglas Gregore7ab3662011-12-07 02:23:45 +00001245/// \brief Parse a module-id.
1246///
1247/// module-id:
1248/// identifier
1249/// identifier '.' module-id
1250///
1251/// \returns true if an error occurred, false otherwise.
1252bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1253 Id.clear();
1254 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001255 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001256 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1257 consumeToken();
1258 } else {
1259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1260 return true;
1261 }
1262
1263 if (!Tok.is(MMToken::Period))
1264 break;
1265
1266 consumeToken();
1267 } while (true);
1268
1269 return false;
1270}
1271
Douglas Gregora686e1b2012-01-27 19:52:33 +00001272namespace {
1273 /// \brief Enumerates the known attributes.
1274 enum AttributeKind {
1275 /// \brief An unknown attribute.
1276 AT_unknown,
1277 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001278 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001279 /// \brief The 'extern_c' attribute.
1280 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001281 /// \brief The 'exhaustive' attribute.
1282 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001283 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001284}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001285
Douglas Gregor718292f2011-11-11 19:10:28 +00001286/// \brief Parse a module declaration.
1287///
1288/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001289/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001290/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1291/// { module-member* }
1292///
Douglas Gregor718292f2011-11-11 19:10:28 +00001293/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001294/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001295/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001296/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001297/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001298/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001299///
1300/// submodule-declaration:
1301/// module-declaration
1302/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001303void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001304 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001305 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1306 if (Tok.is(MMToken::ExternKeyword)) {
1307 parseExternModuleDecl();
1308 return;
1309 }
1310
Douglas Gregorf2161a72011-12-06 17:16:41 +00001311 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001312 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001313 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001314 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001315
Douglas Gregorf2161a72011-12-06 17:16:41 +00001316 // Parse 'explicit' keyword, if present.
1317 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001318 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001319 Explicit = true;
1320 }
1321
1322 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001323 if (Tok.is(MMToken::FrameworkKeyword)) {
1324 consumeToken();
1325 Framework = true;
1326 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001327
1328 // Parse 'module' keyword.
1329 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001330 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001331 consumeToken();
1332 HadError = true;
1333 return;
1334 }
1335 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001336
1337 // If we have a wildcard for the module name, this is an inferred submodule.
1338 // Parse it.
1339 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001340 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001341
1342 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001343 ModuleId Id;
1344 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001345 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001346 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001347 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001348
Douglas Gregore7ab3662011-12-07 02:23:45 +00001349 if (ActiveModule) {
1350 if (Id.size() > 1) {
1351 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1352 << SourceRange(Id.front().second, Id.back().second);
1353
1354 HadError = true;
1355 return;
1356 }
1357 } else if (Id.size() == 1 && Explicit) {
1358 // Top-level modules can't be explicit.
1359 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1360 Explicit = false;
1361 ExplicitLoc = SourceLocation();
1362 HadError = true;
1363 }
1364
1365 Module *PreviousActiveModule = ActiveModule;
1366 if (Id.size() > 1) {
1367 // This module map defines a submodule. Go find the module of which it
1368 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001369 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001370 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001371 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1372 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001373 if (I == 0)
1374 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001375 ActiveModule = Next;
1376 continue;
1377 }
1378
1379 if (ActiveModule) {
1380 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001381 << Id[I].first
1382 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001383 } else {
1384 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1385 }
1386 HadError = true;
1387 return;
1388 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001389
1390 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1391 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1392 "submodule defined in same file as 'module *' that allowed its "
1393 "top-level module");
1394 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1395 }
1396 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001397
1398 StringRef ModuleName = Id.back().first;
1399 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001400
Douglas Gregora686e1b2012-01-27 19:52:33 +00001401 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001402 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001403 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001404
Douglas Gregor718292f2011-11-11 19:10:28 +00001405 // Parse the opening brace.
1406 if (!Tok.is(MMToken::LBrace)) {
1407 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1408 << ModuleName;
1409 HadError = true;
1410 return;
1411 }
1412 SourceLocation LBraceLoc = consumeToken();
1413
1414 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001415 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001416 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1417 // Skip the module definition.
1418 skipUntil(MMToken::RBrace);
1419 if (Tok.is(MMToken::RBrace))
1420 consumeToken();
1421 else {
1422 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1423 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1424 HadError = true;
1425 }
1426 return;
1427 }
1428
Douglas Gregor718292f2011-11-11 19:10:28 +00001429 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1430 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001431 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001432
1433 // Skip the module definition.
1434 skipUntil(MMToken::RBrace);
1435 if (Tok.is(MMToken::RBrace))
1436 consumeToken();
1437
1438 HadError = true;
1439 return;
1440 }
1441
1442 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001443 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1444 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001445 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001446 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001447 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001448 if (Attrs.IsExternC)
1449 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001450 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001451
Douglas Gregor718292f2011-11-11 19:10:28 +00001452 bool Done = false;
1453 do {
1454 switch (Tok.Kind) {
1455 case MMToken::EndOfFile:
1456 case MMToken::RBrace:
1457 Done = true;
1458 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001459
1460 case MMToken::ConfigMacros:
1461 parseConfigMacros();
1462 break;
1463
Douglas Gregorfb912652013-03-20 21:10:35 +00001464 case MMToken::Conflict:
1465 parseConflict();
1466 break;
1467
Douglas Gregor718292f2011-11-11 19:10:28 +00001468 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001469 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001470 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001471 case MMToken::ModuleKeyword:
1472 parseModuleDecl();
1473 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001474
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001475 case MMToken::ExportKeyword:
1476 parseExportDecl();
1477 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001478
1479 case MMToken::UseKeyword:
1480 parseUseDecl();
1481 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001482
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001483 case MMToken::RequiresKeyword:
1484 parseRequiresDecl();
1485 break;
1486
Richard Smith202210b2014-10-24 20:23:01 +00001487 case MMToken::TextualKeyword:
1488 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001489 break;
Richard Smith306d8922014-10-22 23:50:56 +00001490
Douglas Gregor524e33e2011-12-08 19:11:24 +00001491 case MMToken::UmbrellaKeyword: {
1492 SourceLocation UmbrellaLoc = consumeToken();
1493 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001494 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001495 else
1496 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001497 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001498 }
Richard Smith202210b2014-10-24 20:23:01 +00001499
1500 case MMToken::ExcludeKeyword:
1501 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001502 break;
Richard Smith202210b2014-10-24 20:23:01 +00001503
1504 case MMToken::PrivateKeyword:
1505 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001506 break;
Richard Smith202210b2014-10-24 20:23:01 +00001507
Douglas Gregor322f6332011-12-08 18:00:48 +00001508 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001509 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001510 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001511
1512 case MMToken::LinkKeyword:
1513 parseLinkDecl();
1514 break;
1515
Douglas Gregor718292f2011-11-11 19:10:28 +00001516 default:
1517 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1518 consumeToken();
1519 break;
1520 }
1521 } while (!Done);
1522
1523 if (Tok.is(MMToken::RBrace))
1524 consumeToken();
1525 else {
1526 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1527 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1528 HadError = true;
1529 }
1530
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001531 // If the active module is a top-level framework, and there are no link
1532 // libraries, automatically link against the framework.
1533 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1534 ActiveModule->LinkLibraries.empty()) {
1535 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1536 }
1537
Ben Langmuirec8c9752014-04-18 22:07:31 +00001538 // If the module meets all requirements but is still unavailable, mark the
1539 // whole tree as unavailable to prevent it from building.
1540 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1541 ActiveModule->Parent) {
1542 ActiveModule->getTopLevelModule()->markUnavailable();
1543 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1544 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1545 }
1546
Douglas Gregore7ab3662011-12-07 02:23:45 +00001547 // We're done parsing this module. Pop back to the previous module.
1548 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001549}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001550
Daniel Jasper97292842013-09-11 07:20:44 +00001551/// \brief Parse an extern module declaration.
1552///
1553/// extern module-declaration:
1554/// 'extern' 'module' module-id string-literal
1555void ModuleMapParser::parseExternModuleDecl() {
1556 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001557 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001558
1559 // Parse 'module' keyword.
1560 if (!Tok.is(MMToken::ModuleKeyword)) {
1561 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1562 consumeToken();
1563 HadError = true;
1564 return;
1565 }
1566 consumeToken(); // 'module' keyword
1567
1568 // Parse the module name.
1569 ModuleId Id;
1570 if (parseModuleId(Id)) {
1571 HadError = true;
1572 return;
1573 }
1574
1575 // Parse the referenced module map file name.
1576 if (!Tok.is(MMToken::StringLiteral)) {
1577 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1578 HadError = true;
1579 return;
1580 }
1581 std::string FileName = Tok.getString();
1582 consumeToken(); // filename
1583
1584 StringRef FileNameRef = FileName;
1585 SmallString<128> ModuleMapFileName;
1586 if (llvm::sys::path::is_relative(FileNameRef)) {
1587 ModuleMapFileName += Directory->getName();
1588 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001589 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001590 }
1591 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001592 Map.parseModuleMapFile(
1593 File, /*IsSystem=*/false,
1594 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1595 ? Directory
Richard Smithae6df272015-07-14 02:06:01 +00001596 : File->getDir(), ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001597}
1598
Ben Langmuir7ff29142015-08-13 17:13:33 +00001599/// Whether to add the requirement \p Feature to the module \p M.
1600///
1601/// This preserves backwards compatibility for two hacks in the Darwin system
1602/// module map files:
1603///
1604/// 1. The use of 'requires excluded' to make headers non-modular, which
1605/// should really be mapped to 'textual' now that we have this feature. We
1606/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1607/// true. Later, this bit will be used to map all the headers inside this
1608/// module to 'textual'.
1609///
1610/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1611///
1612/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1613/// was never correct and causes issues now that we check it, so drop it.
1614static bool shouldAddRequirement(Module *M, StringRef Feature,
1615 bool &IsRequiresExcludedHack) {
1616 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1617 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1618 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1619
1620 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1621 M->fullModuleNameIs(TclPrivate))) {
1622 IsRequiresExcludedHack = true;
1623 return false;
1624 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1625 return false;
1626 }
1627
1628 return true;
1629}
1630
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001631/// \brief Parse a requires declaration.
1632///
1633/// requires-declaration:
1634/// 'requires' feature-list
1635///
1636/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001637/// feature ',' feature-list
1638/// feature
1639///
1640/// feature:
1641/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001642void ModuleMapParser::parseRequiresDecl() {
1643 assert(Tok.is(MMToken::RequiresKeyword));
1644
1645 // Parse 'requires' keyword.
1646 consumeToken();
1647
1648 // Parse the feature-list.
1649 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001650 bool RequiredState = true;
1651 if (Tok.is(MMToken::Exclaim)) {
1652 RequiredState = false;
1653 consumeToken();
1654 }
1655
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001656 if (!Tok.is(MMToken::Identifier)) {
1657 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1658 HadError = true;
1659 return;
1660 }
1661
1662 // Consume the feature name.
1663 std::string Feature = Tok.getString();
1664 consumeToken();
1665
Ben Langmuir7ff29142015-08-13 17:13:33 +00001666 bool IsRequiresExcludedHack = false;
1667 bool ShouldAddRequirement =
1668 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1669
1670 if (IsRequiresExcludedHack)
1671 UsesRequiresExcludedHack.insert(ActiveModule);
1672
1673 if (ShouldAddRequirement) {
1674 // Add this feature.
1675 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1676 *Map.Target);
1677 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001678
1679 if (!Tok.is(MMToken::Comma))
1680 break;
1681
1682 // Consume the comma.
1683 consumeToken();
1684 } while (true);
1685}
1686
Douglas Gregorf2161a72011-12-06 17:16:41 +00001687/// \brief Append to \p Paths the set of paths needed to get to the
1688/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001689static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001690 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001691 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001692 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001693 for (; Mod; Mod = Mod->Parent) {
1694 if (Mod->IsFramework)
1695 Paths.push_back(Mod->Name);
1696 }
1697
1698 if (Paths.empty())
1699 return;
1700
1701 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001702 for (unsigned I = Paths.size() - 1; I != 0; --I)
1703 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001704}
1705
Douglas Gregor718292f2011-11-11 19:10:28 +00001706/// \brief Parse a header declaration.
1707///
1708/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001709/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001710/// 'private' 'textual'[opt] 'header' string-literal
1711/// 'exclude' 'header' string-literal
1712/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001713///
1714/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001715void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1716 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001717 // We've already consumed the first token.
1718 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1719 if (LeadingToken == MMToken::PrivateKeyword) {
1720 Role = ModuleMap::PrivateHeader;
1721 // 'private' may optionally be followed by 'textual'.
1722 if (Tok.is(MMToken::TextualKeyword)) {
1723 LeadingToken = Tok.Kind;
1724 consumeToken();
1725 }
1726 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001727
Richard Smith202210b2014-10-24 20:23:01 +00001728 if (LeadingToken == MMToken::TextualKeyword)
1729 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1730
Ben Langmuir7ff29142015-08-13 17:13:33 +00001731 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1732 // Mark this header 'textual' (see doc comment for
1733 // Module::UsesRequiresExcludedHack).
1734 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1735 }
1736
Richard Smith202210b2014-10-24 20:23:01 +00001737 if (LeadingToken != MMToken::HeaderKeyword) {
1738 if (!Tok.is(MMToken::HeaderKeyword)) {
1739 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1740 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1741 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1742 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1743 return;
1744 }
1745 consumeToken();
1746 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001747
Douglas Gregor718292f2011-11-11 19:10:28 +00001748 // Parse the header name.
1749 if (!Tok.is(MMToken::StringLiteral)) {
1750 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1751 << "header";
1752 HadError = true;
1753 return;
1754 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001755 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001756 Header.FileName = Tok.getString();
1757 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001758
Douglas Gregor524e33e2011-12-08 19:11:24 +00001759 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001760 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001761 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001762 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001763 HadError = true;
1764 return;
1765 }
1766
Douglas Gregor5257fc62011-11-11 21:55:48 +00001767 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001768 const FileEntry *File = nullptr;
1769 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001770 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001771 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001772 RelativePathName = Header.FileName;
1773 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001774 } else {
1775 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001776 SmallString<128> FullPathName(Directory->getName());
1777 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001778
Douglas Gregorf2161a72011-12-06 17:16:41 +00001779 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001780 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001781
1782 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001783 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001784 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001785 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001786
1787 if (!File) {
1788 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001789 // FIXME: Should we retain the subframework paths here?
1790 RelativePathName.clear();
1791 FullPathName.resize(FullPathLength);
1792 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1793 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001794 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001795 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001796 }
1797 } else {
1798 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001799 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001800 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001801 File = SourceMgr.getFileManager().getFile(FullPathName);
1802
Douglas Gregor3ec66632012-02-02 18:42:48 +00001803 // If this is a system module with a top-level header, this header
1804 // may have a counterpart (or replacement) in the set of headers
1805 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001806 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1807 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001808 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001809 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001810 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001811 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001812
Douglas Gregor3ec66632012-02-02 18:42:48 +00001813 // If Clang supplies this header but the underlying system does not,
1814 // just silently swap in our builtin version. Otherwise, we'll end
1815 // up adding both (later).
Richard Smith42413142015-05-15 20:05:43 +00001816 //
1817 // For local visibility, entirely replace the system file with our
1818 // one and textually include the system one. We need to pass macros
1819 // from our header to the system one if we #include_next it.
1820 //
1821 // FIXME: Can we do this in all cases?
1822 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001823 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001824 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001825 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001826 }
1827 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001828 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001829 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001830
Douglas Gregor5257fc62011-11-11 21:55:48 +00001831 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1832 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001833 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001834 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001835 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001836 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001837 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001838 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001839 HadError = true;
1840 } else {
1841 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001842 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001843 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001844 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001845 Module::Header H = {RelativePathName.str(), File};
1846 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001847 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001848 // If there is a builtin counterpart to this file, add it now, before
1849 // the "real" header, so we build the built-in one first when building
1850 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001851 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001852 // FIXME: Taking the name from the FileEntry is unstable and can give
1853 // different results depending on how we've previously named that file
1854 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001855 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1856 Map.addHeader(ActiveModule, H, Role);
1857 }
Richard Smith25d50752014-10-20 00:15:49 +00001858
Richard Smith202210b2014-10-24 20:23:01 +00001859 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001860 Module::Header H = { RelativePathName.str(), File };
1861 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001862 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001863 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001864 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001865
1866 // If we find a module that has a missing header, we mark this module as
1867 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001868 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001869 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001870 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001871 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001872}
1873
Ben Langmuir41f81992015-08-13 17:30:07 +00001874static int compareModuleHeaders(const Module::Header *A,
1875 const Module::Header *B) {
1876 return A->NameAsWritten.compare(B->NameAsWritten);
1877}
1878
Douglas Gregor524e33e2011-12-08 19:11:24 +00001879/// \brief Parse an umbrella directory declaration.
1880///
1881/// umbrella-dir-declaration:
1882/// umbrella string-literal
1883void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1884 // Parse the directory name.
1885 if (!Tok.is(MMToken::StringLiteral)) {
1886 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1887 << "umbrella";
1888 HadError = true;
1889 return;
1890 }
1891
1892 std::string DirName = Tok.getString();
1893 SourceLocation DirNameLoc = consumeToken();
1894
1895 // Check whether we already have an umbrella.
1896 if (ActiveModule->Umbrella) {
1897 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1898 << ActiveModule->getFullModuleName();
1899 HadError = true;
1900 return;
1901 }
1902
1903 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001904 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001905 if (llvm::sys::path::is_absolute(DirName))
1906 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1907 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001908 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001909 PathName = Directory->getName();
1910 llvm::sys::path::append(PathName, DirName);
1911 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1912 }
1913
1914 if (!Dir) {
1915 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1916 << DirName;
1917 HadError = true;
1918 return;
1919 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001920
1921 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1922 // Mark this header 'textual' (see doc comment for
1923 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1924 // directory is relatively expensive, in practice this only applies to the
1925 // uncommonly used Tcl module on Darwin platforms.
1926 std::error_code EC;
1927 SmallVector<Module::Header, 6> Headers;
1928 for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E;
1929 I != E && !EC; I.increment(EC)) {
1930 if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
1931
1932 Module::Header Header = {I->path(), FE};
1933 Headers.push_back(std::move(Header));
1934 }
1935 }
1936
1937 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00001938 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1939
Ben Langmuir7ff29142015-08-13 17:13:33 +00001940 for (auto &Header : Headers)
1941 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1942 return;
1943 }
1944
Douglas Gregor524e33e2011-12-08 19:11:24 +00001945 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1946 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1947 << OwningModule->getFullModuleName();
1948 HadError = true;
1949 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001950 }
1951
Douglas Gregor524e33e2011-12-08 19:11:24 +00001952 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00001953 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001954}
1955
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001956/// \brief Parse a module export declaration.
1957///
1958/// export-declaration:
1959/// 'export' wildcard-module-id
1960///
1961/// wildcard-module-id:
1962/// identifier
1963/// '*'
1964/// identifier '.' wildcard-module-id
1965void ModuleMapParser::parseExportDecl() {
1966 assert(Tok.is(MMToken::ExportKeyword));
1967 SourceLocation ExportLoc = consumeToken();
1968
1969 // Parse the module-id with an optional wildcard at the end.
1970 ModuleId ParsedModuleId;
1971 bool Wildcard = false;
1972 do {
Richard Smith306d8922014-10-22 23:50:56 +00001973 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001974 if (Tok.is(MMToken::Identifier)) {
1975 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1976 Tok.getLocation()));
1977 consumeToken();
1978
1979 if (Tok.is(MMToken::Period)) {
1980 consumeToken();
1981 continue;
1982 }
1983
1984 break;
1985 }
1986
1987 if(Tok.is(MMToken::Star)) {
1988 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001989 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001990 break;
1991 }
1992
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001993 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001994 HadError = true;
1995 return;
1996 } while (true);
1997
1998 Module::UnresolvedExportDecl Unresolved = {
1999 ExportLoc, ParsedModuleId, Wildcard
2000 };
2001 ActiveModule->UnresolvedExports.push_back(Unresolved);
2002}
2003
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002004/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002005///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002006/// use-declaration:
2007/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002008void ModuleMapParser::parseUseDecl() {
2009 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002010 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002011 // Parse the module-id.
2012 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002013 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002014
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002015 if (ActiveModule->Parent)
2016 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2017 else
2018 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002019}
2020
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002021/// \brief Parse a link declaration.
2022///
2023/// module-declaration:
2024/// 'link' 'framework'[opt] string-literal
2025void ModuleMapParser::parseLinkDecl() {
2026 assert(Tok.is(MMToken::LinkKeyword));
2027 SourceLocation LinkLoc = consumeToken();
2028
2029 // Parse the optional 'framework' keyword.
2030 bool IsFramework = false;
2031 if (Tok.is(MMToken::FrameworkKeyword)) {
2032 consumeToken();
2033 IsFramework = true;
2034 }
2035
2036 // Parse the library name
2037 if (!Tok.is(MMToken::StringLiteral)) {
2038 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2039 << IsFramework << SourceRange(LinkLoc);
2040 HadError = true;
2041 return;
2042 }
2043
2044 std::string LibraryName = Tok.getString();
2045 consumeToken();
2046 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2047 IsFramework));
2048}
2049
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002050/// \brief Parse a configuration macro declaration.
2051///
2052/// module-declaration:
2053/// 'config_macros' attributes[opt] config-macro-list?
2054///
2055/// config-macro-list:
2056/// identifier (',' identifier)?
2057void ModuleMapParser::parseConfigMacros() {
2058 assert(Tok.is(MMToken::ConfigMacros));
2059 SourceLocation ConfigMacrosLoc = consumeToken();
2060
2061 // Only top-level modules can have configuration macros.
2062 if (ActiveModule->Parent) {
2063 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2064 }
2065
2066 // Parse the optional attributes.
2067 Attributes Attrs;
2068 parseOptionalAttributes(Attrs);
2069 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2070 ActiveModule->ConfigMacrosExhaustive = true;
2071 }
2072
2073 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002074 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002075 if (!Tok.is(MMToken::Identifier))
2076 return;
2077
2078 // Consume the first identifier.
2079 if (!ActiveModule->Parent) {
2080 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2081 }
2082 consumeToken();
2083
2084 do {
2085 // If there's a comma, consume it.
2086 if (!Tok.is(MMToken::Comma))
2087 break;
2088 consumeToken();
2089
2090 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002091 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002092 if (!Tok.is(MMToken::Identifier)) {
2093 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2094 break;
2095 }
2096
2097 // Consume the macro name.
2098 if (!ActiveModule->Parent) {
2099 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2100 }
2101 consumeToken();
2102 } while (true);
2103}
2104
Douglas Gregorfb912652013-03-20 21:10:35 +00002105/// \brief Format a module-id into a string.
2106static std::string formatModuleId(const ModuleId &Id) {
2107 std::string result;
2108 {
2109 llvm::raw_string_ostream OS(result);
2110
2111 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2112 if (I)
2113 OS << ".";
2114 OS << Id[I].first;
2115 }
2116 }
2117
2118 return result;
2119}
2120
2121/// \brief Parse a conflict declaration.
2122///
2123/// module-declaration:
2124/// 'conflict' module-id ',' string-literal
2125void ModuleMapParser::parseConflict() {
2126 assert(Tok.is(MMToken::Conflict));
2127 SourceLocation ConflictLoc = consumeToken();
2128 Module::UnresolvedConflict Conflict;
2129
2130 // Parse the module-id.
2131 if (parseModuleId(Conflict.Id))
2132 return;
2133
2134 // Parse the ','.
2135 if (!Tok.is(MMToken::Comma)) {
2136 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2137 << SourceRange(ConflictLoc);
2138 return;
2139 }
2140 consumeToken();
2141
2142 // Parse the message.
2143 if (!Tok.is(MMToken::StringLiteral)) {
2144 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2145 << formatModuleId(Conflict.Id);
2146 return;
2147 }
2148 Conflict.Message = Tok.getString().str();
2149 consumeToken();
2150
2151 // Add this unresolved conflict.
2152 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2153}
2154
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002155/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002156///
2157/// module-declaration:
2158/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2159/// { inferred-module-member* }
2160///
2161/// inferred-module-member:
2162/// 'export' '*'
2163/// 'exclude' identifier
2164void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002165 assert(Tok.is(MMToken::Star));
2166 SourceLocation StarLoc = consumeToken();
2167 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002168
Douglas Gregor73441092011-12-05 22:27:44 +00002169 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002170 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002171 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2172 Failed = true;
2173 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002174
2175 if (ActiveModule) {
2176 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002177 if (!Failed && ActiveModule->IsAvailable &&
2178 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002179 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2180 Failed = true;
2181 }
2182
2183 // Check for redefinition of an inferred module.
2184 if (!Failed && ActiveModule->InferSubmodules) {
2185 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2186 if (ActiveModule->InferredSubmoduleLoc.isValid())
2187 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2188 diag::note_mmap_prev_definition);
2189 Failed = true;
2190 }
2191
2192 // Check for the 'framework' keyword, which is not permitted here.
2193 if (Framework) {
2194 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2195 Framework = false;
2196 }
2197 } else if (Explicit) {
2198 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2199 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002200 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002201
Douglas Gregor73441092011-12-05 22:27:44 +00002202 // If there were any problems with this inferred submodule, skip its body.
2203 if (Failed) {
2204 if (Tok.is(MMToken::LBrace)) {
2205 consumeToken();
2206 skipUntil(MMToken::RBrace);
2207 if (Tok.is(MMToken::RBrace))
2208 consumeToken();
2209 }
2210 HadError = true;
2211 return;
2212 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002213
2214 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002215 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002216 parseOptionalAttributes(Attrs);
2217
2218 if (ActiveModule) {
2219 // Note that we have an inferred submodule.
2220 ActiveModule->InferSubmodules = true;
2221 ActiveModule->InferredSubmoduleLoc = StarLoc;
2222 ActiveModule->InferExplicitSubmodules = Explicit;
2223 } else {
2224 // We'll be inferring framework modules for this directory.
2225 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002226 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002227 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002228 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002229 }
2230
Douglas Gregor73441092011-12-05 22:27:44 +00002231 // Parse the opening brace.
2232 if (!Tok.is(MMToken::LBrace)) {
2233 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2234 HadError = true;
2235 return;
2236 }
2237 SourceLocation LBraceLoc = consumeToken();
2238
2239 // Parse the body of the inferred submodule.
2240 bool Done = false;
2241 do {
2242 switch (Tok.Kind) {
2243 case MMToken::EndOfFile:
2244 case MMToken::RBrace:
2245 Done = true;
2246 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002247
2248 case MMToken::ExcludeKeyword: {
2249 if (ActiveModule) {
2250 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002251 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002252 consumeToken();
2253 break;
2254 }
2255
2256 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002257 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002258 if (!Tok.is(MMToken::Identifier)) {
2259 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2260 break;
2261 }
2262
2263 Map.InferredDirectories[Directory].ExcludedModules
2264 .push_back(Tok.getString());
2265 consumeToken();
2266 break;
2267 }
2268
2269 case MMToken::ExportKeyword:
2270 if (!ActiveModule) {
2271 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002272 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002273 consumeToken();
2274 break;
2275 }
2276
Douglas Gregor73441092011-12-05 22:27:44 +00002277 consumeToken();
2278 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002279 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002280 else
2281 Diags.Report(Tok.getLocation(),
2282 diag::err_mmap_expected_export_wildcard);
2283 consumeToken();
2284 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002285
Douglas Gregor73441092011-12-05 22:27:44 +00002286 case MMToken::ExplicitKeyword:
2287 case MMToken::ModuleKeyword:
2288 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002289 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002290 case MMToken::UmbrellaKeyword:
2291 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002292 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002293 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002294 consumeToken();
2295 break;
2296 }
2297 } while (!Done);
2298
2299 if (Tok.is(MMToken::RBrace))
2300 consumeToken();
2301 else {
2302 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2303 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2304 HadError = true;
2305 }
2306}
2307
Douglas Gregor9194a912012-11-06 19:39:40 +00002308/// \brief Parse optional attributes.
2309///
2310/// attributes:
2311/// attribute attributes
2312/// attribute
2313///
2314/// attribute:
2315/// [ identifier ]
2316///
2317/// \param Attrs Will be filled in with the parsed attributes.
2318///
2319/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002320bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002321 bool HadError = false;
2322
2323 while (Tok.is(MMToken::LSquare)) {
2324 // Consume the '['.
2325 SourceLocation LSquareLoc = consumeToken();
2326
2327 // Check whether we have an attribute name here.
2328 if (!Tok.is(MMToken::Identifier)) {
2329 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2330 skipUntil(MMToken::RSquare);
2331 if (Tok.is(MMToken::RSquare))
2332 consumeToken();
2333 HadError = true;
2334 }
2335
2336 // Decode the attribute name.
2337 AttributeKind Attribute
2338 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002339 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002340 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002341 .Case("system", AT_system)
2342 .Default(AT_unknown);
2343 switch (Attribute) {
2344 case AT_unknown:
2345 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2346 << Tok.getString();
2347 break;
2348
2349 case AT_system:
2350 Attrs.IsSystem = true;
2351 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002352
Richard Smith77944862014-03-02 05:58:18 +00002353 case AT_extern_c:
2354 Attrs.IsExternC = true;
2355 break;
2356
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002357 case AT_exhaustive:
2358 Attrs.IsExhaustive = true;
2359 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002360 }
2361 consumeToken();
2362
2363 // Consume the ']'.
2364 if (!Tok.is(MMToken::RSquare)) {
2365 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2366 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2367 skipUntil(MMToken::RSquare);
2368 HadError = true;
2369 }
2370
2371 if (Tok.is(MMToken::RSquare))
2372 consumeToken();
2373 }
2374
2375 return HadError;
2376}
2377
Douglas Gregor718292f2011-11-11 19:10:28 +00002378/// \brief Parse a module map file.
2379///
2380/// module-map-file:
2381/// module-declaration*
2382bool ModuleMapParser::parseModuleMapFile() {
2383 do {
2384 switch (Tok.Kind) {
2385 case MMToken::EndOfFile:
2386 return HadError;
2387
Douglas Gregore7ab3662011-12-07 02:23:45 +00002388 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002389 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002390 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002391 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002392 parseModuleDecl();
2393 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002394
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002395 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002396 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002397 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002398 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002399 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002400 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002401 case MMToken::HeaderKeyword:
2402 case MMToken::Identifier:
2403 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002404 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002405 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002406 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002407 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002408 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002409 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002410 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002411 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002412 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002413 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002414 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002415 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002416 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2417 HadError = true;
2418 consumeToken();
2419 break;
2420 }
2421 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002422}
2423
Richard Smith9acb99e32014-12-10 03:09:48 +00002424bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smithae6df272015-07-14 02:06:01 +00002425 const DirectoryEntry *Dir,
2426 SourceLocation ExternModuleLoc) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002427 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2428 = ParsedModuleMap.find(File);
2429 if (Known != ParsedModuleMap.end())
2430 return Known->second;
2431
Craig Topperd2d442c2014-05-17 23:10:59 +00002432 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002433 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
Richard Smithae6df272015-07-14 02:06:01 +00002434 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002435 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002436 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002437 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002438
Douglas Gregor718292f2011-11-11 19:10:28 +00002439 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002440 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Richard Smith2a6edb32015-08-09 04:46:57 +00002441 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002442 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002443 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002444 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002445 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002446
2447 // Notify callbacks that we parsed it.
2448 for (const auto &Cb : Callbacks)
2449 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002450 return Result;
2451}