blob: 5e103a054d5c77cbf22ea54bdc8d3c8048a317a5 [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 Smith7e82e012016-02-19 22:25:36 +000092 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() {
Davide Italiano21668752016-03-08 23:58:08 +000097 for (auto &M : Modules)
98 delete M.getValue();
Douglas Gregor718292f2011-11-11 19:10:28 +000099}
100
Douglas Gregor89929282012-01-30 06:01:29 +0000101void ModuleMap::setTarget(const TargetInfo &Target) {
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
105}
106
Douglas Gregor056396a2012-10-12 21:15:50 +0000107/// \brief "Sanitize" a filename so that it can be used as an identifier.
108static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
109 SmallVectorImpl<char> &Buffer) {
110 if (Name.empty())
111 return Name;
112
Jordan Rosea7d03842013-02-08 22:30:41 +0000113 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000114 // If we don't already have something with the form of an identifier,
115 // create a buffer with the sanitized name.
116 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000117 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000118 Buffer.push_back('_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000121 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000122 Buffer.push_back(Name[I]);
123 else
124 Buffer.push_back('_');
125 }
126
127 Name = StringRef(Buffer.data(), Buffer.size());
128 }
129
130 while (llvm::StringSwitch<bool>(Name)
131#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
132#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
133#include "clang/Basic/TokenKinds.def"
134 .Default(false)) {
135 if (Name.data() != Buffer.data())
136 Buffer.append(Name.begin(), Name.end());
137 Buffer.push_back('_');
138 Name = StringRef(Buffer.data(), Buffer.size());
139 }
140
141 return Name;
142}
143
Douglas Gregor34d52742013-05-02 17:58:30 +0000144/// \brief Determine whether the given file name is the name of a builtin
145/// header, supplied by Clang to replace, override, or augment existing system
146/// headers.
147static bool isBuiltinHeader(StringRef FileName) {
148 return llvm::StringSwitch<bool>(FileName)
149 .Case("float.h", true)
150 .Case("iso646.h", true)
151 .Case("limits.h", true)
152 .Case("stdalign.h", true)
153 .Case("stdarg.h", true)
Ben Langmuir3c4b1292016-03-09 23:31:34 +0000154 .Case("stdatomic.h", true)
Douglas Gregor34d52742013-05-02 17:58:30 +0000155 .Case("stdbool.h", true)
156 .Case("stddef.h", true)
157 .Case("stdint.h", true)
158 .Case("tgmath.h", true)
159 .Case("unwind.h", true)
160 .Default(false);
161}
162
Daniel Jasper92669ee2013-12-20 12:09:36 +0000163ModuleMap::HeadersMap::iterator
164ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000165 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000166 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
167 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000168 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
169 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000170 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000171 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000172 return Known;
173}
174
Ben Langmuir44691382014-04-10 00:39:10 +0000175ModuleMap::KnownHeader
176ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
177 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000178 if (UmbrellaDirs.empty())
179 return KnownHeader();
180
Ben Langmuir44691382014-04-10 00:39:10 +0000181 const DirectoryEntry *Dir = File->getDir();
182 assert(Dir && "file in no directory");
183
184 // Note: as an egregious but useful hack we use the real path here, because
185 // frameworks moving from top-level frameworks to embedded frameworks tend
186 // to be symlinked from the top-level location to the embedded location,
187 // and we need to resolve lookups as if we had found the embedded location.
188 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
189
190 // Keep walking up the directory hierarchy, looking for a directory with
191 // an umbrella header.
192 do {
193 auto KnownDir = UmbrellaDirs.find(Dir);
194 if (KnownDir != UmbrellaDirs.end())
195 return KnownHeader(KnownDir->second, NormalHeader);
196
197 IntermediateDirs.push_back(Dir);
198
199 // Retrieve our parent path.
200 DirName = llvm::sys::path::parent_path(DirName);
201 if (DirName.empty())
202 break;
203
204 // Resolve the parent path to a directory entry.
205 Dir = SourceMgr.getFileManager().getDirectory(DirName);
206 } while (Dir);
207 return KnownHeader();
208}
209
Daniel Jasper92669ee2013-12-20 12:09:36 +0000210static bool violatesPrivateInclude(Module *RequestingModule,
211 const FileEntry *IncFileEnt,
212 ModuleMap::ModuleHeaderRole Role,
213 Module *RequestedModule) {
Richard Smith202210b2014-10-24 20:23:01 +0000214 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
215#ifndef NDEBUG
Richard Smith2708e522015-03-10 00:19:04 +0000216 if (IsPrivateRole) {
217 // Check for consistency between the module header role
218 // as obtained from the lookup and as obtained from the module.
219 // This check is not cheap, so enable it only for debugging.
220 bool IsPrivate = false;
221 SmallVectorImpl<Module::Header> *HeaderList[] = {
222 &RequestedModule->Headers[Module::HK_Private],
223 &RequestedModule->Headers[Module::HK_PrivateTextual]};
224 for (auto *Hs : HeaderList)
225 IsPrivate |=
226 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000227 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000228 }) != Hs->end();
229 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
230 }
Richard Smith202210b2014-10-24 20:23:01 +0000231#endif
Manuel Klimeke8bd0db2015-11-05 15:24:47 +0000232 return IsPrivateRole && (!RequestingModule ||
233 RequestedModule->getTopLevelModule() !=
234 RequestingModule->getTopLevelModule());
Daniel Jasper92669ee2013-12-20 12:09:36 +0000235}
236
Ben Langmuir71e1a642014-05-05 21:44:13 +0000237static Module *getTopLevelOrNull(Module *M) {
238 return M ? M->getTopLevelModule() : nullptr;
239}
240
Daniel Jasper92669ee2013-12-20 12:09:36 +0000241void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
242 SourceLocation FilenameLoc,
243 StringRef Filename,
244 const FileEntry *File) {
245 // No errors for indirect modules. This may be a bit of a problem for modules
246 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000247 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000248 return;
249
250 if (RequestingModule)
251 resolveUses(RequestingModule, /*Complain=*/false);
252
Ben Langmuir71e1a642014-05-05 21:44:13 +0000253 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000254 Module *Private = nullptr;
255 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000256
Ben Langmuir71e1a642014-05-05 21:44:13 +0000257 HeadersMap::iterator Known = findKnownHeader(File);
258 if (Known != Headers.end()) {
259 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000260 // Remember private headers for later printing of a diagnostic.
261 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
262 Header.getModule())) {
263 Private = Header.getModule();
264 continue;
265 }
266
267 // If uses need to be specified explicitly, we are only allowed to return
268 // modules that are explicitly used by the requesting module.
269 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000270 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000271 NotUsed = Header.getModule();
272 continue;
273 }
274
275 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000276 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000277 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000278
279 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000280 }
281
282 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000283 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000284 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000285 << Filename;
286 return;
287 }
288
289 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000290 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000291 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000292 << RequestingModule->getFullModuleName() << Filename;
293 return;
294 }
295
Ben Langmuir71e1a642014-05-05 21:44:13 +0000296 if (Excluded || isHeaderInUmbrellaDirs(File))
297 return;
298
299 // At this point, only non-modular includes remain.
300
301 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000302 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000303 << RequestingModule->getFullModuleName() << Filename;
304 } else if (RequestingModule) {
305 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
306 diag::warn_non_modular_include_in_framework_module :
307 diag::warn_non_modular_include_in_module;
308 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000309 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000310}
311
Richard Smithec87a502015-02-13 23:50:20 +0000312static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
313 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000314 // Prefer available modules.
315 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
316 return true;
317
Richard Smithec87a502015-02-13 23:50:20 +0000318 // Prefer a public header over a private header.
319 if ((New.getRole() & ModuleMap::PrivateHeader) !=
320 (Old.getRole() & ModuleMap::PrivateHeader))
321 return !(New.getRole() & ModuleMap::PrivateHeader);
322
323 // Prefer a non-textual header over a textual header.
324 if ((New.getRole() & ModuleMap::TextualHeader) !=
325 (Old.getRole() & ModuleMap::TextualHeader))
326 return !(New.getRole() & ModuleMap::TextualHeader);
327
328 // Don't have a reason to choose between these. Just keep the first one.
329 return false;
330}
331
Sean Silva4881e8b2015-06-10 01:37:59 +0000332ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Richard Smith306d8922014-10-22 23:50:56 +0000333 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Sean Silva8230e5e2015-06-04 23:38:11 +0000334 if (R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000335 return ModuleMap::KnownHeader();
336 return R;
337 };
338
Sean Silva4881e8b2015-06-10 01:37:59 +0000339 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000340 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000341 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000342 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000343 for (KnownHeader &H : Known->second) {
Richard Smith7e82e012016-02-19 22:25:36 +0000344 // Prefer a header from the source module over all others.
345 if (H.getModule()->getTopLevelModule() == SourceModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000346 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000347 if (!Result || isBetterKnownHeader(H, Result))
348 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000349 }
Richard Smith306d8922014-10-22 23:50:56 +0000350 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000351 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000352
Richard Smith386bb072015-08-18 23:42:23 +0000353 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
354}
355
356ModuleMap::KnownHeader
357ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
358 assert(!Headers.count(File) && "already have a module for this header");
359
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000360 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000361 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
362 if (H) {
363 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000364
Ben Langmuir44691382014-04-10 00:39:10 +0000365 // Search up the module stack until we find a module with an umbrella
366 // directory.
367 Module *UmbrellaModule = Result;
368 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
369 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000370
Ben Langmuir44691382014-04-10 00:39:10 +0000371 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000372 const FileEntry *UmbrellaModuleMap =
373 getModuleMapFileForUniquing(UmbrellaModule);
374
Ben Langmuir44691382014-04-10 00:39:10 +0000375 // Infer submodules for each of the directories we found between
376 // the directory of the umbrella header and the directory where
377 // the actual header is located.
378 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000379
Ben Langmuir44691382014-04-10 00:39:10 +0000380 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
381 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000382 SmallString<32> NameBuf;
383 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000384 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000385 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
386 Explicit).first;
387 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000388 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000389
390 // Associate the module and the directory.
391 UmbrellaDirs[SkippedDirs[I-1]] = Result;
392
393 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000394 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000395 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000396 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000397 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000398
Ben Langmuir44691382014-04-10 00:39:10 +0000399 // Infer a submodule with the same name as this header file.
400 SmallString<32> NameBuf;
401 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000402 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000403 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
404 Explicit).first;
405 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000406 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000407 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000408
Ben Langmuir44691382014-04-10 00:39:10 +0000409 // If inferred submodules export everything they import, add a
410 // wildcard to the set of exports.
411 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000412 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000413 } else {
414 // Record each of the directories we stepped through as being part of
415 // the module we found, since the umbrella header covers them all.
416 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
417 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000418 }
Ben Langmuir44691382014-04-10 00:39:10 +0000419
Richard Smith386bb072015-08-18 23:42:23 +0000420 KnownHeader Header(Result, NormalHeader);
421 Headers[File].push_back(Header);
422 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000423 }
Richard Smith306d8922014-10-22 23:50:56 +0000424
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000425 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000426}
427
Richard Smith386bb072015-08-18 23:42:23 +0000428ArrayRef<ModuleMap::KnownHeader>
429ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
430 auto It = Headers.find(File);
431 if (It == Headers.end())
432 return None;
433 return It->second;
434}
435
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000436bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000437 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000438}
439
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000440bool
441ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
442 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000443 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000444 if (Known != Headers.end()) {
445 for (SmallVectorImpl<KnownHeader>::const_iterator
446 I = Known->second.begin(),
447 E = Known->second.end();
448 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000449 if (I->isAvailable() && (!RequestingModule ||
450 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000451 return false;
452 }
453 return true;
454 }
Richard Smith50996ce2014-04-08 13:13:04 +0000455
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000456 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000457 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000458 StringRef DirName = Dir->getName();
459
Richard Smith50996ce2014-04-08 13:13:04 +0000460 auto IsUnavailable = [&](const Module *M) {
461 return !M->isAvailable() && (!RequestingModule ||
462 M->isSubModuleOf(RequestingModule));
463 };
464
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000465 // Keep walking up the directory hierarchy, looking for a directory with
466 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000467 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000468 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000469 = UmbrellaDirs.find(Dir);
470 if (KnownDir != UmbrellaDirs.end()) {
471 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000472 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000473 return true;
474
475 // Search up the module stack until we find a module with an umbrella
476 // directory.
477 Module *UmbrellaModule = Found;
478 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
479 UmbrellaModule = UmbrellaModule->Parent;
480
481 if (UmbrellaModule->InferSubmodules) {
482 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
483 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000484 SmallString<32> NameBuf;
485 StringRef Name = sanitizeFilenameAsIdentifier(
486 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
487 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000488 Found = lookupModuleQualified(Name, Found);
489 if (!Found)
490 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000491 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000492 return true;
493 }
494
495 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000496 SmallString<32> NameBuf;
497 StringRef Name = sanitizeFilenameAsIdentifier(
498 llvm::sys::path::stem(Header->getName()),
499 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000500 Found = lookupModuleQualified(Name, Found);
501 if (!Found)
502 return false;
503 }
504
Richard Smith50996ce2014-04-08 13:13:04 +0000505 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000506 }
507
508 SkippedDirs.push_back(Dir);
509
510 // Retrieve our parent path.
511 DirName = llvm::sys::path::parent_path(DirName);
512 if (DirName.empty())
513 break;
514
515 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000516 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000517 } while (Dir);
518
519 return false;
520}
521
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000522Module *ModuleMap::findModule(StringRef Name) const {
523 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000524 if (Known != Modules.end())
525 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000526
527 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000528}
529
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000530Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
531 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000532 for(; Context; Context = Context->Parent) {
533 if (Module *Sub = lookupModuleQualified(Name, Context))
534 return Sub;
535 }
536
537 return findModule(Name);
538}
539
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000540Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000541 if (!Context)
542 return findModule(Name);
543
Douglas Gregoreb90e832012-01-04 23:32:19 +0000544 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000545}
546
Douglas Gregorde3ef502011-11-30 23:21:26 +0000547std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000548ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000549 bool IsExplicit) {
550 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000551 if (Module *Sub = lookupModuleQualified(Name, Parent))
552 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000553
554 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000555 Module *Result = new Module(Name, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000556 IsFramework, IsExplicit, NumCreatedModules++);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000557 if (!Parent) {
Richard Smith7e82e012016-02-19 22:25:36 +0000558 if (LangOpts.CurrentModule == Name)
559 SourceModule = Result;
Douglas Gregor69021972011-11-30 17:33:56 +0000560 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000561 }
Douglas Gregor69021972011-11-30 17:33:56 +0000562 return std::make_pair(Result, true);
563}
564
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000565/// \brief For a framework module, infer the framework against which we
566/// should link.
567static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
568 FileManager &FileMgr) {
569 assert(Mod->IsFramework && "Can only infer linking for framework modules");
570 assert(!Mod->isSubFramework() &&
571 "Can only infer linking for top-level frameworks");
572
573 SmallString<128> LibName;
574 LibName += FrameworkDir->getName();
575 llvm::sys::path::append(LibName, Mod->Name);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000576
577 // The library name of a framework has more than one possible extension since
578 // the introduction of the text-based dynamic library format. We need to check
579 // for both before we give up.
580 static const char *frameworkExtensions[] = {"", ".tbd"};
581 for (const auto *extension : frameworkExtensions) {
582 llvm::sys::path::replace_extension(LibName, extension);
583 if (FileMgr.getFile(LibName)) {
584 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
585 /*IsFramework=*/true));
586 return;
587 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000588 }
589}
590
Ben Langmuira5254002015-07-02 13:19:48 +0000591Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
592 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000593 Attributes Attrs;
594 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000595 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000596}
597
Ben Langmuira5254002015-07-02 13:19:48 +0000598Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000599 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000600 // Note: as an egregious but useful hack we use the real path here, because
601 // we might be looking at an embedded framework that symlinks out to a
602 // top-level framework, and we need to infer as if we were naming the
603 // top-level framework.
604 StringRef FrameworkDirName =
605 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
606
607 // In case this is a case-insensitive filesystem, use the canonical
608 // directory name as the ModuleName, since modules are case-sensitive.
609 // FIXME: we should be able to give a fix-it hint for the correct spelling.
610 SmallString<32> ModuleNameStorage;
611 StringRef ModuleName = sanitizeFilenameAsIdentifier(
612 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000613
Douglas Gregor56c64012011-11-17 01:41:17 +0000614 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000615 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
616 return Mod;
617
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000618 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000619
620 // If the framework has a parent path from which we're allowed to infer
621 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000622 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000623 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000624 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000625 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000626 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000627 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000628 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000629 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
630 // Check whether we have already looked into the parent directory
631 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000632 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000633 inferred = InferredDirectories.find(ParentDir);
634 if (inferred == InferredDirectories.end()) {
635 // We haven't looked here before. Load a module map, if there is
636 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000637 bool IsFrameworkDir = Parent.endswith(".framework");
638 if (const FileEntry *ModMapFile =
639 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000640 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000641 inferred = InferredDirectories.find(ParentDir);
642 }
643
644 if (inferred == InferredDirectories.end())
645 inferred = InferredDirectories.insert(
646 std::make_pair(ParentDir, InferredDirectory())).first;
647 }
648
649 if (inferred->second.InferModules) {
650 // We're allowed to infer for this directory, but make sure it's okay
651 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000652 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000653 canInfer = std::find(inferred->second.ExcludedModules.begin(),
654 inferred->second.ExcludedModules.end(),
655 Name) == inferred->second.ExcludedModules.end();
656
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000657 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
658 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
659 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000660 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000661 }
662 }
663 }
664
665 // If we're not allowed to infer a framework module, don't.
666 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000667 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000668 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000669 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000670
671
Douglas Gregor56c64012011-11-17 01:41:17 +0000672 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000673 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000674 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000675 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000676
677 // FIXME: If there's no umbrella header, we could probably scan the
678 // framework to load *everything*. But, it's not clear that this is a good
679 // idea.
680 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000681 return nullptr;
682
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000683 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000684 /*IsFramework=*/true, /*IsExplicit=*/false,
685 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000686 InferredModuleAllowedBy[Result] = ModuleMapFile;
687 Result->IsInferred = true;
Richard Smith7e82e012016-02-19 22:25:36 +0000688 if (!Parent) {
689 if (LangOpts.CurrentModule == ModuleName)
690 SourceModule = Result;
691 Modules[ModuleName] = Result;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000692 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000693
694 Result->IsSystem |= Attrs.IsSystem;
695 Result->IsExternC |= Attrs.IsExternC;
696 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Richard Smith2b63d152015-05-16 02:28:53 +0000697 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000698
Douglas Gregor322f6332011-12-08 18:00:48 +0000699 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000700 //
701 // The "Headers/" component of the name is implied because this is
702 // a framework module.
703 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000704
705 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000706 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
707
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000708 // module * { export * }
709 Result->InferSubmodules = true;
710 Result->InferExportWildcard = true;
711
Douglas Gregore89dbc12011-12-06 19:39:29 +0000712 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000713 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000714 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000715 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000716 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000717 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000718 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000719 Dir != DirEnd && !EC; Dir.increment(EC)) {
720 if (!StringRef(Dir->path()).endswith(".framework"))
721 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000722
Douglas Gregore89dbc12011-12-06 19:39:29 +0000723 if (const DirectoryEntry *SubframeworkDir
724 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000725 // Note: as an egregious but useful hack, we use the real path here and
726 // check whether it is actually a subdirectory of the parent directory.
727 // This will not be the case if the 'subframework' is actually a symlink
728 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000729 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
730 bool FoundParent = false;
731 do {
732 // Get the parent directory name.
733 SubframeworkDirName
734 = llvm::sys::path::parent_path(SubframeworkDirName);
735 if (SubframeworkDirName.empty())
736 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000737
Douglas Gregore00c8b22013-01-26 00:55:12 +0000738 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
739 FoundParent = true;
740 break;
741 }
742 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000743
Douglas Gregore00c8b22013-01-26 00:55:12 +0000744 if (!FoundParent)
745 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000746
Douglas Gregore89dbc12011-12-06 19:39:29 +0000747 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000748 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000749 }
750 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000751
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000752 // If the module is a top-level framework, automatically link against the
753 // framework.
754 if (!Result->isSubFramework()) {
755 inferFrameworkLink(Result, FrameworkDir, FileMgr);
756 }
757
Douglas Gregor56c64012011-11-17 01:41:17 +0000758 return Result;
759}
760
Richard Smith2b63d152015-05-16 02:28:53 +0000761void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
762 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000763 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000764 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000765 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000766 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000767}
768
Richard Smith2b63d152015-05-16 02:28:53 +0000769void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
770 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000771 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000772 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000773 UmbrellaDirs[UmbrellaDir] = Mod;
774}
775
Richard Smith3c1a41a2014-12-02 00:08:08 +0000776static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000777 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000778 default: llvm_unreachable("unknown header role");
779 case ModuleMap::NormalHeader:
780 return Module::HK_Normal;
781 case ModuleMap::PrivateHeader:
782 return Module::HK_Private;
783 case ModuleMap::TextualHeader:
784 return Module::HK_Textual;
785 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
786 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000787 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000788}
789
Richard Smith3c1a41a2014-12-02 00:08:08 +0000790void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000791 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000792 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000793
Richard Smith386bb072015-08-18 23:42:23 +0000794 // Only add each header to the headers list once.
795 // FIXME: Should we diagnose if a header is listed twice in the
796 // same module definition?
797 auto &HeaderList = Headers[Header.Entry];
798 for (auto H : HeaderList)
799 if (H == KH)
800 return;
801
802 HeaderList.push_back(KH);
Richard Smith3c1a41a2014-12-02 00:08:08 +0000803 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
Richard Smith386bb072015-08-18 23:42:23 +0000804
Richard Smith7e82e012016-02-19 22:25:36 +0000805 bool isCompilingModuleHeader =
806 LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000807 if (!Imported || isCompilingModuleHeader) {
808 // When we import HeaderFileInfo, the external source is expected to
809 // set the isModuleHeader flag itself.
810 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
811 isCompilingModuleHeader);
812 }
Richard Smith3c1a41a2014-12-02 00:08:08 +0000813}
814
815void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000816 // Add this as a known header so we won't implicitly add it to any
817 // umbrella directory module.
818 // FIXME: Should we only exclude it from umbrella modules within the
819 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000820 (void) Headers[Header.Entry];
821
822 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000823}
824
Douglas Gregor514b6362011-11-29 19:06:37 +0000825const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000826ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000827 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000828 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000829
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000830 return SourceMgr.getFileEntryForID(
831 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000832}
833
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000834const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000835 if (M->IsInferred) {
836 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
837 return InferredModuleAllowedBy.find(M)->second;
838 }
839 return getContainingModuleMapFile(M);
840}
841
842void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
843 assert(M->IsInferred && "module not inferred");
844 InferredModuleAllowedBy[M] = ModMap;
845}
846
Yaron Kerencdae9412016-01-29 19:38:18 +0000847LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +0000848 llvm::errs() << "Modules:";
849 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
850 MEnd = Modules.end();
851 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000852 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000853
854 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000855 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000856 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000857 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
858 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
859 E = H->second.end();
860 I != E; ++I) {
861 if (I != H->second.begin())
862 llvm::errs() << ",";
863 llvm::errs() << I->getModule()->getFullModuleName();
864 }
865 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000866 }
867}
868
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000869bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000870 auto Unresolved = std::move(Mod->UnresolvedExports);
871 Mod->UnresolvedExports.clear();
872 for (auto &UE : Unresolved) {
873 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000874 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000875 Mod->Exports.push_back(Export);
876 else
Richard Smith42413142015-05-15 20:05:43 +0000877 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000878 }
Richard Smith42413142015-05-15 20:05:43 +0000879 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000880}
881
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000882bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000883 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
884 Mod->UnresolvedDirectUses.clear();
885 for (auto &UDU : Unresolved) {
886 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000887 if (DirectUse)
888 Mod->DirectUses.push_back(DirectUse);
889 else
Richard Smith42413142015-05-15 20:05:43 +0000890 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000891 }
Richard Smith42413142015-05-15 20:05:43 +0000892 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000893}
894
Douglas Gregorfb912652013-03-20 21:10:35 +0000895bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000896 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000897 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000898 for (auto &UC : Unresolved) {
899 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
900 Module::Conflict Conflict;
901 Conflict.Other = OtherMod;
902 Conflict.Message = UC.Message;
903 Mod->Conflicts.push_back(Conflict);
904 } else
905 Mod->UnresolvedConflicts.push_back(UC);
906 }
907 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000908}
909
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000910Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
911 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000912 return nullptr;
913
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000914 // Use the expansion location to determine which module we're in.
915 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
916 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000917 return nullptr;
918
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000919 const SourceManager &SrcMgr = Loc.getManager();
920 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000921
Douglas Gregor224d8a72012-01-06 17:19:32 +0000922 while (const FileEntry *ExpansionFile
923 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
924 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000925 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000926 return Mod;
927
928 // No module owns this header, so look up the inclusion chain to see if
929 // any included header has an associated module.
930 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
931 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000932 return nullptr;
933
Douglas Gregor224d8a72012-01-06 17:19:32 +0000934 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
935 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000936
937 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000938}
939
Douglas Gregor718292f2011-11-11 19:10:28 +0000940//----------------------------------------------------------------------------//
941// Module map file parser
942//----------------------------------------------------------------------------//
943
944namespace clang {
945 /// \brief A token in a module map file.
946 struct MMToken {
947 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000948 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000949 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000950 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000951 EndOfFile,
952 HeaderKeyword,
953 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000954 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000955 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000956 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000957 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000958 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000959 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000960 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000961 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000962 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000963 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000965 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000966 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000967 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000968 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000969 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000970 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000971 RBrace,
972 LSquare,
973 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000974 } Kind;
975
976 unsigned Location;
977 unsigned StringLength;
978 const char *StringData;
979
980 void clear() {
981 Kind = EndOfFile;
982 Location = 0;
983 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000984 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000985 }
986
987 bool is(TokenKind K) const { return Kind == K; }
988
989 SourceLocation getLocation() const {
990 return SourceLocation::getFromRawEncoding(Location);
991 }
992
993 StringRef getString() const {
994 return StringRef(StringData, StringLength);
995 }
996 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000997
Douglas Gregor718292f2011-11-11 19:10:28 +0000998 class ModuleMapParser {
999 Lexer &L;
1000 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001001
1002 /// \brief Default target information, used only for string literal
1003 /// parsing.
1004 const TargetInfo *Target;
1005
Douglas Gregor718292f2011-11-11 19:10:28 +00001006 DiagnosticsEngine &Diags;
1007 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001008
1009 /// \brief The current module map file.
1010 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001011
Richard Smith9acb99e32014-12-10 03:09:48 +00001012 /// \brief The directory that file names in this module map file should
1013 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001014 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001015
1016 /// \brief The directory containing Clang-supplied headers.
1017 const DirectoryEntry *BuiltinIncludeDir;
1018
Douglas Gregor963c5532013-06-21 16:28:10 +00001019 /// \brief Whether this module map is in a system header directory.
1020 bool IsSystem;
1021
Douglas Gregor718292f2011-11-11 19:10:28 +00001022 /// \brief Whether an error occurred.
1023 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001024
Douglas Gregor718292f2011-11-11 19:10:28 +00001025 /// \brief Stores string data for the various string literals referenced
1026 /// during parsing.
1027 llvm::BumpPtrAllocator StringData;
1028
1029 /// \brief The current token.
1030 MMToken Tok;
1031
1032 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001033 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001034
1035 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1036 /// contents as 'textual'.
1037 ///
1038 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1039 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1040 /// non-modular headers. For backwards compatibility, we continue to
1041 /// support this idiom for just these modules, and map the headers to
1042 /// 'textual' to match the original intent.
1043 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1044
Douglas Gregor718292f2011-11-11 19:10:28 +00001045 /// \brief Consume the current token and return its location.
1046 SourceLocation consumeToken();
1047
1048 /// \brief Skip tokens until we reach the a token with the given kind
1049 /// (or the end of the file).
1050 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001051
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001052 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001053 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001054 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001055 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001056 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001057 void parseHeaderDecl(clang::MMToken::TokenKind,
1058 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001059 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001060 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001061 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001062 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001063 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001064 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001065 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001066
1067 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001068 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001069
Douglas Gregor718292f2011-11-11 19:10:28 +00001070 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001071 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001072 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001073 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001074 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001075 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001076 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001077 const DirectoryEntry *BuiltinIncludeDir,
1078 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001079 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001080 ModuleMapFile(ModuleMapFile), Directory(Directory),
1081 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001082 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001084 Tok.clear();
1085 consumeToken();
1086 }
1087
1088 bool parseModuleMapFile();
1089 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001090}
Douglas Gregor718292f2011-11-11 19:10:28 +00001091
1092SourceLocation ModuleMapParser::consumeToken() {
1093retry:
1094 SourceLocation Result = Tok.getLocation();
1095 Tok.clear();
1096
1097 Token LToken;
1098 L.LexFromRawLexer(LToken);
1099 Tok.Location = LToken.getLocation().getRawEncoding();
1100 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001101 case tok::raw_identifier: {
1102 StringRef RI = LToken.getRawIdentifier();
1103 Tok.StringData = RI.data();
1104 Tok.StringLength = RI.size();
1105 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001106 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001107 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001108 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001109 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001110 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001111 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001112 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001113 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001114 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001115 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001116 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001117 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001118 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001119 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001120 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001121 .Default(MMToken::Identifier);
1122 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001123 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001124
1125 case tok::comma:
1126 Tok.Kind = MMToken::Comma;
1127 break;
1128
Douglas Gregor718292f2011-11-11 19:10:28 +00001129 case tok::eof:
1130 Tok.Kind = MMToken::EndOfFile;
1131 break;
1132
1133 case tok::l_brace:
1134 Tok.Kind = MMToken::LBrace;
1135 break;
1136
Douglas Gregora686e1b2012-01-27 19:52:33 +00001137 case tok::l_square:
1138 Tok.Kind = MMToken::LSquare;
1139 break;
1140
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001141 case tok::period:
1142 Tok.Kind = MMToken::Period;
1143 break;
1144
Douglas Gregor718292f2011-11-11 19:10:28 +00001145 case tok::r_brace:
1146 Tok.Kind = MMToken::RBrace;
1147 break;
1148
Douglas Gregora686e1b2012-01-27 19:52:33 +00001149 case tok::r_square:
1150 Tok.Kind = MMToken::RSquare;
1151 break;
1152
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001153 case tok::star:
1154 Tok.Kind = MMToken::Star;
1155 break;
1156
Richard Smitha3feee22013-10-28 22:18:19 +00001157 case tok::exclaim:
1158 Tok.Kind = MMToken::Exclaim;
1159 break;
1160
Douglas Gregor718292f2011-11-11 19:10:28 +00001161 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001162 if (LToken.hasUDSuffix()) {
1163 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1164 HadError = true;
1165 goto retry;
1166 }
1167
Douglas Gregor718292f2011-11-11 19:10:28 +00001168 // Parse the string literal.
1169 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001170 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001171 if (StringLiteral.hadError)
1172 goto retry;
1173
1174 // Copy the string literal into our string data allocator.
1175 unsigned Length = StringLiteral.GetStringLength();
1176 char *Saved = StringData.Allocate<char>(Length + 1);
1177 memcpy(Saved, StringLiteral.GetString().data(), Length);
1178 Saved[Length] = 0;
1179
1180 // Form the token.
1181 Tok.Kind = MMToken::StringLiteral;
1182 Tok.StringData = Saved;
1183 Tok.StringLength = Length;
1184 break;
1185 }
1186
1187 case tok::comment:
1188 goto retry;
1189
1190 default:
1191 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1192 HadError = true;
1193 goto retry;
1194 }
1195
1196 return Result;
1197}
1198
1199void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1200 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001201 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001202 do {
1203 switch (Tok.Kind) {
1204 case MMToken::EndOfFile:
1205 return;
1206
1207 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001208 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001209 return;
1210
1211 ++braceDepth;
1212 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001213
1214 case MMToken::LSquare:
1215 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1216 return;
1217
1218 ++squareDepth;
1219 break;
1220
Douglas Gregor718292f2011-11-11 19:10:28 +00001221 case MMToken::RBrace:
1222 if (braceDepth > 0)
1223 --braceDepth;
1224 else if (Tok.is(K))
1225 return;
1226 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001227
1228 case MMToken::RSquare:
1229 if (squareDepth > 0)
1230 --squareDepth;
1231 else if (Tok.is(K))
1232 return;
1233 break;
1234
Douglas Gregor718292f2011-11-11 19:10:28 +00001235 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001236 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 return;
1238 break;
1239 }
1240
1241 consumeToken();
1242 } while (true);
1243}
1244
Douglas Gregore7ab3662011-12-07 02:23:45 +00001245/// \brief Parse a module-id.
1246///
1247/// module-id:
1248/// identifier
1249/// identifier '.' module-id
1250///
1251/// \returns true if an error occurred, false otherwise.
1252bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1253 Id.clear();
1254 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001255 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001256 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1257 consumeToken();
1258 } else {
1259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1260 return true;
1261 }
1262
1263 if (!Tok.is(MMToken::Period))
1264 break;
1265
1266 consumeToken();
1267 } while (true);
1268
1269 return false;
1270}
1271
Douglas Gregora686e1b2012-01-27 19:52:33 +00001272namespace {
1273 /// \brief Enumerates the known attributes.
1274 enum AttributeKind {
1275 /// \brief An unknown attribute.
1276 AT_unknown,
1277 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001278 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001279 /// \brief The 'extern_c' attribute.
1280 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001281 /// \brief The 'exhaustive' attribute.
1282 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001283 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001284}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001285
Douglas Gregor718292f2011-11-11 19:10:28 +00001286/// \brief Parse a module declaration.
1287///
1288/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001289/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001290/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1291/// { module-member* }
1292///
Douglas Gregor718292f2011-11-11 19:10:28 +00001293/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001294/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001295/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001296/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001297/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001298/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001299///
1300/// submodule-declaration:
1301/// module-declaration
1302/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001303void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001304 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001305 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1306 if (Tok.is(MMToken::ExternKeyword)) {
1307 parseExternModuleDecl();
1308 return;
1309 }
1310
Douglas Gregorf2161a72011-12-06 17:16:41 +00001311 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001312 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001313 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001314 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001315
Douglas Gregorf2161a72011-12-06 17:16:41 +00001316 // Parse 'explicit' keyword, if present.
1317 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001318 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001319 Explicit = true;
1320 }
1321
1322 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001323 if (Tok.is(MMToken::FrameworkKeyword)) {
1324 consumeToken();
1325 Framework = true;
1326 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001327
1328 // Parse 'module' keyword.
1329 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001330 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001331 consumeToken();
1332 HadError = true;
1333 return;
1334 }
1335 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001336
1337 // If we have a wildcard for the module name, this is an inferred submodule.
1338 // Parse it.
1339 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001340 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001341
1342 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001343 ModuleId Id;
1344 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001345 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001346 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001347 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001348
Douglas Gregore7ab3662011-12-07 02:23:45 +00001349 if (ActiveModule) {
1350 if (Id.size() > 1) {
1351 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1352 << SourceRange(Id.front().second, Id.back().second);
1353
1354 HadError = true;
1355 return;
1356 }
1357 } else if (Id.size() == 1 && Explicit) {
1358 // Top-level modules can't be explicit.
1359 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1360 Explicit = false;
1361 ExplicitLoc = SourceLocation();
1362 HadError = true;
1363 }
1364
1365 Module *PreviousActiveModule = ActiveModule;
1366 if (Id.size() > 1) {
1367 // This module map defines a submodule. Go find the module of which it
1368 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001369 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001370 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001371 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1372 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001373 if (I == 0)
1374 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001375 ActiveModule = Next;
1376 continue;
1377 }
1378
1379 if (ActiveModule) {
1380 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001381 << Id[I].first
1382 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001383 } else {
1384 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1385 }
1386 HadError = true;
1387 return;
1388 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001389
1390 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1391 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1392 "submodule defined in same file as 'module *' that allowed its "
1393 "top-level module");
1394 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1395 }
1396 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001397
1398 StringRef ModuleName = Id.back().first;
1399 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001400
Douglas Gregora686e1b2012-01-27 19:52:33 +00001401 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001402 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00001403 if (parseOptionalAttributes(Attrs))
1404 return;
1405
Douglas Gregora686e1b2012-01-27 19:52:33 +00001406
Douglas Gregor718292f2011-11-11 19:10:28 +00001407 // Parse the opening brace.
1408 if (!Tok.is(MMToken::LBrace)) {
1409 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1410 << ModuleName;
1411 HadError = true;
1412 return;
1413 }
1414 SourceLocation LBraceLoc = consumeToken();
1415
1416 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001417 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001418 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1419 // Skip the module definition.
1420 skipUntil(MMToken::RBrace);
1421 if (Tok.is(MMToken::RBrace))
1422 consumeToken();
1423 else {
1424 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1425 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1426 HadError = true;
1427 }
1428 return;
1429 }
1430
Douglas Gregor718292f2011-11-11 19:10:28 +00001431 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1432 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001433 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001434
1435 // Skip the module definition.
1436 skipUntil(MMToken::RBrace);
1437 if (Tok.is(MMToken::RBrace))
1438 consumeToken();
1439
1440 HadError = true;
1441 return;
1442 }
1443
1444 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001445 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1446 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001447 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001448 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001449 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001450 if (Attrs.IsExternC)
1451 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001452 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001453
Douglas Gregor718292f2011-11-11 19:10:28 +00001454 bool Done = false;
1455 do {
1456 switch (Tok.Kind) {
1457 case MMToken::EndOfFile:
1458 case MMToken::RBrace:
1459 Done = true;
1460 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001461
1462 case MMToken::ConfigMacros:
1463 parseConfigMacros();
1464 break;
1465
Douglas Gregorfb912652013-03-20 21:10:35 +00001466 case MMToken::Conflict:
1467 parseConflict();
1468 break;
1469
Douglas Gregor718292f2011-11-11 19:10:28 +00001470 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001471 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001472 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001473 case MMToken::ModuleKeyword:
1474 parseModuleDecl();
1475 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001476
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001477 case MMToken::ExportKeyword:
1478 parseExportDecl();
1479 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001480
1481 case MMToken::UseKeyword:
1482 parseUseDecl();
1483 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001484
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001485 case MMToken::RequiresKeyword:
1486 parseRequiresDecl();
1487 break;
1488
Richard Smith202210b2014-10-24 20:23:01 +00001489 case MMToken::TextualKeyword:
1490 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001491 break;
Richard Smith306d8922014-10-22 23:50:56 +00001492
Douglas Gregor524e33e2011-12-08 19:11:24 +00001493 case MMToken::UmbrellaKeyword: {
1494 SourceLocation UmbrellaLoc = consumeToken();
1495 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001496 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001497 else
1498 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001499 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001500 }
Richard Smith202210b2014-10-24 20:23:01 +00001501
1502 case MMToken::ExcludeKeyword:
1503 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001504 break;
Richard Smith202210b2014-10-24 20:23:01 +00001505
1506 case MMToken::PrivateKeyword:
1507 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001508 break;
Richard Smith202210b2014-10-24 20:23:01 +00001509
Douglas Gregor322f6332011-12-08 18:00:48 +00001510 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001511 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001512 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001513
1514 case MMToken::LinkKeyword:
1515 parseLinkDecl();
1516 break;
1517
Douglas Gregor718292f2011-11-11 19:10:28 +00001518 default:
1519 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1520 consumeToken();
1521 break;
1522 }
1523 } while (!Done);
1524
1525 if (Tok.is(MMToken::RBrace))
1526 consumeToken();
1527 else {
1528 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1529 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1530 HadError = true;
1531 }
1532
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001533 // If the active module is a top-level framework, and there are no link
1534 // libraries, automatically link against the framework.
1535 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1536 ActiveModule->LinkLibraries.empty()) {
1537 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1538 }
1539
Ben Langmuirec8c9752014-04-18 22:07:31 +00001540 // If the module meets all requirements but is still unavailable, mark the
1541 // whole tree as unavailable to prevent it from building.
1542 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1543 ActiveModule->Parent) {
1544 ActiveModule->getTopLevelModule()->markUnavailable();
1545 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1546 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1547 }
1548
Douglas Gregore7ab3662011-12-07 02:23:45 +00001549 // We're done parsing this module. Pop back to the previous module.
1550 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001551}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001552
Daniel Jasper97292842013-09-11 07:20:44 +00001553/// \brief Parse an extern module declaration.
1554///
1555/// extern module-declaration:
1556/// 'extern' 'module' module-id string-literal
1557void ModuleMapParser::parseExternModuleDecl() {
1558 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001559 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001560
1561 // Parse 'module' keyword.
1562 if (!Tok.is(MMToken::ModuleKeyword)) {
1563 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1564 consumeToken();
1565 HadError = true;
1566 return;
1567 }
1568 consumeToken(); // 'module' keyword
1569
1570 // Parse the module name.
1571 ModuleId Id;
1572 if (parseModuleId(Id)) {
1573 HadError = true;
1574 return;
1575 }
1576
1577 // Parse the referenced module map file name.
1578 if (!Tok.is(MMToken::StringLiteral)) {
1579 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1580 HadError = true;
1581 return;
1582 }
1583 std::string FileName = Tok.getString();
1584 consumeToken(); // filename
1585
1586 StringRef FileNameRef = FileName;
1587 SmallString<128> ModuleMapFileName;
1588 if (llvm::sys::path::is_relative(FileNameRef)) {
1589 ModuleMapFileName += Directory->getName();
1590 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001591 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001592 }
1593 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001594 Map.parseModuleMapFile(
1595 File, /*IsSystem=*/false,
1596 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1597 ? Directory
Richard Smithae6df272015-07-14 02:06:01 +00001598 : File->getDir(), ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001599}
1600
Ben Langmuir7ff29142015-08-13 17:13:33 +00001601/// Whether to add the requirement \p Feature to the module \p M.
1602///
1603/// This preserves backwards compatibility for two hacks in the Darwin system
1604/// module map files:
1605///
1606/// 1. The use of 'requires excluded' to make headers non-modular, which
1607/// should really be mapped to 'textual' now that we have this feature. We
1608/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1609/// true. Later, this bit will be used to map all the headers inside this
1610/// module to 'textual'.
1611///
1612/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1613///
1614/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1615/// was never correct and causes issues now that we check it, so drop it.
1616static bool shouldAddRequirement(Module *M, StringRef Feature,
1617 bool &IsRequiresExcludedHack) {
1618 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1619 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1620 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1621
1622 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1623 M->fullModuleNameIs(TclPrivate))) {
1624 IsRequiresExcludedHack = true;
1625 return false;
1626 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1627 return false;
1628 }
1629
1630 return true;
1631}
1632
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001633/// \brief Parse a requires declaration.
1634///
1635/// requires-declaration:
1636/// 'requires' feature-list
1637///
1638/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001639/// feature ',' feature-list
1640/// feature
1641///
1642/// feature:
1643/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001644void ModuleMapParser::parseRequiresDecl() {
1645 assert(Tok.is(MMToken::RequiresKeyword));
1646
1647 // Parse 'requires' keyword.
1648 consumeToken();
1649
1650 // Parse the feature-list.
1651 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001652 bool RequiredState = true;
1653 if (Tok.is(MMToken::Exclaim)) {
1654 RequiredState = false;
1655 consumeToken();
1656 }
1657
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001658 if (!Tok.is(MMToken::Identifier)) {
1659 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1660 HadError = true;
1661 return;
1662 }
1663
1664 // Consume the feature name.
1665 std::string Feature = Tok.getString();
1666 consumeToken();
1667
Ben Langmuir7ff29142015-08-13 17:13:33 +00001668 bool IsRequiresExcludedHack = false;
1669 bool ShouldAddRequirement =
1670 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1671
1672 if (IsRequiresExcludedHack)
1673 UsesRequiresExcludedHack.insert(ActiveModule);
1674
1675 if (ShouldAddRequirement) {
1676 // Add this feature.
1677 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1678 *Map.Target);
1679 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001680
1681 if (!Tok.is(MMToken::Comma))
1682 break;
1683
1684 // Consume the comma.
1685 consumeToken();
1686 } while (true);
1687}
1688
Douglas Gregorf2161a72011-12-06 17:16:41 +00001689/// \brief Append to \p Paths the set of paths needed to get to the
1690/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001691static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001692 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001693 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001694 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001695 for (; Mod; Mod = Mod->Parent) {
1696 if (Mod->IsFramework)
1697 Paths.push_back(Mod->Name);
1698 }
1699
1700 if (Paths.empty())
1701 return;
1702
1703 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001704 for (unsigned I = Paths.size() - 1; I != 0; --I)
1705 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001706}
1707
Douglas Gregor718292f2011-11-11 19:10:28 +00001708/// \brief Parse a header declaration.
1709///
1710/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001711/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001712/// 'private' 'textual'[opt] 'header' string-literal
1713/// 'exclude' 'header' string-literal
1714/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001715///
1716/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001717void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1718 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001719 // We've already consumed the first token.
1720 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1721 if (LeadingToken == MMToken::PrivateKeyword) {
1722 Role = ModuleMap::PrivateHeader;
1723 // 'private' may optionally be followed by 'textual'.
1724 if (Tok.is(MMToken::TextualKeyword)) {
1725 LeadingToken = Tok.Kind;
1726 consumeToken();
1727 }
1728 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001729
Richard Smith202210b2014-10-24 20:23:01 +00001730 if (LeadingToken == MMToken::TextualKeyword)
1731 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1732
Ben Langmuir7ff29142015-08-13 17:13:33 +00001733 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1734 // Mark this header 'textual' (see doc comment for
1735 // Module::UsesRequiresExcludedHack).
1736 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1737 }
1738
Richard Smith202210b2014-10-24 20:23:01 +00001739 if (LeadingToken != MMToken::HeaderKeyword) {
1740 if (!Tok.is(MMToken::HeaderKeyword)) {
1741 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1742 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1743 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1744 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1745 return;
1746 }
1747 consumeToken();
1748 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001749
Douglas Gregor718292f2011-11-11 19:10:28 +00001750 // Parse the header name.
1751 if (!Tok.is(MMToken::StringLiteral)) {
1752 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1753 << "header";
1754 HadError = true;
1755 return;
1756 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001757 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001758 Header.FileName = Tok.getString();
1759 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001760
Douglas Gregor524e33e2011-12-08 19:11:24 +00001761 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001762 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001763 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001764 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001765 HadError = true;
1766 return;
1767 }
1768
Douglas Gregor5257fc62011-11-11 21:55:48 +00001769 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001770 const FileEntry *File = nullptr;
1771 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001772 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001773 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001774 RelativePathName = Header.FileName;
1775 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001776 } else {
1777 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001778 SmallString<128> FullPathName(Directory->getName());
1779 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001780
Douglas Gregorf2161a72011-12-06 17:16:41 +00001781 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001782 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001783
1784 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001785 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001786 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001787 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001788
1789 if (!File) {
1790 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001791 // FIXME: Should we retain the subframework paths here?
1792 RelativePathName.clear();
1793 FullPathName.resize(FullPathLength);
1794 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1795 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001796 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001797 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001798 }
1799 } else {
1800 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001801 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001802 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001803 File = SourceMgr.getFileManager().getFile(FullPathName);
1804
Douglas Gregor3ec66632012-02-02 18:42:48 +00001805 // If this is a system module with a top-level header, this header
1806 // may have a counterpart (or replacement) in the set of headers
1807 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001808 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1809 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001810 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001811 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001812 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001813 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001814
Douglas Gregor3ec66632012-02-02 18:42:48 +00001815 // If Clang supplies this header but the underlying system does not,
1816 // just silently swap in our builtin version. Otherwise, we'll end
1817 // up adding both (later).
Richard Smith42413142015-05-15 20:05:43 +00001818 //
1819 // For local visibility, entirely replace the system file with our
1820 // one and textually include the system one. We need to pass macros
1821 // from our header to the system one if we #include_next it.
1822 //
1823 // FIXME: Can we do this in all cases?
1824 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001825 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001826 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001827 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001828 }
1829 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001830 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001831 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001832
Douglas Gregor5257fc62011-11-11 21:55:48 +00001833 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1834 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001835 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001836 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001837 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001838 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001839 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001840 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001841 HadError = true;
1842 } else {
1843 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001844 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001845 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001846 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001847 Module::Header H = {RelativePathName.str(), File};
1848 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001849 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001850 // If there is a builtin counterpart to this file, add it now, before
1851 // the "real" header, so we build the built-in one first when building
1852 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001853 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001854 // FIXME: Taking the name from the FileEntry is unstable and can give
1855 // different results depending on how we've previously named that file
1856 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001857 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1858 Map.addHeader(ActiveModule, H, Role);
1859 }
Richard Smith25d50752014-10-20 00:15:49 +00001860
Richard Smith202210b2014-10-24 20:23:01 +00001861 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001862 Module::Header H = { RelativePathName.str(), File };
1863 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001864 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001865 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001866 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001867
1868 // If we find a module that has a missing header, we mark this module as
1869 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001870 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001871 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001872 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001873 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001874}
1875
Ben Langmuir41f81992015-08-13 17:30:07 +00001876static int compareModuleHeaders(const Module::Header *A,
1877 const Module::Header *B) {
1878 return A->NameAsWritten.compare(B->NameAsWritten);
1879}
1880
Douglas Gregor524e33e2011-12-08 19:11:24 +00001881/// \brief Parse an umbrella directory declaration.
1882///
1883/// umbrella-dir-declaration:
1884/// umbrella string-literal
1885void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1886 // Parse the directory name.
1887 if (!Tok.is(MMToken::StringLiteral)) {
1888 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1889 << "umbrella";
1890 HadError = true;
1891 return;
1892 }
1893
1894 std::string DirName = Tok.getString();
1895 SourceLocation DirNameLoc = consumeToken();
1896
1897 // Check whether we already have an umbrella.
1898 if (ActiveModule->Umbrella) {
1899 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1900 << ActiveModule->getFullModuleName();
1901 HadError = true;
1902 return;
1903 }
1904
1905 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001906 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001907 if (llvm::sys::path::is_absolute(DirName))
1908 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1909 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001910 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001911 PathName = Directory->getName();
1912 llvm::sys::path::append(PathName, DirName);
1913 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1914 }
1915
1916 if (!Dir) {
1917 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1918 << DirName;
1919 HadError = true;
1920 return;
1921 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001922
1923 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1924 // Mark this header 'textual' (see doc comment for
1925 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1926 // directory is relatively expensive, in practice this only applies to the
1927 // uncommonly used Tcl module on Darwin platforms.
1928 std::error_code EC;
1929 SmallVector<Module::Header, 6> Headers;
1930 for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E;
1931 I != E && !EC; I.increment(EC)) {
1932 if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
1933
1934 Module::Header Header = {I->path(), FE};
1935 Headers.push_back(std::move(Header));
1936 }
1937 }
1938
1939 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00001940 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1941
Ben Langmuir7ff29142015-08-13 17:13:33 +00001942 for (auto &Header : Headers)
1943 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1944 return;
1945 }
1946
Douglas Gregor524e33e2011-12-08 19:11:24 +00001947 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1948 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1949 << OwningModule->getFullModuleName();
1950 HadError = true;
1951 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001952 }
1953
Douglas Gregor524e33e2011-12-08 19:11:24 +00001954 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00001955 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001956}
1957
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001958/// \brief Parse a module export declaration.
1959///
1960/// export-declaration:
1961/// 'export' wildcard-module-id
1962///
1963/// wildcard-module-id:
1964/// identifier
1965/// '*'
1966/// identifier '.' wildcard-module-id
1967void ModuleMapParser::parseExportDecl() {
1968 assert(Tok.is(MMToken::ExportKeyword));
1969 SourceLocation ExportLoc = consumeToken();
1970
1971 // Parse the module-id with an optional wildcard at the end.
1972 ModuleId ParsedModuleId;
1973 bool Wildcard = false;
1974 do {
Richard Smith306d8922014-10-22 23:50:56 +00001975 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001976 if (Tok.is(MMToken::Identifier)) {
1977 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1978 Tok.getLocation()));
1979 consumeToken();
1980
1981 if (Tok.is(MMToken::Period)) {
1982 consumeToken();
1983 continue;
1984 }
1985
1986 break;
1987 }
1988
1989 if(Tok.is(MMToken::Star)) {
1990 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001991 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001992 break;
1993 }
1994
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001995 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001996 HadError = true;
1997 return;
1998 } while (true);
1999
2000 Module::UnresolvedExportDecl Unresolved = {
2001 ExportLoc, ParsedModuleId, Wildcard
2002 };
2003 ActiveModule->UnresolvedExports.push_back(Unresolved);
2004}
2005
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002006/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002007///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002008/// use-declaration:
2009/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002010void ModuleMapParser::parseUseDecl() {
2011 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002012 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002013 // Parse the module-id.
2014 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002015 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002016
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002017 if (ActiveModule->Parent)
2018 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2019 else
2020 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002021}
2022
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002023/// \brief Parse a link declaration.
2024///
2025/// module-declaration:
2026/// 'link' 'framework'[opt] string-literal
2027void ModuleMapParser::parseLinkDecl() {
2028 assert(Tok.is(MMToken::LinkKeyword));
2029 SourceLocation LinkLoc = consumeToken();
2030
2031 // Parse the optional 'framework' keyword.
2032 bool IsFramework = false;
2033 if (Tok.is(MMToken::FrameworkKeyword)) {
2034 consumeToken();
2035 IsFramework = true;
2036 }
2037
2038 // Parse the library name
2039 if (!Tok.is(MMToken::StringLiteral)) {
2040 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2041 << IsFramework << SourceRange(LinkLoc);
2042 HadError = true;
2043 return;
2044 }
2045
2046 std::string LibraryName = Tok.getString();
2047 consumeToken();
2048 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2049 IsFramework));
2050}
2051
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002052/// \brief Parse a configuration macro declaration.
2053///
2054/// module-declaration:
2055/// 'config_macros' attributes[opt] config-macro-list?
2056///
2057/// config-macro-list:
2058/// identifier (',' identifier)?
2059void ModuleMapParser::parseConfigMacros() {
2060 assert(Tok.is(MMToken::ConfigMacros));
2061 SourceLocation ConfigMacrosLoc = consumeToken();
2062
2063 // Only top-level modules can have configuration macros.
2064 if (ActiveModule->Parent) {
2065 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2066 }
2067
2068 // Parse the optional attributes.
2069 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002070 if (parseOptionalAttributes(Attrs))
2071 return;
2072
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002073 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2074 ActiveModule->ConfigMacrosExhaustive = true;
2075 }
2076
2077 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002078 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002079 if (!Tok.is(MMToken::Identifier))
2080 return;
2081
2082 // Consume the first identifier.
2083 if (!ActiveModule->Parent) {
2084 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2085 }
2086 consumeToken();
2087
2088 do {
2089 // If there's a comma, consume it.
2090 if (!Tok.is(MMToken::Comma))
2091 break;
2092 consumeToken();
2093
2094 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002095 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002096 if (!Tok.is(MMToken::Identifier)) {
2097 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2098 break;
2099 }
2100
2101 // Consume the macro name.
2102 if (!ActiveModule->Parent) {
2103 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2104 }
2105 consumeToken();
2106 } while (true);
2107}
2108
Douglas Gregorfb912652013-03-20 21:10:35 +00002109/// \brief Format a module-id into a string.
2110static std::string formatModuleId(const ModuleId &Id) {
2111 std::string result;
2112 {
2113 llvm::raw_string_ostream OS(result);
2114
2115 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2116 if (I)
2117 OS << ".";
2118 OS << Id[I].first;
2119 }
2120 }
2121
2122 return result;
2123}
2124
2125/// \brief Parse a conflict declaration.
2126///
2127/// module-declaration:
2128/// 'conflict' module-id ',' string-literal
2129void ModuleMapParser::parseConflict() {
2130 assert(Tok.is(MMToken::Conflict));
2131 SourceLocation ConflictLoc = consumeToken();
2132 Module::UnresolvedConflict Conflict;
2133
2134 // Parse the module-id.
2135 if (parseModuleId(Conflict.Id))
2136 return;
2137
2138 // Parse the ','.
2139 if (!Tok.is(MMToken::Comma)) {
2140 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2141 << SourceRange(ConflictLoc);
2142 return;
2143 }
2144 consumeToken();
2145
2146 // Parse the message.
2147 if (!Tok.is(MMToken::StringLiteral)) {
2148 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2149 << formatModuleId(Conflict.Id);
2150 return;
2151 }
2152 Conflict.Message = Tok.getString().str();
2153 consumeToken();
2154
2155 // Add this unresolved conflict.
2156 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2157}
2158
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002159/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002160///
2161/// module-declaration:
2162/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2163/// { inferred-module-member* }
2164///
2165/// inferred-module-member:
2166/// 'export' '*'
2167/// 'exclude' identifier
2168void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002169 assert(Tok.is(MMToken::Star));
2170 SourceLocation StarLoc = consumeToken();
2171 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002172
Douglas Gregor73441092011-12-05 22:27:44 +00002173 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002174 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002175 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2176 Failed = true;
2177 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002178
2179 if (ActiveModule) {
2180 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002181 if (!Failed && ActiveModule->IsAvailable &&
2182 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002183 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2184 Failed = true;
2185 }
2186
2187 // Check for redefinition of an inferred module.
2188 if (!Failed && ActiveModule->InferSubmodules) {
2189 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2190 if (ActiveModule->InferredSubmoduleLoc.isValid())
2191 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2192 diag::note_mmap_prev_definition);
2193 Failed = true;
2194 }
2195
2196 // Check for the 'framework' keyword, which is not permitted here.
2197 if (Framework) {
2198 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2199 Framework = false;
2200 }
2201 } else if (Explicit) {
2202 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2203 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002204 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002205
Douglas Gregor73441092011-12-05 22:27:44 +00002206 // If there were any problems with this inferred submodule, skip its body.
2207 if (Failed) {
2208 if (Tok.is(MMToken::LBrace)) {
2209 consumeToken();
2210 skipUntil(MMToken::RBrace);
2211 if (Tok.is(MMToken::RBrace))
2212 consumeToken();
2213 }
2214 HadError = true;
2215 return;
2216 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002217
2218 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002219 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002220 if (parseOptionalAttributes(Attrs))
2221 return;
Douglas Gregor9194a912012-11-06 19:39:40 +00002222
2223 if (ActiveModule) {
2224 // Note that we have an inferred submodule.
2225 ActiveModule->InferSubmodules = true;
2226 ActiveModule->InferredSubmoduleLoc = StarLoc;
2227 ActiveModule->InferExplicitSubmodules = Explicit;
2228 } else {
2229 // We'll be inferring framework modules for this directory.
2230 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002231 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002232 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002233 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002234 }
2235
Douglas Gregor73441092011-12-05 22:27:44 +00002236 // Parse the opening brace.
2237 if (!Tok.is(MMToken::LBrace)) {
2238 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2239 HadError = true;
2240 return;
2241 }
2242 SourceLocation LBraceLoc = consumeToken();
2243
2244 // Parse the body of the inferred submodule.
2245 bool Done = false;
2246 do {
2247 switch (Tok.Kind) {
2248 case MMToken::EndOfFile:
2249 case MMToken::RBrace:
2250 Done = true;
2251 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002252
2253 case MMToken::ExcludeKeyword: {
2254 if (ActiveModule) {
2255 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002256 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002257 consumeToken();
2258 break;
2259 }
2260
2261 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002262 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002263 if (!Tok.is(MMToken::Identifier)) {
2264 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2265 break;
2266 }
2267
2268 Map.InferredDirectories[Directory].ExcludedModules
2269 .push_back(Tok.getString());
2270 consumeToken();
2271 break;
2272 }
2273
2274 case MMToken::ExportKeyword:
2275 if (!ActiveModule) {
2276 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002277 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002278 consumeToken();
2279 break;
2280 }
2281
Douglas Gregor73441092011-12-05 22:27:44 +00002282 consumeToken();
2283 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002284 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002285 else
2286 Diags.Report(Tok.getLocation(),
2287 diag::err_mmap_expected_export_wildcard);
2288 consumeToken();
2289 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002290
Douglas Gregor73441092011-12-05 22:27:44 +00002291 case MMToken::ExplicitKeyword:
2292 case MMToken::ModuleKeyword:
2293 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002294 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002295 case MMToken::UmbrellaKeyword:
2296 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002297 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002298 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002299 consumeToken();
2300 break;
2301 }
2302 } while (!Done);
2303
2304 if (Tok.is(MMToken::RBrace))
2305 consumeToken();
2306 else {
2307 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2308 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2309 HadError = true;
2310 }
2311}
2312
Douglas Gregor9194a912012-11-06 19:39:40 +00002313/// \brief Parse optional attributes.
2314///
2315/// attributes:
2316/// attribute attributes
2317/// attribute
2318///
2319/// attribute:
2320/// [ identifier ]
2321///
2322/// \param Attrs Will be filled in with the parsed attributes.
2323///
2324/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002325bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002326 bool HadError = false;
2327
2328 while (Tok.is(MMToken::LSquare)) {
2329 // Consume the '['.
2330 SourceLocation LSquareLoc = consumeToken();
2331
2332 // Check whether we have an attribute name here.
2333 if (!Tok.is(MMToken::Identifier)) {
2334 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2335 skipUntil(MMToken::RSquare);
2336 if (Tok.is(MMToken::RSquare))
2337 consumeToken();
2338 HadError = true;
2339 }
2340
2341 // Decode the attribute name.
2342 AttributeKind Attribute
2343 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002344 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002345 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002346 .Case("system", AT_system)
2347 .Default(AT_unknown);
2348 switch (Attribute) {
2349 case AT_unknown:
2350 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2351 << Tok.getString();
2352 break;
2353
2354 case AT_system:
2355 Attrs.IsSystem = true;
2356 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002357
Richard Smith77944862014-03-02 05:58:18 +00002358 case AT_extern_c:
2359 Attrs.IsExternC = true;
2360 break;
2361
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002362 case AT_exhaustive:
2363 Attrs.IsExhaustive = true;
2364 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002365 }
2366 consumeToken();
2367
2368 // Consume the ']'.
2369 if (!Tok.is(MMToken::RSquare)) {
2370 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2371 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2372 skipUntil(MMToken::RSquare);
2373 HadError = true;
2374 }
2375
2376 if (Tok.is(MMToken::RSquare))
2377 consumeToken();
2378 }
2379
2380 return HadError;
2381}
2382
Douglas Gregor718292f2011-11-11 19:10:28 +00002383/// \brief Parse a module map file.
2384///
2385/// module-map-file:
2386/// module-declaration*
2387bool ModuleMapParser::parseModuleMapFile() {
2388 do {
2389 switch (Tok.Kind) {
2390 case MMToken::EndOfFile:
2391 return HadError;
2392
Douglas Gregore7ab3662011-12-07 02:23:45 +00002393 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002394 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002395 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002396 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002397 parseModuleDecl();
2398 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002399
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002400 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002401 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002402 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002403 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002404 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002405 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002406 case MMToken::HeaderKeyword:
2407 case MMToken::Identifier:
2408 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002409 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002410 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002411 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002412 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002413 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002414 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002415 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002416 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002417 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002418 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002419 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002420 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002421 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2422 HadError = true;
2423 consumeToken();
2424 break;
2425 }
2426 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002427}
2428
Richard Smith9acb99e32014-12-10 03:09:48 +00002429bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smithae6df272015-07-14 02:06:01 +00002430 const DirectoryEntry *Dir,
2431 SourceLocation ExternModuleLoc) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002432 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2433 = ParsedModuleMap.find(File);
2434 if (Known != ParsedModuleMap.end())
2435 return Known->second;
2436
Craig Topperd2d442c2014-05-17 23:10:59 +00002437 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002438 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
Richard Smithae6df272015-07-14 02:06:01 +00002439 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002440 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002441 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002442 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002443
Douglas Gregor718292f2011-11-11 19:10:28 +00002444 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002445 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Richard Smith2a6edb32015-08-09 04:46:57 +00002446 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002447 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002448 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002449 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002450 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002451
2452 // Notify callbacks that we parsed it.
2453 for (const auto &Cb : Callbacks)
2454 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002455 return Result;
2456}