blob: f39928a44a8cc020d5ae7a64b47300b958ed54ba [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);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000584
585 // The library name of a framework has more than one possible extension since
586 // the introduction of the text-based dynamic library format. We need to check
587 // for both before we give up.
588 static const char *frameworkExtensions[] = {"", ".tbd"};
589 for (const auto *extension : frameworkExtensions) {
590 llvm::sys::path::replace_extension(LibName, extension);
591 if (FileMgr.getFile(LibName)) {
592 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
593 /*IsFramework=*/true));
594 return;
595 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000596 }
597}
598
Ben Langmuira5254002015-07-02 13:19:48 +0000599Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
600 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000601 Attributes Attrs;
602 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000603 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000604}
605
Ben Langmuira5254002015-07-02 13:19:48 +0000606Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000607 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000608 // Note: as an egregious but useful hack we use the real path here, because
609 // we might be looking at an embedded framework that symlinks out to a
610 // top-level framework, and we need to infer as if we were naming the
611 // top-level framework.
612 StringRef FrameworkDirName =
613 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
614
615 // In case this is a case-insensitive filesystem, use the canonical
616 // directory name as the ModuleName, since modules are case-sensitive.
617 // FIXME: we should be able to give a fix-it hint for the correct spelling.
618 SmallString<32> ModuleNameStorage;
619 StringRef ModuleName = sanitizeFilenameAsIdentifier(
620 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000621
Douglas Gregor56c64012011-11-17 01:41:17 +0000622 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000623 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
624 return Mod;
625
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000626 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000627
628 // If the framework has a parent path from which we're allowed to infer
629 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000630 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000631 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000632 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000633 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000634 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000635 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000636 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000637 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
638 // Check whether we have already looked into the parent directory
639 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000640 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000641 inferred = InferredDirectories.find(ParentDir);
642 if (inferred == InferredDirectories.end()) {
643 // We haven't looked here before. Load a module map, if there is
644 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000645 bool IsFrameworkDir = Parent.endswith(".framework");
646 if (const FileEntry *ModMapFile =
647 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000648 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000649 inferred = InferredDirectories.find(ParentDir);
650 }
651
652 if (inferred == InferredDirectories.end())
653 inferred = InferredDirectories.insert(
654 std::make_pair(ParentDir, InferredDirectory())).first;
655 }
656
657 if (inferred->second.InferModules) {
658 // We're allowed to infer for this directory, but make sure it's okay
659 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000660 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000661 canInfer = std::find(inferred->second.ExcludedModules.begin(),
662 inferred->second.ExcludedModules.end(),
663 Name) == inferred->second.ExcludedModules.end();
664
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000665 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
666 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
667 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000668 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000669 }
670 }
671 }
672
673 // If we're not allowed to infer a framework module, don't.
674 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000675 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000676 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000677 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000678
679
Douglas Gregor56c64012011-11-17 01:41:17 +0000680 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000681 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000682 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000683 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000684
685 // FIXME: If there's no umbrella header, we could probably scan the
686 // framework to load *everything*. But, it's not clear that this is a good
687 // idea.
688 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000689 return nullptr;
690
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000691 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000692 /*IsFramework=*/true, /*IsExplicit=*/false,
693 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000694 InferredModuleAllowedBy[Result] = ModuleMapFile;
695 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000696 if (LangOpts.CurrentModule == ModuleName) {
697 SourceModule = Result;
698 SourceModuleName = ModuleName;
699 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000700
701 Result->IsSystem |= Attrs.IsSystem;
702 Result->IsExternC |= Attrs.IsExternC;
703 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Richard Smith2b63d152015-05-16 02:28:53 +0000704 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000705
Douglas Gregoreb90e832012-01-04 23:32:19 +0000706 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000707 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000708
Douglas Gregor322f6332011-12-08 18:00:48 +0000709 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000710 //
711 // The "Headers/" component of the name is implied because this is
712 // a framework module.
713 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000714
715 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000716 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
717
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000718 // module * { export * }
719 Result->InferSubmodules = true;
720 Result->InferExportWildcard = true;
721
Douglas Gregore89dbc12011-12-06 19:39:29 +0000722 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000723 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000724 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000725 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000726 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000727 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000728 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000729 Dir != DirEnd && !EC; Dir.increment(EC)) {
730 if (!StringRef(Dir->path()).endswith(".framework"))
731 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000732
Douglas Gregore89dbc12011-12-06 19:39:29 +0000733 if (const DirectoryEntry *SubframeworkDir
734 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000735 // Note: as an egregious but useful hack, we use the real path here and
736 // check whether it is actually a subdirectory of the parent directory.
737 // This will not be the case if the 'subframework' is actually a symlink
738 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000739 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
740 bool FoundParent = false;
741 do {
742 // Get the parent directory name.
743 SubframeworkDirName
744 = llvm::sys::path::parent_path(SubframeworkDirName);
745 if (SubframeworkDirName.empty())
746 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000747
Douglas Gregore00c8b22013-01-26 00:55:12 +0000748 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
749 FoundParent = true;
750 break;
751 }
752 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000753
Douglas Gregore00c8b22013-01-26 00:55:12 +0000754 if (!FoundParent)
755 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000756
Douglas Gregore89dbc12011-12-06 19:39:29 +0000757 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000758 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000759 }
760 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000761
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000762 // If the module is a top-level framework, automatically link against the
763 // framework.
764 if (!Result->isSubFramework()) {
765 inferFrameworkLink(Result, FrameworkDir, FileMgr);
766 }
767
Douglas Gregor56c64012011-11-17 01:41:17 +0000768 return Result;
769}
770
Richard Smith2b63d152015-05-16 02:28:53 +0000771void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
772 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000773 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000774 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000775 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000776 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000777}
778
Richard Smith2b63d152015-05-16 02:28:53 +0000779void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
780 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000781 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000782 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000783 UmbrellaDirs[UmbrellaDir] = Mod;
784}
785
Richard Smith3c1a41a2014-12-02 00:08:08 +0000786static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000787 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000788 default: llvm_unreachable("unknown header role");
789 case ModuleMap::NormalHeader:
790 return Module::HK_Normal;
791 case ModuleMap::PrivateHeader:
792 return Module::HK_Private;
793 case ModuleMap::TextualHeader:
794 return Module::HK_Textual;
795 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
796 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000797 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000798}
799
Richard Smith3c1a41a2014-12-02 00:08:08 +0000800void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000801 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000802 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000803
Richard Smith386bb072015-08-18 23:42:23 +0000804 // Only add each header to the headers list once.
805 // FIXME: Should we diagnose if a header is listed twice in the
806 // same module definition?
807 auto &HeaderList = Headers[Header.Entry];
808 for (auto H : HeaderList)
809 if (H == KH)
810 return;
811
812 HeaderList.push_back(KH);
Richard Smith3c1a41a2014-12-02 00:08:08 +0000813 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
Richard Smith386bb072015-08-18 23:42:23 +0000814
815 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000816 if (!Imported || isCompilingModuleHeader) {
817 // When we import HeaderFileInfo, the external source is expected to
818 // set the isModuleHeader flag itself.
819 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
820 isCompilingModuleHeader);
821 }
Richard Smith3c1a41a2014-12-02 00:08:08 +0000822}
823
824void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000825 // Add this as a known header so we won't implicitly add it to any
826 // umbrella directory module.
827 // FIXME: Should we only exclude it from umbrella modules within the
828 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000829 (void) Headers[Header.Entry];
830
831 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000832}
833
Douglas Gregor514b6362011-11-29 19:06:37 +0000834const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000835ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000836 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000837 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000838
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000839 return SourceMgr.getFileEntryForID(
840 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000841}
842
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000843const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000844 if (M->IsInferred) {
845 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
846 return InferredModuleAllowedBy.find(M)->second;
847 }
848 return getContainingModuleMapFile(M);
849}
850
851void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
852 assert(M->IsInferred && "module not inferred");
853 InferredModuleAllowedBy[M] = ModMap;
854}
855
Yaron Kerencdae9412016-01-29 19:38:18 +0000856LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +0000857 llvm::errs() << "Modules:";
858 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
859 MEnd = Modules.end();
860 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000861 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000862
863 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000864 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000865 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000866 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
867 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
868 E = H->second.end();
869 I != E; ++I) {
870 if (I != H->second.begin())
871 llvm::errs() << ",";
872 llvm::errs() << I->getModule()->getFullModuleName();
873 }
874 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000875 }
876}
877
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000878bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000879 auto Unresolved = std::move(Mod->UnresolvedExports);
880 Mod->UnresolvedExports.clear();
881 for (auto &UE : Unresolved) {
882 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000883 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000884 Mod->Exports.push_back(Export);
885 else
Richard Smith42413142015-05-15 20:05:43 +0000886 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000887 }
Richard Smith42413142015-05-15 20:05:43 +0000888 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000889}
890
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000891bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000892 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
893 Mod->UnresolvedDirectUses.clear();
894 for (auto &UDU : Unresolved) {
895 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000896 if (DirectUse)
897 Mod->DirectUses.push_back(DirectUse);
898 else
Richard Smith42413142015-05-15 20:05:43 +0000899 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000900 }
Richard Smith42413142015-05-15 20:05:43 +0000901 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000902}
903
Douglas Gregorfb912652013-03-20 21:10:35 +0000904bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000905 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000906 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000907 for (auto &UC : Unresolved) {
908 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
909 Module::Conflict Conflict;
910 Conflict.Other = OtherMod;
911 Conflict.Message = UC.Message;
912 Mod->Conflicts.push_back(Conflict);
913 } else
914 Mod->UnresolvedConflicts.push_back(UC);
915 }
916 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000917}
918
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000919Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
920 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000921 return nullptr;
922
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000923 // Use the expansion location to determine which module we're in.
924 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
925 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000926 return nullptr;
927
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000928 const SourceManager &SrcMgr = Loc.getManager();
929 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000930
Douglas Gregor224d8a72012-01-06 17:19:32 +0000931 while (const FileEntry *ExpansionFile
932 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
933 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000934 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000935 return Mod;
936
937 // No module owns this header, so look up the inclusion chain to see if
938 // any included header has an associated module.
939 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
940 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000941 return nullptr;
942
Douglas Gregor224d8a72012-01-06 17:19:32 +0000943 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
944 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000945
946 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000947}
948
Douglas Gregor718292f2011-11-11 19:10:28 +0000949//----------------------------------------------------------------------------//
950// Module map file parser
951//----------------------------------------------------------------------------//
952
953namespace clang {
954 /// \brief A token in a module map file.
955 struct MMToken {
956 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000957 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000958 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000959 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000960 EndOfFile,
961 HeaderKeyword,
962 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000963 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000964 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000965 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000966 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000967 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000968 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000969 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000970 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000971 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000972 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000973 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000974 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000975 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000976 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000977 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000978 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000979 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000980 RBrace,
981 LSquare,
982 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000983 } Kind;
984
985 unsigned Location;
986 unsigned StringLength;
987 const char *StringData;
988
989 void clear() {
990 Kind = EndOfFile;
991 Location = 0;
992 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000993 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000994 }
995
996 bool is(TokenKind K) const { return Kind == K; }
997
998 SourceLocation getLocation() const {
999 return SourceLocation::getFromRawEncoding(Location);
1000 }
1001
1002 StringRef getString() const {
1003 return StringRef(StringData, StringLength);
1004 }
1005 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001006
Douglas Gregor718292f2011-11-11 19:10:28 +00001007 class ModuleMapParser {
1008 Lexer &L;
1009 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001010
1011 /// \brief Default target information, used only for string literal
1012 /// parsing.
1013 const TargetInfo *Target;
1014
Douglas Gregor718292f2011-11-11 19:10:28 +00001015 DiagnosticsEngine &Diags;
1016 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001017
1018 /// \brief The current module map file.
1019 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001020
Richard Smith9acb99e32014-12-10 03:09:48 +00001021 /// \brief The directory that file names in this module map file should
1022 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001023 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001024
1025 /// \brief The directory containing Clang-supplied headers.
1026 const DirectoryEntry *BuiltinIncludeDir;
1027
Douglas Gregor963c5532013-06-21 16:28:10 +00001028 /// \brief Whether this module map is in a system header directory.
1029 bool IsSystem;
1030
Douglas Gregor718292f2011-11-11 19:10:28 +00001031 /// \brief Whether an error occurred.
1032 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001033
Douglas Gregor718292f2011-11-11 19:10:28 +00001034 /// \brief Stores string data for the various string literals referenced
1035 /// during parsing.
1036 llvm::BumpPtrAllocator StringData;
1037
1038 /// \brief The current token.
1039 MMToken Tok;
1040
1041 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001042 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001043
1044 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1045 /// contents as 'textual'.
1046 ///
1047 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1048 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1049 /// non-modular headers. For backwards compatibility, we continue to
1050 /// support this idiom for just these modules, and map the headers to
1051 /// 'textual' to match the original intent.
1052 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1053
Douglas Gregor718292f2011-11-11 19:10:28 +00001054 /// \brief Consume the current token and return its location.
1055 SourceLocation consumeToken();
1056
1057 /// \brief Skip tokens until we reach the a token with the given kind
1058 /// (or the end of the file).
1059 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001060
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001061 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001062 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001063 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001064 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001065 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001066 void parseHeaderDecl(clang::MMToken::TokenKind,
1067 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001068 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001069 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001070 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001071 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001072 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001073 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001074 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001075
1076 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001077 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001078
Douglas Gregor718292f2011-11-11 19:10:28 +00001079 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001080 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001081 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001082 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001083 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001084 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001085 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001086 const DirectoryEntry *BuiltinIncludeDir,
1087 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001088 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001089 ModuleMapFile(ModuleMapFile), Directory(Directory),
1090 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001091 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001092 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001093 Tok.clear();
1094 consumeToken();
1095 }
1096
1097 bool parseModuleMapFile();
1098 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001099}
Douglas Gregor718292f2011-11-11 19:10:28 +00001100
1101SourceLocation ModuleMapParser::consumeToken() {
1102retry:
1103 SourceLocation Result = Tok.getLocation();
1104 Tok.clear();
1105
1106 Token LToken;
1107 L.LexFromRawLexer(LToken);
1108 Tok.Location = LToken.getLocation().getRawEncoding();
1109 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001110 case tok::raw_identifier: {
1111 StringRef RI = LToken.getRawIdentifier();
1112 Tok.StringData = RI.data();
1113 Tok.StringLength = RI.size();
1114 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001115 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001116 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001117 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001118 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001119 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001120 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001121 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001122 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001123 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001124 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001125 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001126 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001127 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001128 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001129 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001130 .Default(MMToken::Identifier);
1131 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001132 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001133
1134 case tok::comma:
1135 Tok.Kind = MMToken::Comma;
1136 break;
1137
Douglas Gregor718292f2011-11-11 19:10:28 +00001138 case tok::eof:
1139 Tok.Kind = MMToken::EndOfFile;
1140 break;
1141
1142 case tok::l_brace:
1143 Tok.Kind = MMToken::LBrace;
1144 break;
1145
Douglas Gregora686e1b2012-01-27 19:52:33 +00001146 case tok::l_square:
1147 Tok.Kind = MMToken::LSquare;
1148 break;
1149
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001150 case tok::period:
1151 Tok.Kind = MMToken::Period;
1152 break;
1153
Douglas Gregor718292f2011-11-11 19:10:28 +00001154 case tok::r_brace:
1155 Tok.Kind = MMToken::RBrace;
1156 break;
1157
Douglas Gregora686e1b2012-01-27 19:52:33 +00001158 case tok::r_square:
1159 Tok.Kind = MMToken::RSquare;
1160 break;
1161
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001162 case tok::star:
1163 Tok.Kind = MMToken::Star;
1164 break;
1165
Richard Smitha3feee22013-10-28 22:18:19 +00001166 case tok::exclaim:
1167 Tok.Kind = MMToken::Exclaim;
1168 break;
1169
Douglas Gregor718292f2011-11-11 19:10:28 +00001170 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001171 if (LToken.hasUDSuffix()) {
1172 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1173 HadError = true;
1174 goto retry;
1175 }
1176
Douglas Gregor718292f2011-11-11 19:10:28 +00001177 // Parse the string literal.
1178 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001179 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001180 if (StringLiteral.hadError)
1181 goto retry;
1182
1183 // Copy the string literal into our string data allocator.
1184 unsigned Length = StringLiteral.GetStringLength();
1185 char *Saved = StringData.Allocate<char>(Length + 1);
1186 memcpy(Saved, StringLiteral.GetString().data(), Length);
1187 Saved[Length] = 0;
1188
1189 // Form the token.
1190 Tok.Kind = MMToken::StringLiteral;
1191 Tok.StringData = Saved;
1192 Tok.StringLength = Length;
1193 break;
1194 }
1195
1196 case tok::comment:
1197 goto retry;
1198
1199 default:
1200 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1201 HadError = true;
1202 goto retry;
1203 }
1204
1205 return Result;
1206}
1207
1208void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1209 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001210 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001211 do {
1212 switch (Tok.Kind) {
1213 case MMToken::EndOfFile:
1214 return;
1215
1216 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001217 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001218 return;
1219
1220 ++braceDepth;
1221 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001222
1223 case MMToken::LSquare:
1224 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1225 return;
1226
1227 ++squareDepth;
1228 break;
1229
Douglas Gregor718292f2011-11-11 19:10:28 +00001230 case MMToken::RBrace:
1231 if (braceDepth > 0)
1232 --braceDepth;
1233 else if (Tok.is(K))
1234 return;
1235 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001236
1237 case MMToken::RSquare:
1238 if (squareDepth > 0)
1239 --squareDepth;
1240 else if (Tok.is(K))
1241 return;
1242 break;
1243
Douglas Gregor718292f2011-11-11 19:10:28 +00001244 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001245 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001246 return;
1247 break;
1248 }
1249
1250 consumeToken();
1251 } while (true);
1252}
1253
Douglas Gregore7ab3662011-12-07 02:23:45 +00001254/// \brief Parse a module-id.
1255///
1256/// module-id:
1257/// identifier
1258/// identifier '.' module-id
1259///
1260/// \returns true if an error occurred, false otherwise.
1261bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1262 Id.clear();
1263 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001264 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001265 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1266 consumeToken();
1267 } else {
1268 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1269 return true;
1270 }
1271
1272 if (!Tok.is(MMToken::Period))
1273 break;
1274
1275 consumeToken();
1276 } while (true);
1277
1278 return false;
1279}
1280
Douglas Gregora686e1b2012-01-27 19:52:33 +00001281namespace {
1282 /// \brief Enumerates the known attributes.
1283 enum AttributeKind {
1284 /// \brief An unknown attribute.
1285 AT_unknown,
1286 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001287 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001288 /// \brief The 'extern_c' attribute.
1289 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001290 /// \brief The 'exhaustive' attribute.
1291 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001292 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001293}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001294
Douglas Gregor718292f2011-11-11 19:10:28 +00001295/// \brief Parse a module declaration.
1296///
1297/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001298/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001299/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1300/// { module-member* }
1301///
Douglas Gregor718292f2011-11-11 19:10:28 +00001302/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001303/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001304/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001305/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001306/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001307/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001308///
1309/// submodule-declaration:
1310/// module-declaration
1311/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001312void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001313 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001314 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1315 if (Tok.is(MMToken::ExternKeyword)) {
1316 parseExternModuleDecl();
1317 return;
1318 }
1319
Douglas Gregorf2161a72011-12-06 17:16:41 +00001320 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001321 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001322 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001323 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001324
Douglas Gregorf2161a72011-12-06 17:16:41 +00001325 // Parse 'explicit' keyword, if present.
1326 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001327 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001328 Explicit = true;
1329 }
1330
1331 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001332 if (Tok.is(MMToken::FrameworkKeyword)) {
1333 consumeToken();
1334 Framework = true;
1335 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001336
1337 // Parse 'module' keyword.
1338 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001339 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001340 consumeToken();
1341 HadError = true;
1342 return;
1343 }
1344 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001345
1346 // If we have a wildcard for the module name, this is an inferred submodule.
1347 // Parse it.
1348 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001349 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001350
1351 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001352 ModuleId Id;
1353 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001354 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001355 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001356 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001357
Douglas Gregore7ab3662011-12-07 02:23:45 +00001358 if (ActiveModule) {
1359 if (Id.size() > 1) {
1360 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1361 << SourceRange(Id.front().second, Id.back().second);
1362
1363 HadError = true;
1364 return;
1365 }
1366 } else if (Id.size() == 1 && Explicit) {
1367 // Top-level modules can't be explicit.
1368 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1369 Explicit = false;
1370 ExplicitLoc = SourceLocation();
1371 HadError = true;
1372 }
1373
1374 Module *PreviousActiveModule = ActiveModule;
1375 if (Id.size() > 1) {
1376 // This module map defines a submodule. Go find the module of which it
1377 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001378 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001379 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001380 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1381 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001382 if (I == 0)
1383 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001384 ActiveModule = Next;
1385 continue;
1386 }
1387
1388 if (ActiveModule) {
1389 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001390 << Id[I].first
1391 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001392 } else {
1393 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1394 }
1395 HadError = true;
1396 return;
1397 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001398
1399 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1400 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1401 "submodule defined in same file as 'module *' that allowed its "
1402 "top-level module");
1403 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1404 }
1405 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001406
1407 StringRef ModuleName = Id.back().first;
1408 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001409
Douglas Gregora686e1b2012-01-27 19:52:33 +00001410 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001411 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001412 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001413
Douglas Gregor718292f2011-11-11 19:10:28 +00001414 // Parse the opening brace.
1415 if (!Tok.is(MMToken::LBrace)) {
1416 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1417 << ModuleName;
1418 HadError = true;
1419 return;
1420 }
1421 SourceLocation LBraceLoc = consumeToken();
1422
1423 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001424 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001425 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1426 // Skip the module definition.
1427 skipUntil(MMToken::RBrace);
1428 if (Tok.is(MMToken::RBrace))
1429 consumeToken();
1430 else {
1431 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1432 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1433 HadError = true;
1434 }
1435 return;
1436 }
1437
Douglas Gregor718292f2011-11-11 19:10:28 +00001438 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1439 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001440 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001441
1442 // Skip the module definition.
1443 skipUntil(MMToken::RBrace);
1444 if (Tok.is(MMToken::RBrace))
1445 consumeToken();
1446
1447 HadError = true;
1448 return;
1449 }
1450
1451 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001452 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1453 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001454 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001455 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001456 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001457 if (Attrs.IsExternC)
1458 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001459 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001460
Douglas Gregor718292f2011-11-11 19:10:28 +00001461 bool Done = false;
1462 do {
1463 switch (Tok.Kind) {
1464 case MMToken::EndOfFile:
1465 case MMToken::RBrace:
1466 Done = true;
1467 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001468
1469 case MMToken::ConfigMacros:
1470 parseConfigMacros();
1471 break;
1472
Douglas Gregorfb912652013-03-20 21:10:35 +00001473 case MMToken::Conflict:
1474 parseConflict();
1475 break;
1476
Douglas Gregor718292f2011-11-11 19:10:28 +00001477 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001478 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001479 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001480 case MMToken::ModuleKeyword:
1481 parseModuleDecl();
1482 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001483
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001484 case MMToken::ExportKeyword:
1485 parseExportDecl();
1486 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001487
1488 case MMToken::UseKeyword:
1489 parseUseDecl();
1490 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001491
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001492 case MMToken::RequiresKeyword:
1493 parseRequiresDecl();
1494 break;
1495
Richard Smith202210b2014-10-24 20:23:01 +00001496 case MMToken::TextualKeyword:
1497 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001498 break;
Richard Smith306d8922014-10-22 23:50:56 +00001499
Douglas Gregor524e33e2011-12-08 19:11:24 +00001500 case MMToken::UmbrellaKeyword: {
1501 SourceLocation UmbrellaLoc = consumeToken();
1502 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001503 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001504 else
1505 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001506 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001507 }
Richard Smith202210b2014-10-24 20:23:01 +00001508
1509 case MMToken::ExcludeKeyword:
1510 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001511 break;
Richard Smith202210b2014-10-24 20:23:01 +00001512
1513 case MMToken::PrivateKeyword:
1514 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001515 break;
Richard Smith202210b2014-10-24 20:23:01 +00001516
Douglas Gregor322f6332011-12-08 18:00:48 +00001517 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001518 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001519 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001520
1521 case MMToken::LinkKeyword:
1522 parseLinkDecl();
1523 break;
1524
Douglas Gregor718292f2011-11-11 19:10:28 +00001525 default:
1526 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1527 consumeToken();
1528 break;
1529 }
1530 } while (!Done);
1531
1532 if (Tok.is(MMToken::RBrace))
1533 consumeToken();
1534 else {
1535 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1536 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1537 HadError = true;
1538 }
1539
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001540 // If the active module is a top-level framework, and there are no link
1541 // libraries, automatically link against the framework.
1542 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1543 ActiveModule->LinkLibraries.empty()) {
1544 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1545 }
1546
Ben Langmuirec8c9752014-04-18 22:07:31 +00001547 // If the module meets all requirements but is still unavailable, mark the
1548 // whole tree as unavailable to prevent it from building.
1549 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1550 ActiveModule->Parent) {
1551 ActiveModule->getTopLevelModule()->markUnavailable();
1552 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1553 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1554 }
1555
Douglas Gregore7ab3662011-12-07 02:23:45 +00001556 // We're done parsing this module. Pop back to the previous module.
1557 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001558}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001559
Daniel Jasper97292842013-09-11 07:20:44 +00001560/// \brief Parse an extern module declaration.
1561///
1562/// extern module-declaration:
1563/// 'extern' 'module' module-id string-literal
1564void ModuleMapParser::parseExternModuleDecl() {
1565 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001566 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001567
1568 // Parse 'module' keyword.
1569 if (!Tok.is(MMToken::ModuleKeyword)) {
1570 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1571 consumeToken();
1572 HadError = true;
1573 return;
1574 }
1575 consumeToken(); // 'module' keyword
1576
1577 // Parse the module name.
1578 ModuleId Id;
1579 if (parseModuleId(Id)) {
1580 HadError = true;
1581 return;
1582 }
1583
1584 // Parse the referenced module map file name.
1585 if (!Tok.is(MMToken::StringLiteral)) {
1586 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1587 HadError = true;
1588 return;
1589 }
1590 std::string FileName = Tok.getString();
1591 consumeToken(); // filename
1592
1593 StringRef FileNameRef = FileName;
1594 SmallString<128> ModuleMapFileName;
1595 if (llvm::sys::path::is_relative(FileNameRef)) {
1596 ModuleMapFileName += Directory->getName();
1597 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001598 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001599 }
1600 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001601 Map.parseModuleMapFile(
1602 File, /*IsSystem=*/false,
1603 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1604 ? Directory
Richard Smithae6df272015-07-14 02:06:01 +00001605 : File->getDir(), ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001606}
1607
Ben Langmuir7ff29142015-08-13 17:13:33 +00001608/// Whether to add the requirement \p Feature to the module \p M.
1609///
1610/// This preserves backwards compatibility for two hacks in the Darwin system
1611/// module map files:
1612///
1613/// 1. The use of 'requires excluded' to make headers non-modular, which
1614/// should really be mapped to 'textual' now that we have this feature. We
1615/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1616/// true. Later, this bit will be used to map all the headers inside this
1617/// module to 'textual'.
1618///
1619/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1620///
1621/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1622/// was never correct and causes issues now that we check it, so drop it.
1623static bool shouldAddRequirement(Module *M, StringRef Feature,
1624 bool &IsRequiresExcludedHack) {
1625 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1626 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1627 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1628
1629 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1630 M->fullModuleNameIs(TclPrivate))) {
1631 IsRequiresExcludedHack = true;
1632 return false;
1633 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1634 return false;
1635 }
1636
1637 return true;
1638}
1639
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001640/// \brief Parse a requires declaration.
1641///
1642/// requires-declaration:
1643/// 'requires' feature-list
1644///
1645/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001646/// feature ',' feature-list
1647/// feature
1648///
1649/// feature:
1650/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001651void ModuleMapParser::parseRequiresDecl() {
1652 assert(Tok.is(MMToken::RequiresKeyword));
1653
1654 // Parse 'requires' keyword.
1655 consumeToken();
1656
1657 // Parse the feature-list.
1658 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001659 bool RequiredState = true;
1660 if (Tok.is(MMToken::Exclaim)) {
1661 RequiredState = false;
1662 consumeToken();
1663 }
1664
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001665 if (!Tok.is(MMToken::Identifier)) {
1666 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1667 HadError = true;
1668 return;
1669 }
1670
1671 // Consume the feature name.
1672 std::string Feature = Tok.getString();
1673 consumeToken();
1674
Ben Langmuir7ff29142015-08-13 17:13:33 +00001675 bool IsRequiresExcludedHack = false;
1676 bool ShouldAddRequirement =
1677 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1678
1679 if (IsRequiresExcludedHack)
1680 UsesRequiresExcludedHack.insert(ActiveModule);
1681
1682 if (ShouldAddRequirement) {
1683 // Add this feature.
1684 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1685 *Map.Target);
1686 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001687
1688 if (!Tok.is(MMToken::Comma))
1689 break;
1690
1691 // Consume the comma.
1692 consumeToken();
1693 } while (true);
1694}
1695
Douglas Gregorf2161a72011-12-06 17:16:41 +00001696/// \brief Append to \p Paths the set of paths needed to get to the
1697/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001698static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001699 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001700 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001701 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001702 for (; Mod; Mod = Mod->Parent) {
1703 if (Mod->IsFramework)
1704 Paths.push_back(Mod->Name);
1705 }
1706
1707 if (Paths.empty())
1708 return;
1709
1710 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001711 for (unsigned I = Paths.size() - 1; I != 0; --I)
1712 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001713}
1714
Douglas Gregor718292f2011-11-11 19:10:28 +00001715/// \brief Parse a header declaration.
1716///
1717/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001718/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001719/// 'private' 'textual'[opt] 'header' string-literal
1720/// 'exclude' 'header' string-literal
1721/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001722///
1723/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001724void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1725 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001726 // We've already consumed the first token.
1727 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1728 if (LeadingToken == MMToken::PrivateKeyword) {
1729 Role = ModuleMap::PrivateHeader;
1730 // 'private' may optionally be followed by 'textual'.
1731 if (Tok.is(MMToken::TextualKeyword)) {
1732 LeadingToken = Tok.Kind;
1733 consumeToken();
1734 }
1735 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001736
Richard Smith202210b2014-10-24 20:23:01 +00001737 if (LeadingToken == MMToken::TextualKeyword)
1738 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1739
Ben Langmuir7ff29142015-08-13 17:13:33 +00001740 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1741 // Mark this header 'textual' (see doc comment for
1742 // Module::UsesRequiresExcludedHack).
1743 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1744 }
1745
Richard Smith202210b2014-10-24 20:23:01 +00001746 if (LeadingToken != MMToken::HeaderKeyword) {
1747 if (!Tok.is(MMToken::HeaderKeyword)) {
1748 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1749 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1750 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1751 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1752 return;
1753 }
1754 consumeToken();
1755 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001756
Douglas Gregor718292f2011-11-11 19:10:28 +00001757 // Parse the header name.
1758 if (!Tok.is(MMToken::StringLiteral)) {
1759 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1760 << "header";
1761 HadError = true;
1762 return;
1763 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001764 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001765 Header.FileName = Tok.getString();
1766 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001767
Douglas Gregor524e33e2011-12-08 19:11:24 +00001768 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001769 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001770 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001771 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001772 HadError = true;
1773 return;
1774 }
1775
Douglas Gregor5257fc62011-11-11 21:55:48 +00001776 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001777 const FileEntry *File = nullptr;
1778 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001779 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001780 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001781 RelativePathName = Header.FileName;
1782 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001783 } else {
1784 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001785 SmallString<128> FullPathName(Directory->getName());
1786 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001787
Douglas Gregorf2161a72011-12-06 17:16:41 +00001788 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001789 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001790
1791 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001792 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001793 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001794 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001795
1796 if (!File) {
1797 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001798 // FIXME: Should we retain the subframework paths here?
1799 RelativePathName.clear();
1800 FullPathName.resize(FullPathLength);
1801 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1802 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001803 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001804 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001805 }
1806 } else {
1807 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001808 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001809 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001810 File = SourceMgr.getFileManager().getFile(FullPathName);
1811
Douglas Gregor3ec66632012-02-02 18:42:48 +00001812 // If this is a system module with a top-level header, this header
1813 // may have a counterpart (or replacement) in the set of headers
1814 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001815 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1816 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001817 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001818 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001819 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001820 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001821
Douglas Gregor3ec66632012-02-02 18:42:48 +00001822 // If Clang supplies this header but the underlying system does not,
1823 // just silently swap in our builtin version. Otherwise, we'll end
1824 // up adding both (later).
Richard Smith42413142015-05-15 20:05:43 +00001825 //
1826 // For local visibility, entirely replace the system file with our
1827 // one and textually include the system one. We need to pass macros
1828 // from our header to the system one if we #include_next it.
1829 //
1830 // FIXME: Can we do this in all cases?
1831 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001832 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001833 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001834 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001835 }
1836 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001837 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001838 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001839
Douglas Gregor5257fc62011-11-11 21:55:48 +00001840 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1841 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001842 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001843 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001844 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001845 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001846 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001847 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001848 HadError = true;
1849 } else {
1850 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001851 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001852 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001853 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001854 Module::Header H = {RelativePathName.str(), File};
1855 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001856 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001857 // If there is a builtin counterpart to this file, add it now, before
1858 // the "real" header, so we build the built-in one first when building
1859 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001860 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001861 // FIXME: Taking the name from the FileEntry is unstable and can give
1862 // different results depending on how we've previously named that file
1863 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001864 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1865 Map.addHeader(ActiveModule, H, Role);
1866 }
Richard Smith25d50752014-10-20 00:15:49 +00001867
Richard Smith202210b2014-10-24 20:23:01 +00001868 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001869 Module::Header H = { RelativePathName.str(), File };
1870 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001871 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001872 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001873 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001874
1875 // If we find a module that has a missing header, we mark this module as
1876 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001877 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001878 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001879 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001880 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001881}
1882
Ben Langmuir41f81992015-08-13 17:30:07 +00001883static int compareModuleHeaders(const Module::Header *A,
1884 const Module::Header *B) {
1885 return A->NameAsWritten.compare(B->NameAsWritten);
1886}
1887
Douglas Gregor524e33e2011-12-08 19:11:24 +00001888/// \brief Parse an umbrella directory declaration.
1889///
1890/// umbrella-dir-declaration:
1891/// umbrella string-literal
1892void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1893 // Parse the directory name.
1894 if (!Tok.is(MMToken::StringLiteral)) {
1895 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1896 << "umbrella";
1897 HadError = true;
1898 return;
1899 }
1900
1901 std::string DirName = Tok.getString();
1902 SourceLocation DirNameLoc = consumeToken();
1903
1904 // Check whether we already have an umbrella.
1905 if (ActiveModule->Umbrella) {
1906 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1907 << ActiveModule->getFullModuleName();
1908 HadError = true;
1909 return;
1910 }
1911
1912 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001913 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001914 if (llvm::sys::path::is_absolute(DirName))
1915 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1916 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001917 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001918 PathName = Directory->getName();
1919 llvm::sys::path::append(PathName, DirName);
1920 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1921 }
1922
1923 if (!Dir) {
1924 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1925 << DirName;
1926 HadError = true;
1927 return;
1928 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001929
1930 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1931 // Mark this header 'textual' (see doc comment for
1932 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1933 // directory is relatively expensive, in practice this only applies to the
1934 // uncommonly used Tcl module on Darwin platforms.
1935 std::error_code EC;
1936 SmallVector<Module::Header, 6> Headers;
1937 for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E;
1938 I != E && !EC; I.increment(EC)) {
1939 if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
1940
1941 Module::Header Header = {I->path(), FE};
1942 Headers.push_back(std::move(Header));
1943 }
1944 }
1945
1946 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00001947 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1948
Ben Langmuir7ff29142015-08-13 17:13:33 +00001949 for (auto &Header : Headers)
1950 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1951 return;
1952 }
1953
Douglas Gregor524e33e2011-12-08 19:11:24 +00001954 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1955 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1956 << OwningModule->getFullModuleName();
1957 HadError = true;
1958 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001959 }
1960
Douglas Gregor524e33e2011-12-08 19:11:24 +00001961 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00001962 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001963}
1964
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001965/// \brief Parse a module export declaration.
1966///
1967/// export-declaration:
1968/// 'export' wildcard-module-id
1969///
1970/// wildcard-module-id:
1971/// identifier
1972/// '*'
1973/// identifier '.' wildcard-module-id
1974void ModuleMapParser::parseExportDecl() {
1975 assert(Tok.is(MMToken::ExportKeyword));
1976 SourceLocation ExportLoc = consumeToken();
1977
1978 // Parse the module-id with an optional wildcard at the end.
1979 ModuleId ParsedModuleId;
1980 bool Wildcard = false;
1981 do {
Richard Smith306d8922014-10-22 23:50:56 +00001982 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001983 if (Tok.is(MMToken::Identifier)) {
1984 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1985 Tok.getLocation()));
1986 consumeToken();
1987
1988 if (Tok.is(MMToken::Period)) {
1989 consumeToken();
1990 continue;
1991 }
1992
1993 break;
1994 }
1995
1996 if(Tok.is(MMToken::Star)) {
1997 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001998 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001999 break;
2000 }
2001
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002002 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002003 HadError = true;
2004 return;
2005 } while (true);
2006
2007 Module::UnresolvedExportDecl Unresolved = {
2008 ExportLoc, ParsedModuleId, Wildcard
2009 };
2010 ActiveModule->UnresolvedExports.push_back(Unresolved);
2011}
2012
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002013/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002014///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002015/// use-declaration:
2016/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002017void ModuleMapParser::parseUseDecl() {
2018 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002019 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002020 // Parse the module-id.
2021 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002022 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002023
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002024 if (ActiveModule->Parent)
2025 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2026 else
2027 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002028}
2029
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002030/// \brief Parse a link declaration.
2031///
2032/// module-declaration:
2033/// 'link' 'framework'[opt] string-literal
2034void ModuleMapParser::parseLinkDecl() {
2035 assert(Tok.is(MMToken::LinkKeyword));
2036 SourceLocation LinkLoc = consumeToken();
2037
2038 // Parse the optional 'framework' keyword.
2039 bool IsFramework = false;
2040 if (Tok.is(MMToken::FrameworkKeyword)) {
2041 consumeToken();
2042 IsFramework = true;
2043 }
2044
2045 // Parse the library name
2046 if (!Tok.is(MMToken::StringLiteral)) {
2047 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2048 << IsFramework << SourceRange(LinkLoc);
2049 HadError = true;
2050 return;
2051 }
2052
2053 std::string LibraryName = Tok.getString();
2054 consumeToken();
2055 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2056 IsFramework));
2057}
2058
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002059/// \brief Parse a configuration macro declaration.
2060///
2061/// module-declaration:
2062/// 'config_macros' attributes[opt] config-macro-list?
2063///
2064/// config-macro-list:
2065/// identifier (',' identifier)?
2066void ModuleMapParser::parseConfigMacros() {
2067 assert(Tok.is(MMToken::ConfigMacros));
2068 SourceLocation ConfigMacrosLoc = consumeToken();
2069
2070 // Only top-level modules can have configuration macros.
2071 if (ActiveModule->Parent) {
2072 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2073 }
2074
2075 // Parse the optional attributes.
2076 Attributes Attrs;
2077 parseOptionalAttributes(Attrs);
2078 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2079 ActiveModule->ConfigMacrosExhaustive = true;
2080 }
2081
2082 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002083 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002084 if (!Tok.is(MMToken::Identifier))
2085 return;
2086
2087 // Consume the first identifier.
2088 if (!ActiveModule->Parent) {
2089 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2090 }
2091 consumeToken();
2092
2093 do {
2094 // If there's a comma, consume it.
2095 if (!Tok.is(MMToken::Comma))
2096 break;
2097 consumeToken();
2098
2099 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002100 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002101 if (!Tok.is(MMToken::Identifier)) {
2102 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2103 break;
2104 }
2105
2106 // Consume the macro name.
2107 if (!ActiveModule->Parent) {
2108 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2109 }
2110 consumeToken();
2111 } while (true);
2112}
2113
Douglas Gregorfb912652013-03-20 21:10:35 +00002114/// \brief Format a module-id into a string.
2115static std::string formatModuleId(const ModuleId &Id) {
2116 std::string result;
2117 {
2118 llvm::raw_string_ostream OS(result);
2119
2120 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2121 if (I)
2122 OS << ".";
2123 OS << Id[I].first;
2124 }
2125 }
2126
2127 return result;
2128}
2129
2130/// \brief Parse a conflict declaration.
2131///
2132/// module-declaration:
2133/// 'conflict' module-id ',' string-literal
2134void ModuleMapParser::parseConflict() {
2135 assert(Tok.is(MMToken::Conflict));
2136 SourceLocation ConflictLoc = consumeToken();
2137 Module::UnresolvedConflict Conflict;
2138
2139 // Parse the module-id.
2140 if (parseModuleId(Conflict.Id))
2141 return;
2142
2143 // Parse the ','.
2144 if (!Tok.is(MMToken::Comma)) {
2145 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2146 << SourceRange(ConflictLoc);
2147 return;
2148 }
2149 consumeToken();
2150
2151 // Parse the message.
2152 if (!Tok.is(MMToken::StringLiteral)) {
2153 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2154 << formatModuleId(Conflict.Id);
2155 return;
2156 }
2157 Conflict.Message = Tok.getString().str();
2158 consumeToken();
2159
2160 // Add this unresolved conflict.
2161 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2162}
2163
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002164/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002165///
2166/// module-declaration:
2167/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2168/// { inferred-module-member* }
2169///
2170/// inferred-module-member:
2171/// 'export' '*'
2172/// 'exclude' identifier
2173void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002174 assert(Tok.is(MMToken::Star));
2175 SourceLocation StarLoc = consumeToken();
2176 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002177
Douglas Gregor73441092011-12-05 22:27:44 +00002178 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002179 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002180 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2181 Failed = true;
2182 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002183
2184 if (ActiveModule) {
2185 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002186 if (!Failed && ActiveModule->IsAvailable &&
2187 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002188 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2189 Failed = true;
2190 }
2191
2192 // Check for redefinition of an inferred module.
2193 if (!Failed && ActiveModule->InferSubmodules) {
2194 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2195 if (ActiveModule->InferredSubmoduleLoc.isValid())
2196 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2197 diag::note_mmap_prev_definition);
2198 Failed = true;
2199 }
2200
2201 // Check for the 'framework' keyword, which is not permitted here.
2202 if (Framework) {
2203 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2204 Framework = false;
2205 }
2206 } else if (Explicit) {
2207 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2208 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002209 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002210
Douglas Gregor73441092011-12-05 22:27:44 +00002211 // If there were any problems with this inferred submodule, skip its body.
2212 if (Failed) {
2213 if (Tok.is(MMToken::LBrace)) {
2214 consumeToken();
2215 skipUntil(MMToken::RBrace);
2216 if (Tok.is(MMToken::RBrace))
2217 consumeToken();
2218 }
2219 HadError = true;
2220 return;
2221 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002222
2223 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002224 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002225 parseOptionalAttributes(Attrs);
2226
2227 if (ActiveModule) {
2228 // Note that we have an inferred submodule.
2229 ActiveModule->InferSubmodules = true;
2230 ActiveModule->InferredSubmoduleLoc = StarLoc;
2231 ActiveModule->InferExplicitSubmodules = Explicit;
2232 } else {
2233 // We'll be inferring framework modules for this directory.
2234 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002235 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002236 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002237 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002238 }
2239
Douglas Gregor73441092011-12-05 22:27:44 +00002240 // Parse the opening brace.
2241 if (!Tok.is(MMToken::LBrace)) {
2242 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2243 HadError = true;
2244 return;
2245 }
2246 SourceLocation LBraceLoc = consumeToken();
2247
2248 // Parse the body of the inferred submodule.
2249 bool Done = false;
2250 do {
2251 switch (Tok.Kind) {
2252 case MMToken::EndOfFile:
2253 case MMToken::RBrace:
2254 Done = true;
2255 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002256
2257 case MMToken::ExcludeKeyword: {
2258 if (ActiveModule) {
2259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002260 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002261 consumeToken();
2262 break;
2263 }
2264
2265 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002266 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002267 if (!Tok.is(MMToken::Identifier)) {
2268 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2269 break;
2270 }
2271
2272 Map.InferredDirectories[Directory].ExcludedModules
2273 .push_back(Tok.getString());
2274 consumeToken();
2275 break;
2276 }
2277
2278 case MMToken::ExportKeyword:
2279 if (!ActiveModule) {
2280 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002281 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002282 consumeToken();
2283 break;
2284 }
2285
Douglas Gregor73441092011-12-05 22:27:44 +00002286 consumeToken();
2287 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002288 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002289 else
2290 Diags.Report(Tok.getLocation(),
2291 diag::err_mmap_expected_export_wildcard);
2292 consumeToken();
2293 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002294
Douglas Gregor73441092011-12-05 22:27:44 +00002295 case MMToken::ExplicitKeyword:
2296 case MMToken::ModuleKeyword:
2297 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002298 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002299 case MMToken::UmbrellaKeyword:
2300 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002301 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002302 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002303 consumeToken();
2304 break;
2305 }
2306 } while (!Done);
2307
2308 if (Tok.is(MMToken::RBrace))
2309 consumeToken();
2310 else {
2311 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2312 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2313 HadError = true;
2314 }
2315}
2316
Douglas Gregor9194a912012-11-06 19:39:40 +00002317/// \brief Parse optional attributes.
2318///
2319/// attributes:
2320/// attribute attributes
2321/// attribute
2322///
2323/// attribute:
2324/// [ identifier ]
2325///
2326/// \param Attrs Will be filled in with the parsed attributes.
2327///
2328/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002329bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002330 bool HadError = false;
2331
2332 while (Tok.is(MMToken::LSquare)) {
2333 // Consume the '['.
2334 SourceLocation LSquareLoc = consumeToken();
2335
2336 // Check whether we have an attribute name here.
2337 if (!Tok.is(MMToken::Identifier)) {
2338 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2339 skipUntil(MMToken::RSquare);
2340 if (Tok.is(MMToken::RSquare))
2341 consumeToken();
2342 HadError = true;
2343 }
2344
2345 // Decode the attribute name.
2346 AttributeKind Attribute
2347 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002348 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002349 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002350 .Case("system", AT_system)
2351 .Default(AT_unknown);
2352 switch (Attribute) {
2353 case AT_unknown:
2354 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2355 << Tok.getString();
2356 break;
2357
2358 case AT_system:
2359 Attrs.IsSystem = true;
2360 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002361
Richard Smith77944862014-03-02 05:58:18 +00002362 case AT_extern_c:
2363 Attrs.IsExternC = true;
2364 break;
2365
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002366 case AT_exhaustive:
2367 Attrs.IsExhaustive = true;
2368 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002369 }
2370 consumeToken();
2371
2372 // Consume the ']'.
2373 if (!Tok.is(MMToken::RSquare)) {
2374 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2375 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2376 skipUntil(MMToken::RSquare);
2377 HadError = true;
2378 }
2379
2380 if (Tok.is(MMToken::RSquare))
2381 consumeToken();
2382 }
2383
2384 return HadError;
2385}
2386
Douglas Gregor718292f2011-11-11 19:10:28 +00002387/// \brief Parse a module map file.
2388///
2389/// module-map-file:
2390/// module-declaration*
2391bool ModuleMapParser::parseModuleMapFile() {
2392 do {
2393 switch (Tok.Kind) {
2394 case MMToken::EndOfFile:
2395 return HadError;
2396
Douglas Gregore7ab3662011-12-07 02:23:45 +00002397 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002398 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002399 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002400 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002401 parseModuleDecl();
2402 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002403
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002404 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002405 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002406 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002407 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002408 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002409 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002410 case MMToken::HeaderKeyword:
2411 case MMToken::Identifier:
2412 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002413 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002414 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002415 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002416 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002417 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002418 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002419 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002420 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002421 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002422 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002423 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002424 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002425 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2426 HadError = true;
2427 consumeToken();
2428 break;
2429 }
2430 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002431}
2432
Richard Smith9acb99e32014-12-10 03:09:48 +00002433bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smithae6df272015-07-14 02:06:01 +00002434 const DirectoryEntry *Dir,
2435 SourceLocation ExternModuleLoc) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002436 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2437 = ParsedModuleMap.find(File);
2438 if (Known != ParsedModuleMap.end())
2439 return Known->second;
2440
Craig Topperd2d442c2014-05-17 23:10:59 +00002441 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002442 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
Richard Smithae6df272015-07-14 02:06:01 +00002443 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002444 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002445 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002446 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002447
Douglas Gregor718292f2011-11-11 19:10:28 +00002448 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002449 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Richard Smith2a6edb32015-08-09 04:46:57 +00002450 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002451 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002452 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002453 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002454 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002455
2456 // Notify callbacks that we parsed it.
2457 for (const auto &Cb : Callbacks)
2458 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002459 return Result;
2460}