blob: 301892c3b1b7e4a6c847116786953d9f729b10e4 [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() {
Douglas Gregor5acdf592011-11-17 02:05:44 +000097 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
98 IEnd = Modules.end();
99 I != IEnd; ++I) {
100 delete I->getValue();
101 }
Douglas Gregor718292f2011-11-11 19:10:28 +0000102}
103
Douglas Gregor89929282012-01-30 06:01:29 +0000104void ModuleMap::setTarget(const TargetInfo &Target) {
105 assert((!this->Target || this->Target == &Target) &&
106 "Improper target override");
107 this->Target = &Target;
108}
109
Douglas Gregor056396a2012-10-12 21:15:50 +0000110/// \brief "Sanitize" a filename so that it can be used as an identifier.
111static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
112 SmallVectorImpl<char> &Buffer) {
113 if (Name.empty())
114 return Name;
115
Jordan Rosea7d03842013-02-08 22:30:41 +0000116 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000117 // If we don't already have something with the form of an identifier,
118 // create a buffer with the sanitized name.
119 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000120 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000121 Buffer.push_back('_');
122 Buffer.reserve(Buffer.size() + Name.size());
123 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000124 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000125 Buffer.push_back(Name[I]);
126 else
127 Buffer.push_back('_');
128 }
129
130 Name = StringRef(Buffer.data(), Buffer.size());
131 }
132
133 while (llvm::StringSwitch<bool>(Name)
134#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
135#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
136#include "clang/Basic/TokenKinds.def"
137 .Default(false)) {
138 if (Name.data() != Buffer.data())
139 Buffer.append(Name.begin(), Name.end());
140 Buffer.push_back('_');
141 Name = StringRef(Buffer.data(), Buffer.size());
142 }
143
144 return Name;
145}
146
Douglas Gregor34d52742013-05-02 17:58:30 +0000147/// \brief Determine whether the given file name is the name of a builtin
148/// header, supplied by Clang to replace, override, or augment existing system
149/// headers.
150static bool isBuiltinHeader(StringRef FileName) {
151 return llvm::StringSwitch<bool>(FileName)
152 .Case("float.h", true)
153 .Case("iso646.h", true)
154 .Case("limits.h", true)
155 .Case("stdalign.h", true)
156 .Case("stdarg.h", true)
157 .Case("stdbool.h", true)
158 .Case("stddef.h", true)
159 .Case("stdint.h", true)
160 .Case("tgmath.h", true)
161 .Case("unwind.h", true)
162 .Default(false);
163}
164
Daniel Jasper92669ee2013-12-20 12:09:36 +0000165ModuleMap::HeadersMap::iterator
166ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000167 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000168 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
169 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000170 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
171 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000172 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000173 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000174 return Known;
175}
176
Ben Langmuir44691382014-04-10 00:39:10 +0000177ModuleMap::KnownHeader
178ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
179 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000180 if (UmbrellaDirs.empty())
181 return KnownHeader();
182
Ben Langmuir44691382014-04-10 00:39:10 +0000183 const DirectoryEntry *Dir = File->getDir();
184 assert(Dir && "file in no directory");
185
186 // Note: as an egregious but useful hack we use the real path here, because
187 // frameworks moving from top-level frameworks to embedded frameworks tend
188 // to be symlinked from the top-level location to the embedded location,
189 // and we need to resolve lookups as if we had found the embedded location.
190 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
191
192 // Keep walking up the directory hierarchy, looking for a directory with
193 // an umbrella header.
194 do {
195 auto KnownDir = UmbrellaDirs.find(Dir);
196 if (KnownDir != UmbrellaDirs.end())
197 return KnownHeader(KnownDir->second, NormalHeader);
198
199 IntermediateDirs.push_back(Dir);
200
201 // Retrieve our parent path.
202 DirName = llvm::sys::path::parent_path(DirName);
203 if (DirName.empty())
204 break;
205
206 // Resolve the parent path to a directory entry.
207 Dir = SourceMgr.getFileManager().getDirectory(DirName);
208 } while (Dir);
209 return KnownHeader();
210}
211
Daniel Jasper92669ee2013-12-20 12:09:36 +0000212static bool violatesPrivateInclude(Module *RequestingModule,
213 const FileEntry *IncFileEnt,
214 ModuleMap::ModuleHeaderRole Role,
215 Module *RequestedModule) {
Richard Smith202210b2014-10-24 20:23:01 +0000216 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
217#ifndef NDEBUG
Richard Smith2708e522015-03-10 00:19:04 +0000218 if (IsPrivateRole) {
219 // Check for consistency between the module header role
220 // as obtained from the lookup and as obtained from the module.
221 // This check is not cheap, so enable it only for debugging.
222 bool IsPrivate = false;
223 SmallVectorImpl<Module::Header> *HeaderList[] = {
224 &RequestedModule->Headers[Module::HK_Private],
225 &RequestedModule->Headers[Module::HK_PrivateTextual]};
226 for (auto *Hs : HeaderList)
227 IsPrivate |=
228 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000229 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000230 }) != Hs->end();
231 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
232 }
Richard Smith202210b2014-10-24 20:23:01 +0000233#endif
Manuel Klimeke8bd0db2015-11-05 15:24:47 +0000234 return IsPrivateRole && (!RequestingModule ||
235 RequestedModule->getTopLevelModule() !=
236 RequestingModule->getTopLevelModule());
Daniel Jasper92669ee2013-12-20 12:09:36 +0000237}
238
Ben Langmuir71e1a642014-05-05 21:44:13 +0000239static Module *getTopLevelOrNull(Module *M) {
240 return M ? M->getTopLevelModule() : nullptr;
241}
242
Daniel Jasper92669ee2013-12-20 12:09:36 +0000243void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
244 SourceLocation FilenameLoc,
245 StringRef Filename,
246 const FileEntry *File) {
247 // No errors for indirect modules. This may be a bit of a problem for modules
248 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000249 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000250 return;
251
252 if (RequestingModule)
253 resolveUses(RequestingModule, /*Complain=*/false);
254
Ben Langmuir71e1a642014-05-05 21:44:13 +0000255 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000256 Module *Private = nullptr;
257 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000258
Ben Langmuir71e1a642014-05-05 21:44:13 +0000259 HeadersMap::iterator Known = findKnownHeader(File);
260 if (Known != Headers.end()) {
261 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000262 // Remember private headers for later printing of a diagnostic.
263 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
264 Header.getModule())) {
265 Private = Header.getModule();
266 continue;
267 }
268
269 // If uses need to be specified explicitly, we are only allowed to return
270 // modules that are explicitly used by the requesting module.
271 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000272 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000273 NotUsed = Header.getModule();
274 continue;
275 }
276
277 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000278 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000279 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000280
281 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000282 }
283
284 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000285 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000286 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000287 << Filename;
288 return;
289 }
290
291 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000292 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000293 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000294 << RequestingModule->getFullModuleName() << Filename;
295 return;
296 }
297
Ben Langmuir71e1a642014-05-05 21:44:13 +0000298 if (Excluded || isHeaderInUmbrellaDirs(File))
299 return;
300
301 // At this point, only non-modular includes remain.
302
303 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000304 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000305 << RequestingModule->getFullModuleName() << Filename;
306 } else if (RequestingModule) {
307 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
308 diag::warn_non_modular_include_in_framework_module :
309 diag::warn_non_modular_include_in_module;
310 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000311 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000312}
313
Richard Smithec87a502015-02-13 23:50:20 +0000314static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
315 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000316 // Prefer available modules.
317 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
318 return true;
319
Richard Smithec87a502015-02-13 23:50:20 +0000320 // Prefer a public header over a private header.
321 if ((New.getRole() & ModuleMap::PrivateHeader) !=
322 (Old.getRole() & ModuleMap::PrivateHeader))
323 return !(New.getRole() & ModuleMap::PrivateHeader);
324
325 // Prefer a non-textual header over a textual header.
326 if ((New.getRole() & ModuleMap::TextualHeader) !=
327 (Old.getRole() & ModuleMap::TextualHeader))
328 return !(New.getRole() & ModuleMap::TextualHeader);
329
330 // Don't have a reason to choose between these. Just keep the first one.
331 return false;
332}
333
Sean Silva4881e8b2015-06-10 01:37:59 +0000334ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Richard Smith306d8922014-10-22 23:50:56 +0000335 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Sean Silva8230e5e2015-06-04 23:38:11 +0000336 if (R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000337 return ModuleMap::KnownHeader();
338 return R;
339 };
340
Sean Silva4881e8b2015-06-10 01:37:59 +0000341 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000342 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000343 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000344 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000345 for (KnownHeader &H : Known->second) {
Richard Smith7e82e012016-02-19 22:25:36 +0000346 // Prefer a header from the source module over all others.
347 if (H.getModule()->getTopLevelModule() == SourceModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000348 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000349 if (!Result || isBetterKnownHeader(H, Result))
350 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000351 }
Richard Smith306d8922014-10-22 23:50:56 +0000352 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000353 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000354
Richard Smith386bb072015-08-18 23:42:23 +0000355 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
356}
357
358ModuleMap::KnownHeader
359ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
360 assert(!Headers.count(File) && "already have a module for this header");
361
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000362 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000363 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
364 if (H) {
365 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000366
Ben Langmuir44691382014-04-10 00:39:10 +0000367 // Search up the module stack until we find a module with an umbrella
368 // directory.
369 Module *UmbrellaModule = Result;
370 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
371 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000372
Ben Langmuir44691382014-04-10 00:39:10 +0000373 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000374 const FileEntry *UmbrellaModuleMap =
375 getModuleMapFileForUniquing(UmbrellaModule);
376
Ben Langmuir44691382014-04-10 00:39:10 +0000377 // Infer submodules for each of the directories we found between
378 // the directory of the umbrella header and the directory where
379 // the actual header is located.
380 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000381
Ben Langmuir44691382014-04-10 00:39:10 +0000382 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
383 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000384 SmallString<32> NameBuf;
385 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000386 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000387 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
388 Explicit).first;
389 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000390 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000391
392 // Associate the module and the directory.
393 UmbrellaDirs[SkippedDirs[I-1]] = Result;
394
395 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000396 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000397 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000398 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000399 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000400
Ben Langmuir44691382014-04-10 00:39:10 +0000401 // Infer a submodule with the same name as this header file.
402 SmallString<32> NameBuf;
403 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000404 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000405 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
406 Explicit).first;
407 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000408 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000409 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000410
Ben Langmuir44691382014-04-10 00:39:10 +0000411 // If inferred submodules export everything they import, add a
412 // wildcard to the set of exports.
413 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000414 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000415 } else {
416 // Record each of the directories we stepped through as being part of
417 // the module we found, since the umbrella header covers them all.
418 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
419 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000420 }
Ben Langmuir44691382014-04-10 00:39:10 +0000421
Richard Smith386bb072015-08-18 23:42:23 +0000422 KnownHeader Header(Result, NormalHeader);
423 Headers[File].push_back(Header);
424 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000425 }
Richard Smith306d8922014-10-22 23:50:56 +0000426
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000427 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000428}
429
Richard Smith386bb072015-08-18 23:42:23 +0000430ArrayRef<ModuleMap::KnownHeader>
431ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
432 auto It = Headers.find(File);
433 if (It == Headers.end())
434 return None;
435 return It->second;
436}
437
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000438bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000439 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000440}
441
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000442bool
443ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
444 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000445 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000446 if (Known != Headers.end()) {
447 for (SmallVectorImpl<KnownHeader>::const_iterator
448 I = Known->second.begin(),
449 E = Known->second.end();
450 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000451 if (I->isAvailable() && (!RequestingModule ||
452 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000453 return false;
454 }
455 return true;
456 }
Richard Smith50996ce2014-04-08 13:13:04 +0000457
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000458 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000459 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000460 StringRef DirName = Dir->getName();
461
Richard Smith50996ce2014-04-08 13:13:04 +0000462 auto IsUnavailable = [&](const Module *M) {
463 return !M->isAvailable() && (!RequestingModule ||
464 M->isSubModuleOf(RequestingModule));
465 };
466
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000467 // Keep walking up the directory hierarchy, looking for a directory with
468 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000469 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000470 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000471 = UmbrellaDirs.find(Dir);
472 if (KnownDir != UmbrellaDirs.end()) {
473 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000474 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000475 return true;
476
477 // Search up the module stack until we find a module with an umbrella
478 // directory.
479 Module *UmbrellaModule = Found;
480 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
481 UmbrellaModule = UmbrellaModule->Parent;
482
483 if (UmbrellaModule->InferSubmodules) {
484 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
485 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000486 SmallString<32> NameBuf;
487 StringRef Name = sanitizeFilenameAsIdentifier(
488 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
489 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 Found = lookupModuleQualified(Name, Found);
491 if (!Found)
492 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000493 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000494 return true;
495 }
496
497 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000498 SmallString<32> NameBuf;
499 StringRef Name = sanitizeFilenameAsIdentifier(
500 llvm::sys::path::stem(Header->getName()),
501 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000502 Found = lookupModuleQualified(Name, Found);
503 if (!Found)
504 return false;
505 }
506
Richard Smith50996ce2014-04-08 13:13:04 +0000507 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000508 }
509
510 SkippedDirs.push_back(Dir);
511
512 // Retrieve our parent path.
513 DirName = llvm::sys::path::parent_path(DirName);
514 if (DirName.empty())
515 break;
516
517 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000518 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000519 } while (Dir);
520
521 return false;
522}
523
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000524Module *ModuleMap::findModule(StringRef Name) const {
525 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000526 if (Known != Modules.end())
527 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000528
529 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000530}
531
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000532Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
533 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000534 for(; Context; Context = Context->Parent) {
535 if (Module *Sub = lookupModuleQualified(Name, Context))
536 return Sub;
537 }
538
539 return findModule(Name);
540}
541
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000542Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000543 if (!Context)
544 return findModule(Name);
545
Douglas Gregoreb90e832012-01-04 23:32:19 +0000546 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000547}
548
Douglas Gregorde3ef502011-11-30 23:21:26 +0000549std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000550ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000551 bool IsExplicit) {
552 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000553 if (Module *Sub = lookupModuleQualified(Name, Parent))
554 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000555
556 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000557 Module *Result = new Module(Name, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000558 IsFramework, IsExplicit, NumCreatedModules++);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000559 if (!Parent) {
Richard Smith7e82e012016-02-19 22:25:36 +0000560 if (LangOpts.CurrentModule == Name)
561 SourceModule = Result;
Douglas Gregor69021972011-11-30 17:33:56 +0000562 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000563 }
Douglas Gregor69021972011-11-30 17:33:56 +0000564 return std::make_pair(Result, true);
565}
566
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000567/// \brief For a framework module, infer the framework against which we
568/// should link.
569static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
570 FileManager &FileMgr) {
571 assert(Mod->IsFramework && "Can only infer linking for framework modules");
572 assert(!Mod->isSubFramework() &&
573 "Can only infer linking for top-level frameworks");
574
575 SmallString<128> LibName;
576 LibName += FrameworkDir->getName();
577 llvm::sys::path::append(LibName, Mod->Name);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000578
579 // The library name of a framework has more than one possible extension since
580 // the introduction of the text-based dynamic library format. We need to check
581 // for both before we give up.
582 static const char *frameworkExtensions[] = {"", ".tbd"};
583 for (const auto *extension : frameworkExtensions) {
584 llvm::sys::path::replace_extension(LibName, extension);
585 if (FileMgr.getFile(LibName)) {
586 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
587 /*IsFramework=*/true));
588 return;
589 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000590 }
591}
592
Ben Langmuira5254002015-07-02 13:19:48 +0000593Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
594 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000595 Attributes Attrs;
596 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000597 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000598}
599
Ben Langmuira5254002015-07-02 13:19:48 +0000600Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000601 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000602 // Note: as an egregious but useful hack we use the real path here, because
603 // we might be looking at an embedded framework that symlinks out to a
604 // top-level framework, and we need to infer as if we were naming the
605 // top-level framework.
606 StringRef FrameworkDirName =
607 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
608
609 // In case this is a case-insensitive filesystem, use the canonical
610 // directory name as the ModuleName, since modules are case-sensitive.
611 // FIXME: we should be able to give a fix-it hint for the correct spelling.
612 SmallString<32> ModuleNameStorage;
613 StringRef ModuleName = sanitizeFilenameAsIdentifier(
614 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000615
Douglas Gregor56c64012011-11-17 01:41:17 +0000616 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000617 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
618 return Mod;
619
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000620 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000621
622 // If the framework has a parent path from which we're allowed to infer
623 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000624 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000625 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000626 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000627 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000628 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000629 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000631 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
632 // Check whether we have already looked into the parent directory
633 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000634 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000635 inferred = InferredDirectories.find(ParentDir);
636 if (inferred == InferredDirectories.end()) {
637 // We haven't looked here before. Load a module map, if there is
638 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000639 bool IsFrameworkDir = Parent.endswith(".framework");
640 if (const FileEntry *ModMapFile =
641 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000642 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000643 inferred = InferredDirectories.find(ParentDir);
644 }
645
646 if (inferred == InferredDirectories.end())
647 inferred = InferredDirectories.insert(
648 std::make_pair(ParentDir, InferredDirectory())).first;
649 }
650
651 if (inferred->second.InferModules) {
652 // We're allowed to infer for this directory, but make sure it's okay
653 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000654 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000655 canInfer = std::find(inferred->second.ExcludedModules.begin(),
656 inferred->second.ExcludedModules.end(),
657 Name) == inferred->second.ExcludedModules.end();
658
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000659 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
660 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
661 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000662 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000663 }
664 }
665 }
666
667 // If we're not allowed to infer a framework module, don't.
668 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000669 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000670 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000671 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000672
673
Douglas Gregor56c64012011-11-17 01:41:17 +0000674 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000675 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000676 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000677 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000678
679 // FIXME: If there's no umbrella header, we could probably scan the
680 // framework to load *everything*. But, it's not clear that this is a good
681 // idea.
682 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000683 return nullptr;
684
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000685 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000686 /*IsFramework=*/true, /*IsExplicit=*/false,
687 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000688 InferredModuleAllowedBy[Result] = ModuleMapFile;
689 Result->IsInferred = true;
Richard Smith7e82e012016-02-19 22:25:36 +0000690 if (!Parent) {
691 if (LangOpts.CurrentModule == ModuleName)
692 SourceModule = Result;
693 Modules[ModuleName] = Result;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000694 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000695
696 Result->IsSystem |= Attrs.IsSystem;
697 Result->IsExternC |= Attrs.IsExternC;
698 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Richard Smith2b63d152015-05-16 02:28:53 +0000699 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000700
Douglas Gregor322f6332011-12-08 18:00:48 +0000701 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000702 //
703 // The "Headers/" component of the name is implied because this is
704 // a framework module.
705 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000706
707 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000708 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
709
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000710 // module * { export * }
711 Result->InferSubmodules = true;
712 Result->InferExportWildcard = true;
713
Douglas Gregore89dbc12011-12-06 19:39:29 +0000714 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000715 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000716 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000717 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000718 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000719 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000720 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000721 Dir != DirEnd && !EC; Dir.increment(EC)) {
722 if (!StringRef(Dir->path()).endswith(".framework"))
723 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000724
Douglas Gregore89dbc12011-12-06 19:39:29 +0000725 if (const DirectoryEntry *SubframeworkDir
726 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000727 // Note: as an egregious but useful hack, we use the real path here and
728 // check whether it is actually a subdirectory of the parent directory.
729 // This will not be the case if the 'subframework' is actually a symlink
730 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000731 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
732 bool FoundParent = false;
733 do {
734 // Get the parent directory name.
735 SubframeworkDirName
736 = llvm::sys::path::parent_path(SubframeworkDirName);
737 if (SubframeworkDirName.empty())
738 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000739
Douglas Gregore00c8b22013-01-26 00:55:12 +0000740 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
741 FoundParent = true;
742 break;
743 }
744 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000745
Douglas Gregore00c8b22013-01-26 00:55:12 +0000746 if (!FoundParent)
747 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000748
Douglas Gregore89dbc12011-12-06 19:39:29 +0000749 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000750 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000751 }
752 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000753
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000754 // If the module is a top-level framework, automatically link against the
755 // framework.
756 if (!Result->isSubFramework()) {
757 inferFrameworkLink(Result, FrameworkDir, FileMgr);
758 }
759
Douglas Gregor56c64012011-11-17 01:41:17 +0000760 return Result;
761}
762
Richard Smith2b63d152015-05-16 02:28:53 +0000763void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
764 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000765 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000766 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000767 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000768 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000769}
770
Richard Smith2b63d152015-05-16 02:28:53 +0000771void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
772 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000773 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000774 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000775 UmbrellaDirs[UmbrellaDir] = Mod;
776}
777
Richard Smith3c1a41a2014-12-02 00:08:08 +0000778static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000779 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000780 default: llvm_unreachable("unknown header role");
781 case ModuleMap::NormalHeader:
782 return Module::HK_Normal;
783 case ModuleMap::PrivateHeader:
784 return Module::HK_Private;
785 case ModuleMap::TextualHeader:
786 return Module::HK_Textual;
787 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
788 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000789 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000790}
791
Richard Smith3c1a41a2014-12-02 00:08:08 +0000792void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000793 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000794 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000795
Richard Smith386bb072015-08-18 23:42:23 +0000796 // Only add each header to the headers list once.
797 // FIXME: Should we diagnose if a header is listed twice in the
798 // same module definition?
799 auto &HeaderList = Headers[Header.Entry];
800 for (auto H : HeaderList)
801 if (H == KH)
802 return;
803
804 HeaderList.push_back(KH);
Richard Smith3c1a41a2014-12-02 00:08:08 +0000805 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
Richard Smith386bb072015-08-18 23:42:23 +0000806
Richard Smith7e82e012016-02-19 22:25:36 +0000807 bool isCompilingModuleHeader =
808 LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000809 if (!Imported || isCompilingModuleHeader) {
810 // When we import HeaderFileInfo, the external source is expected to
811 // set the isModuleHeader flag itself.
812 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
813 isCompilingModuleHeader);
814 }
Richard Smith3c1a41a2014-12-02 00:08:08 +0000815}
816
817void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000818 // Add this as a known header so we won't implicitly add it to any
819 // umbrella directory module.
820 // FIXME: Should we only exclude it from umbrella modules within the
821 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000822 (void) Headers[Header.Entry];
823
824 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000825}
826
Douglas Gregor514b6362011-11-29 19:06:37 +0000827const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000828ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000829 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000830 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000831
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000832 return SourceMgr.getFileEntryForID(
833 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000834}
835
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000836const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000837 if (M->IsInferred) {
838 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
839 return InferredModuleAllowedBy.find(M)->second;
840 }
841 return getContainingModuleMapFile(M);
842}
843
844void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
845 assert(M->IsInferred && "module not inferred");
846 InferredModuleAllowedBy[M] = ModMap;
847}
848
Yaron Kerencdae9412016-01-29 19:38:18 +0000849LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +0000850 llvm::errs() << "Modules:";
851 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
852 MEnd = Modules.end();
853 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000854 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000855
856 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000857 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000858 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000859 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
860 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
861 E = H->second.end();
862 I != E; ++I) {
863 if (I != H->second.begin())
864 llvm::errs() << ",";
865 llvm::errs() << I->getModule()->getFullModuleName();
866 }
867 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000868 }
869}
870
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000871bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000872 auto Unresolved = std::move(Mod->UnresolvedExports);
873 Mod->UnresolvedExports.clear();
874 for (auto &UE : Unresolved) {
875 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000876 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000877 Mod->Exports.push_back(Export);
878 else
Richard Smith42413142015-05-15 20:05:43 +0000879 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000880 }
Richard Smith42413142015-05-15 20:05:43 +0000881 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000882}
883
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000884bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000885 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
886 Mod->UnresolvedDirectUses.clear();
887 for (auto &UDU : Unresolved) {
888 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000889 if (DirectUse)
890 Mod->DirectUses.push_back(DirectUse);
891 else
Richard Smith42413142015-05-15 20:05:43 +0000892 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000893 }
Richard Smith42413142015-05-15 20:05:43 +0000894 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000895}
896
Douglas Gregorfb912652013-03-20 21:10:35 +0000897bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000898 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000899 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000900 for (auto &UC : Unresolved) {
901 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
902 Module::Conflict Conflict;
903 Conflict.Other = OtherMod;
904 Conflict.Message = UC.Message;
905 Mod->Conflicts.push_back(Conflict);
906 } else
907 Mod->UnresolvedConflicts.push_back(UC);
908 }
909 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000910}
911
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000912Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
913 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000914 return nullptr;
915
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000916 // Use the expansion location to determine which module we're in.
917 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
918 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000919 return nullptr;
920
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000921 const SourceManager &SrcMgr = Loc.getManager();
922 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000923
Douglas Gregor224d8a72012-01-06 17:19:32 +0000924 while (const FileEntry *ExpansionFile
925 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
926 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000927 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000928 return Mod;
929
930 // No module owns this header, so look up the inclusion chain to see if
931 // any included header has an associated module.
932 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
933 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000934 return nullptr;
935
Douglas Gregor224d8a72012-01-06 17:19:32 +0000936 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
937 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000938
939 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000940}
941
Douglas Gregor718292f2011-11-11 19:10:28 +0000942//----------------------------------------------------------------------------//
943// Module map file parser
944//----------------------------------------------------------------------------//
945
946namespace clang {
947 /// \brief A token in a module map file.
948 struct MMToken {
949 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000950 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000951 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000952 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000953 EndOfFile,
954 HeaderKeyword,
955 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000956 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000957 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000958 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000959 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000960 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000961 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000962 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000963 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000964 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000965 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000966 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000967 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000968 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000969 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000970 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000971 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000972 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000973 RBrace,
974 LSquare,
975 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000976 } Kind;
977
978 unsigned Location;
979 unsigned StringLength;
980 const char *StringData;
981
982 void clear() {
983 Kind = EndOfFile;
984 Location = 0;
985 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000986 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000987 }
988
989 bool is(TokenKind K) const { return Kind == K; }
990
991 SourceLocation getLocation() const {
992 return SourceLocation::getFromRawEncoding(Location);
993 }
994
995 StringRef getString() const {
996 return StringRef(StringData, StringLength);
997 }
998 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000999
Douglas Gregor718292f2011-11-11 19:10:28 +00001000 class ModuleMapParser {
1001 Lexer &L;
1002 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001003
1004 /// \brief Default target information, used only for string literal
1005 /// parsing.
1006 const TargetInfo *Target;
1007
Douglas Gregor718292f2011-11-11 19:10:28 +00001008 DiagnosticsEngine &Diags;
1009 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001010
1011 /// \brief The current module map file.
1012 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001013
Richard Smith9acb99e32014-12-10 03:09:48 +00001014 /// \brief The directory that file names in this module map file should
1015 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001016 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001017
1018 /// \brief The directory containing Clang-supplied headers.
1019 const DirectoryEntry *BuiltinIncludeDir;
1020
Douglas Gregor963c5532013-06-21 16:28:10 +00001021 /// \brief Whether this module map is in a system header directory.
1022 bool IsSystem;
1023
Douglas Gregor718292f2011-11-11 19:10:28 +00001024 /// \brief Whether an error occurred.
1025 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001026
Douglas Gregor718292f2011-11-11 19:10:28 +00001027 /// \brief Stores string data for the various string literals referenced
1028 /// during parsing.
1029 llvm::BumpPtrAllocator StringData;
1030
1031 /// \brief The current token.
1032 MMToken Tok;
1033
1034 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001035 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001036
1037 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1038 /// contents as 'textual'.
1039 ///
1040 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1041 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1042 /// non-modular headers. For backwards compatibility, we continue to
1043 /// support this idiom for just these modules, and map the headers to
1044 /// 'textual' to match the original intent.
1045 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1046
Douglas Gregor718292f2011-11-11 19:10:28 +00001047 /// \brief Consume the current token and return its location.
1048 SourceLocation consumeToken();
1049
1050 /// \brief Skip tokens until we reach the a token with the given kind
1051 /// (or the end of the file).
1052 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001053
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001054 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001055 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001056 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001057 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001058 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001059 void parseHeaderDecl(clang::MMToken::TokenKind,
1060 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001061 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001062 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001063 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001064 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001065 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001066 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001067 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001068
1069 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001070 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001071
Douglas Gregor718292f2011-11-11 19:10:28 +00001072 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001073 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001074 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001075 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001076 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001077 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001078 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001079 const DirectoryEntry *BuiltinIncludeDir,
1080 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001081 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001082 ModuleMapFile(ModuleMapFile), Directory(Directory),
1083 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001084 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001085 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001086 Tok.clear();
1087 consumeToken();
1088 }
1089
1090 bool parseModuleMapFile();
1091 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001092}
Douglas Gregor718292f2011-11-11 19:10:28 +00001093
1094SourceLocation ModuleMapParser::consumeToken() {
1095retry:
1096 SourceLocation Result = Tok.getLocation();
1097 Tok.clear();
1098
1099 Token LToken;
1100 L.LexFromRawLexer(LToken);
1101 Tok.Location = LToken.getLocation().getRawEncoding();
1102 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001103 case tok::raw_identifier: {
1104 StringRef RI = LToken.getRawIdentifier();
1105 Tok.StringData = RI.data();
1106 Tok.StringLength = RI.size();
1107 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001108 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001109 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001110 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001111 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001112 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001113 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001114 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001115 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001116 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001117 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001118 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001119 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001120 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001121 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001122 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001123 .Default(MMToken::Identifier);
1124 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001125 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001126
1127 case tok::comma:
1128 Tok.Kind = MMToken::Comma;
1129 break;
1130
Douglas Gregor718292f2011-11-11 19:10:28 +00001131 case tok::eof:
1132 Tok.Kind = MMToken::EndOfFile;
1133 break;
1134
1135 case tok::l_brace:
1136 Tok.Kind = MMToken::LBrace;
1137 break;
1138
Douglas Gregora686e1b2012-01-27 19:52:33 +00001139 case tok::l_square:
1140 Tok.Kind = MMToken::LSquare;
1141 break;
1142
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001143 case tok::period:
1144 Tok.Kind = MMToken::Period;
1145 break;
1146
Douglas Gregor718292f2011-11-11 19:10:28 +00001147 case tok::r_brace:
1148 Tok.Kind = MMToken::RBrace;
1149 break;
1150
Douglas Gregora686e1b2012-01-27 19:52:33 +00001151 case tok::r_square:
1152 Tok.Kind = MMToken::RSquare;
1153 break;
1154
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001155 case tok::star:
1156 Tok.Kind = MMToken::Star;
1157 break;
1158
Richard Smitha3feee22013-10-28 22:18:19 +00001159 case tok::exclaim:
1160 Tok.Kind = MMToken::Exclaim;
1161 break;
1162
Douglas Gregor718292f2011-11-11 19:10:28 +00001163 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001164 if (LToken.hasUDSuffix()) {
1165 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1166 HadError = true;
1167 goto retry;
1168 }
1169
Douglas Gregor718292f2011-11-11 19:10:28 +00001170 // Parse the string literal.
1171 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001172 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001173 if (StringLiteral.hadError)
1174 goto retry;
1175
1176 // Copy the string literal into our string data allocator.
1177 unsigned Length = StringLiteral.GetStringLength();
1178 char *Saved = StringData.Allocate<char>(Length + 1);
1179 memcpy(Saved, StringLiteral.GetString().data(), Length);
1180 Saved[Length] = 0;
1181
1182 // Form the token.
1183 Tok.Kind = MMToken::StringLiteral;
1184 Tok.StringData = Saved;
1185 Tok.StringLength = Length;
1186 break;
1187 }
1188
1189 case tok::comment:
1190 goto retry;
1191
1192 default:
1193 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1194 HadError = true;
1195 goto retry;
1196 }
1197
1198 return Result;
1199}
1200
1201void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1202 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001203 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001204 do {
1205 switch (Tok.Kind) {
1206 case MMToken::EndOfFile:
1207 return;
1208
1209 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001210 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001211 return;
1212
1213 ++braceDepth;
1214 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001215
1216 case MMToken::LSquare:
1217 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1218 return;
1219
1220 ++squareDepth;
1221 break;
1222
Douglas Gregor718292f2011-11-11 19:10:28 +00001223 case MMToken::RBrace:
1224 if (braceDepth > 0)
1225 --braceDepth;
1226 else if (Tok.is(K))
1227 return;
1228 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001229
1230 case MMToken::RSquare:
1231 if (squareDepth > 0)
1232 --squareDepth;
1233 else if (Tok.is(K))
1234 return;
1235 break;
1236
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001238 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001239 return;
1240 break;
1241 }
1242
1243 consumeToken();
1244 } while (true);
1245}
1246
Douglas Gregore7ab3662011-12-07 02:23:45 +00001247/// \brief Parse a module-id.
1248///
1249/// module-id:
1250/// identifier
1251/// identifier '.' module-id
1252///
1253/// \returns true if an error occurred, false otherwise.
1254bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1255 Id.clear();
1256 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001257 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001258 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1259 consumeToken();
1260 } else {
1261 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1262 return true;
1263 }
1264
1265 if (!Tok.is(MMToken::Period))
1266 break;
1267
1268 consumeToken();
1269 } while (true);
1270
1271 return false;
1272}
1273
Douglas Gregora686e1b2012-01-27 19:52:33 +00001274namespace {
1275 /// \brief Enumerates the known attributes.
1276 enum AttributeKind {
1277 /// \brief An unknown attribute.
1278 AT_unknown,
1279 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001280 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001281 /// \brief The 'extern_c' attribute.
1282 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001283 /// \brief The 'exhaustive' attribute.
1284 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001285 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001286}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001287
Douglas Gregor718292f2011-11-11 19:10:28 +00001288/// \brief Parse a module declaration.
1289///
1290/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001291/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001292/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1293/// { module-member* }
1294///
Douglas Gregor718292f2011-11-11 19:10:28 +00001295/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001296/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001297/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001298/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001299/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001300/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001301///
1302/// submodule-declaration:
1303/// module-declaration
1304/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001305void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001306 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001307 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1308 if (Tok.is(MMToken::ExternKeyword)) {
1309 parseExternModuleDecl();
1310 return;
1311 }
1312
Douglas Gregorf2161a72011-12-06 17:16:41 +00001313 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001314 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001315 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001316 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001317
Douglas Gregorf2161a72011-12-06 17:16:41 +00001318 // Parse 'explicit' keyword, if present.
1319 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001320 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001321 Explicit = true;
1322 }
1323
1324 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001325 if (Tok.is(MMToken::FrameworkKeyword)) {
1326 consumeToken();
1327 Framework = true;
1328 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001329
1330 // Parse 'module' keyword.
1331 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001332 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001333 consumeToken();
1334 HadError = true;
1335 return;
1336 }
1337 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001338
1339 // If we have a wildcard for the module name, this is an inferred submodule.
1340 // Parse it.
1341 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001342 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001343
1344 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001345 ModuleId Id;
1346 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001347 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001348 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001349 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001350
Douglas Gregore7ab3662011-12-07 02:23:45 +00001351 if (ActiveModule) {
1352 if (Id.size() > 1) {
1353 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1354 << SourceRange(Id.front().second, Id.back().second);
1355
1356 HadError = true;
1357 return;
1358 }
1359 } else if (Id.size() == 1 && Explicit) {
1360 // Top-level modules can't be explicit.
1361 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1362 Explicit = false;
1363 ExplicitLoc = SourceLocation();
1364 HadError = true;
1365 }
1366
1367 Module *PreviousActiveModule = ActiveModule;
1368 if (Id.size() > 1) {
1369 // This module map defines a submodule. Go find the module of which it
1370 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001371 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001372 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001373 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1374 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001375 if (I == 0)
1376 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001377 ActiveModule = Next;
1378 continue;
1379 }
1380
1381 if (ActiveModule) {
1382 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001383 << Id[I].first
1384 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001385 } else {
1386 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1387 }
1388 HadError = true;
1389 return;
1390 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001391
1392 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1393 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1394 "submodule defined in same file as 'module *' that allowed its "
1395 "top-level module");
1396 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1397 }
1398 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001399
1400 StringRef ModuleName = Id.back().first;
1401 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001402
Douglas Gregora686e1b2012-01-27 19:52:33 +00001403 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001404 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00001405 if (parseOptionalAttributes(Attrs))
1406 return;
1407
Douglas Gregora686e1b2012-01-27 19:52:33 +00001408
Douglas Gregor718292f2011-11-11 19:10:28 +00001409 // Parse the opening brace.
1410 if (!Tok.is(MMToken::LBrace)) {
1411 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1412 << ModuleName;
1413 HadError = true;
1414 return;
1415 }
1416 SourceLocation LBraceLoc = consumeToken();
1417
1418 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001419 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001420 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1421 // Skip the module definition.
1422 skipUntil(MMToken::RBrace);
1423 if (Tok.is(MMToken::RBrace))
1424 consumeToken();
1425 else {
1426 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1427 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1428 HadError = true;
1429 }
1430 return;
1431 }
1432
Douglas Gregor718292f2011-11-11 19:10:28 +00001433 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1434 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001435 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001436
1437 // Skip the module definition.
1438 skipUntil(MMToken::RBrace);
1439 if (Tok.is(MMToken::RBrace))
1440 consumeToken();
1441
1442 HadError = true;
1443 return;
1444 }
1445
1446 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001447 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1448 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001449 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001450 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001451 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001452 if (Attrs.IsExternC)
1453 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001454 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001455
Douglas Gregor718292f2011-11-11 19:10:28 +00001456 bool Done = false;
1457 do {
1458 switch (Tok.Kind) {
1459 case MMToken::EndOfFile:
1460 case MMToken::RBrace:
1461 Done = true;
1462 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001463
1464 case MMToken::ConfigMacros:
1465 parseConfigMacros();
1466 break;
1467
Douglas Gregorfb912652013-03-20 21:10:35 +00001468 case MMToken::Conflict:
1469 parseConflict();
1470 break;
1471
Douglas Gregor718292f2011-11-11 19:10:28 +00001472 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001473 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001474 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001475 case MMToken::ModuleKeyword:
1476 parseModuleDecl();
1477 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001478
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001479 case MMToken::ExportKeyword:
1480 parseExportDecl();
1481 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001482
1483 case MMToken::UseKeyword:
1484 parseUseDecl();
1485 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001486
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001487 case MMToken::RequiresKeyword:
1488 parseRequiresDecl();
1489 break;
1490
Richard Smith202210b2014-10-24 20:23:01 +00001491 case MMToken::TextualKeyword:
1492 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001493 break;
Richard Smith306d8922014-10-22 23:50:56 +00001494
Douglas Gregor524e33e2011-12-08 19:11:24 +00001495 case MMToken::UmbrellaKeyword: {
1496 SourceLocation UmbrellaLoc = consumeToken();
1497 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001498 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001499 else
1500 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001501 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001502 }
Richard Smith202210b2014-10-24 20:23:01 +00001503
1504 case MMToken::ExcludeKeyword:
1505 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001506 break;
Richard Smith202210b2014-10-24 20:23:01 +00001507
1508 case MMToken::PrivateKeyword:
1509 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001510 break;
Richard Smith202210b2014-10-24 20:23:01 +00001511
Douglas Gregor322f6332011-12-08 18:00:48 +00001512 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001513 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001514 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001515
1516 case MMToken::LinkKeyword:
1517 parseLinkDecl();
1518 break;
1519
Douglas Gregor718292f2011-11-11 19:10:28 +00001520 default:
1521 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1522 consumeToken();
1523 break;
1524 }
1525 } while (!Done);
1526
1527 if (Tok.is(MMToken::RBrace))
1528 consumeToken();
1529 else {
1530 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1531 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1532 HadError = true;
1533 }
1534
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001535 // If the active module is a top-level framework, and there are no link
1536 // libraries, automatically link against the framework.
1537 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1538 ActiveModule->LinkLibraries.empty()) {
1539 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1540 }
1541
Ben Langmuirec8c9752014-04-18 22:07:31 +00001542 // If the module meets all requirements but is still unavailable, mark the
1543 // whole tree as unavailable to prevent it from building.
1544 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1545 ActiveModule->Parent) {
1546 ActiveModule->getTopLevelModule()->markUnavailable();
1547 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1548 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1549 }
1550
Douglas Gregore7ab3662011-12-07 02:23:45 +00001551 // We're done parsing this module. Pop back to the previous module.
1552 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001553}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001554
Daniel Jasper97292842013-09-11 07:20:44 +00001555/// \brief Parse an extern module declaration.
1556///
1557/// extern module-declaration:
1558/// 'extern' 'module' module-id string-literal
1559void ModuleMapParser::parseExternModuleDecl() {
1560 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001561 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001562
1563 // Parse 'module' keyword.
1564 if (!Tok.is(MMToken::ModuleKeyword)) {
1565 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1566 consumeToken();
1567 HadError = true;
1568 return;
1569 }
1570 consumeToken(); // 'module' keyword
1571
1572 // Parse the module name.
1573 ModuleId Id;
1574 if (parseModuleId(Id)) {
1575 HadError = true;
1576 return;
1577 }
1578
1579 // Parse the referenced module map file name.
1580 if (!Tok.is(MMToken::StringLiteral)) {
1581 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1582 HadError = true;
1583 return;
1584 }
1585 std::string FileName = Tok.getString();
1586 consumeToken(); // filename
1587
1588 StringRef FileNameRef = FileName;
1589 SmallString<128> ModuleMapFileName;
1590 if (llvm::sys::path::is_relative(FileNameRef)) {
1591 ModuleMapFileName += Directory->getName();
1592 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001593 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001594 }
1595 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001596 Map.parseModuleMapFile(
1597 File, /*IsSystem=*/false,
1598 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1599 ? Directory
Richard Smithae6df272015-07-14 02:06:01 +00001600 : File->getDir(), ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001601}
1602
Ben Langmuir7ff29142015-08-13 17:13:33 +00001603/// Whether to add the requirement \p Feature to the module \p M.
1604///
1605/// This preserves backwards compatibility for two hacks in the Darwin system
1606/// module map files:
1607///
1608/// 1. The use of 'requires excluded' to make headers non-modular, which
1609/// should really be mapped to 'textual' now that we have this feature. We
1610/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1611/// true. Later, this bit will be used to map all the headers inside this
1612/// module to 'textual'.
1613///
1614/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1615///
1616/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1617/// was never correct and causes issues now that we check it, so drop it.
1618static bool shouldAddRequirement(Module *M, StringRef Feature,
1619 bool &IsRequiresExcludedHack) {
1620 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1621 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1622 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1623
1624 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1625 M->fullModuleNameIs(TclPrivate))) {
1626 IsRequiresExcludedHack = true;
1627 return false;
1628 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1629 return false;
1630 }
1631
1632 return true;
1633}
1634
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001635/// \brief Parse a requires declaration.
1636///
1637/// requires-declaration:
1638/// 'requires' feature-list
1639///
1640/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001641/// feature ',' feature-list
1642/// feature
1643///
1644/// feature:
1645/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001646void ModuleMapParser::parseRequiresDecl() {
1647 assert(Tok.is(MMToken::RequiresKeyword));
1648
1649 // Parse 'requires' keyword.
1650 consumeToken();
1651
1652 // Parse the feature-list.
1653 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001654 bool RequiredState = true;
1655 if (Tok.is(MMToken::Exclaim)) {
1656 RequiredState = false;
1657 consumeToken();
1658 }
1659
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001660 if (!Tok.is(MMToken::Identifier)) {
1661 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1662 HadError = true;
1663 return;
1664 }
1665
1666 // Consume the feature name.
1667 std::string Feature = Tok.getString();
1668 consumeToken();
1669
Ben Langmuir7ff29142015-08-13 17:13:33 +00001670 bool IsRequiresExcludedHack = false;
1671 bool ShouldAddRequirement =
1672 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1673
1674 if (IsRequiresExcludedHack)
1675 UsesRequiresExcludedHack.insert(ActiveModule);
1676
1677 if (ShouldAddRequirement) {
1678 // Add this feature.
1679 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1680 *Map.Target);
1681 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001682
1683 if (!Tok.is(MMToken::Comma))
1684 break;
1685
1686 // Consume the comma.
1687 consumeToken();
1688 } while (true);
1689}
1690
Douglas Gregorf2161a72011-12-06 17:16:41 +00001691/// \brief Append to \p Paths the set of paths needed to get to the
1692/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001693static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001694 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001695 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001696 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001697 for (; Mod; Mod = Mod->Parent) {
1698 if (Mod->IsFramework)
1699 Paths.push_back(Mod->Name);
1700 }
1701
1702 if (Paths.empty())
1703 return;
1704
1705 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001706 for (unsigned I = Paths.size() - 1; I != 0; --I)
1707 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001708}
1709
Douglas Gregor718292f2011-11-11 19:10:28 +00001710/// \brief Parse a header declaration.
1711///
1712/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001713/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001714/// 'private' 'textual'[opt] 'header' string-literal
1715/// 'exclude' 'header' string-literal
1716/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001717///
1718/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001719void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1720 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001721 // We've already consumed the first token.
1722 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1723 if (LeadingToken == MMToken::PrivateKeyword) {
1724 Role = ModuleMap::PrivateHeader;
1725 // 'private' may optionally be followed by 'textual'.
1726 if (Tok.is(MMToken::TextualKeyword)) {
1727 LeadingToken = Tok.Kind;
1728 consumeToken();
1729 }
1730 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001731
Richard Smith202210b2014-10-24 20:23:01 +00001732 if (LeadingToken == MMToken::TextualKeyword)
1733 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1734
Ben Langmuir7ff29142015-08-13 17:13:33 +00001735 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1736 // Mark this header 'textual' (see doc comment for
1737 // Module::UsesRequiresExcludedHack).
1738 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1739 }
1740
Richard Smith202210b2014-10-24 20:23:01 +00001741 if (LeadingToken != MMToken::HeaderKeyword) {
1742 if (!Tok.is(MMToken::HeaderKeyword)) {
1743 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1744 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1745 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1746 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1747 return;
1748 }
1749 consumeToken();
1750 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001751
Douglas Gregor718292f2011-11-11 19:10:28 +00001752 // Parse the header name.
1753 if (!Tok.is(MMToken::StringLiteral)) {
1754 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1755 << "header";
1756 HadError = true;
1757 return;
1758 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001759 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001760 Header.FileName = Tok.getString();
1761 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001762
Douglas Gregor524e33e2011-12-08 19:11:24 +00001763 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001764 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001765 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001766 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001767 HadError = true;
1768 return;
1769 }
1770
Douglas Gregor5257fc62011-11-11 21:55:48 +00001771 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001772 const FileEntry *File = nullptr;
1773 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001774 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001775 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001776 RelativePathName = Header.FileName;
1777 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001778 } else {
1779 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001780 SmallString<128> FullPathName(Directory->getName());
1781 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001782
Douglas Gregorf2161a72011-12-06 17:16:41 +00001783 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001784 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001785
1786 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001787 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001788 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001789 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001790
1791 if (!File) {
1792 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001793 // FIXME: Should we retain the subframework paths here?
1794 RelativePathName.clear();
1795 FullPathName.resize(FullPathLength);
1796 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1797 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001798 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001799 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001800 }
1801 } else {
1802 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001803 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001804 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001805 File = SourceMgr.getFileManager().getFile(FullPathName);
1806
Douglas Gregor3ec66632012-02-02 18:42:48 +00001807 // If this is a system module with a top-level header, this header
1808 // may have a counterpart (or replacement) in the set of headers
1809 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001810 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1811 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001812 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001813 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001814 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001815 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001816
Douglas Gregor3ec66632012-02-02 18:42:48 +00001817 // If Clang supplies this header but the underlying system does not,
1818 // just silently swap in our builtin version. Otherwise, we'll end
1819 // up adding both (later).
Richard Smith42413142015-05-15 20:05:43 +00001820 //
1821 // For local visibility, entirely replace the system file with our
1822 // one and textually include the system one. We need to pass macros
1823 // from our header to the system one if we #include_next it.
1824 //
1825 // FIXME: Can we do this in all cases?
1826 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001827 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001828 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001829 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001830 }
1831 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001832 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001833 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001834
Douglas Gregor5257fc62011-11-11 21:55:48 +00001835 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1836 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001837 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001838 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001839 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001840 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001841 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001842 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001843 HadError = true;
1844 } else {
1845 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001846 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001847 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001848 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001849 Module::Header H = {RelativePathName.str(), File};
1850 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001851 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001852 // If there is a builtin counterpart to this file, add it now, before
1853 // the "real" header, so we build the built-in one first when building
1854 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001855 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001856 // FIXME: Taking the name from the FileEntry is unstable and can give
1857 // different results depending on how we've previously named that file
1858 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001859 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1860 Map.addHeader(ActiveModule, H, Role);
1861 }
Richard Smith25d50752014-10-20 00:15:49 +00001862
Richard Smith202210b2014-10-24 20:23:01 +00001863 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001864 Module::Header H = { RelativePathName.str(), File };
1865 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001866 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001867 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001868 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001869
1870 // If we find a module that has a missing header, we mark this module as
1871 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001872 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001873 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001874 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001875 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001876}
1877
Ben Langmuir41f81992015-08-13 17:30:07 +00001878static int compareModuleHeaders(const Module::Header *A,
1879 const Module::Header *B) {
1880 return A->NameAsWritten.compare(B->NameAsWritten);
1881}
1882
Douglas Gregor524e33e2011-12-08 19:11:24 +00001883/// \brief Parse an umbrella directory declaration.
1884///
1885/// umbrella-dir-declaration:
1886/// umbrella string-literal
1887void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1888 // Parse the directory name.
1889 if (!Tok.is(MMToken::StringLiteral)) {
1890 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1891 << "umbrella";
1892 HadError = true;
1893 return;
1894 }
1895
1896 std::string DirName = Tok.getString();
1897 SourceLocation DirNameLoc = consumeToken();
1898
1899 // Check whether we already have an umbrella.
1900 if (ActiveModule->Umbrella) {
1901 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1902 << ActiveModule->getFullModuleName();
1903 HadError = true;
1904 return;
1905 }
1906
1907 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001908 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001909 if (llvm::sys::path::is_absolute(DirName))
1910 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1911 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001912 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001913 PathName = Directory->getName();
1914 llvm::sys::path::append(PathName, DirName);
1915 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1916 }
1917
1918 if (!Dir) {
1919 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1920 << DirName;
1921 HadError = true;
1922 return;
1923 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001924
1925 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1926 // Mark this header 'textual' (see doc comment for
1927 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1928 // directory is relatively expensive, in practice this only applies to the
1929 // uncommonly used Tcl module on Darwin platforms.
1930 std::error_code EC;
1931 SmallVector<Module::Header, 6> Headers;
1932 for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E;
1933 I != E && !EC; I.increment(EC)) {
1934 if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
1935
1936 Module::Header Header = {I->path(), FE};
1937 Headers.push_back(std::move(Header));
1938 }
1939 }
1940
1941 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00001942 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1943
Ben Langmuir7ff29142015-08-13 17:13:33 +00001944 for (auto &Header : Headers)
1945 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1946 return;
1947 }
1948
Douglas Gregor524e33e2011-12-08 19:11:24 +00001949 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1950 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1951 << OwningModule->getFullModuleName();
1952 HadError = true;
1953 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001954 }
1955
Douglas Gregor524e33e2011-12-08 19:11:24 +00001956 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00001957 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001958}
1959
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001960/// \brief Parse a module export declaration.
1961///
1962/// export-declaration:
1963/// 'export' wildcard-module-id
1964///
1965/// wildcard-module-id:
1966/// identifier
1967/// '*'
1968/// identifier '.' wildcard-module-id
1969void ModuleMapParser::parseExportDecl() {
1970 assert(Tok.is(MMToken::ExportKeyword));
1971 SourceLocation ExportLoc = consumeToken();
1972
1973 // Parse the module-id with an optional wildcard at the end.
1974 ModuleId ParsedModuleId;
1975 bool Wildcard = false;
1976 do {
Richard Smith306d8922014-10-22 23:50:56 +00001977 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001978 if (Tok.is(MMToken::Identifier)) {
1979 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1980 Tok.getLocation()));
1981 consumeToken();
1982
1983 if (Tok.is(MMToken::Period)) {
1984 consumeToken();
1985 continue;
1986 }
1987
1988 break;
1989 }
1990
1991 if(Tok.is(MMToken::Star)) {
1992 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001993 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001994 break;
1995 }
1996
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001997 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001998 HadError = true;
1999 return;
2000 } while (true);
2001
2002 Module::UnresolvedExportDecl Unresolved = {
2003 ExportLoc, ParsedModuleId, Wildcard
2004 };
2005 ActiveModule->UnresolvedExports.push_back(Unresolved);
2006}
2007
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002008/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002009///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002010/// use-declaration:
2011/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002012void ModuleMapParser::parseUseDecl() {
2013 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002014 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002015 // Parse the module-id.
2016 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002017 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002018
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002019 if (ActiveModule->Parent)
2020 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2021 else
2022 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002023}
2024
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002025/// \brief Parse a link declaration.
2026///
2027/// module-declaration:
2028/// 'link' 'framework'[opt] string-literal
2029void ModuleMapParser::parseLinkDecl() {
2030 assert(Tok.is(MMToken::LinkKeyword));
2031 SourceLocation LinkLoc = consumeToken();
2032
2033 // Parse the optional 'framework' keyword.
2034 bool IsFramework = false;
2035 if (Tok.is(MMToken::FrameworkKeyword)) {
2036 consumeToken();
2037 IsFramework = true;
2038 }
2039
2040 // Parse the library name
2041 if (!Tok.is(MMToken::StringLiteral)) {
2042 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2043 << IsFramework << SourceRange(LinkLoc);
2044 HadError = true;
2045 return;
2046 }
2047
2048 std::string LibraryName = Tok.getString();
2049 consumeToken();
2050 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2051 IsFramework));
2052}
2053
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002054/// \brief Parse a configuration macro declaration.
2055///
2056/// module-declaration:
2057/// 'config_macros' attributes[opt] config-macro-list?
2058///
2059/// config-macro-list:
2060/// identifier (',' identifier)?
2061void ModuleMapParser::parseConfigMacros() {
2062 assert(Tok.is(MMToken::ConfigMacros));
2063 SourceLocation ConfigMacrosLoc = consumeToken();
2064
2065 // Only top-level modules can have configuration macros.
2066 if (ActiveModule->Parent) {
2067 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2068 }
2069
2070 // Parse the optional attributes.
2071 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002072 if (parseOptionalAttributes(Attrs))
2073 return;
2074
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002075 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2076 ActiveModule->ConfigMacrosExhaustive = true;
2077 }
2078
2079 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002080 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002081 if (!Tok.is(MMToken::Identifier))
2082 return;
2083
2084 // Consume the first identifier.
2085 if (!ActiveModule->Parent) {
2086 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2087 }
2088 consumeToken();
2089
2090 do {
2091 // If there's a comma, consume it.
2092 if (!Tok.is(MMToken::Comma))
2093 break;
2094 consumeToken();
2095
2096 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002097 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002098 if (!Tok.is(MMToken::Identifier)) {
2099 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2100 break;
2101 }
2102
2103 // Consume the macro name.
2104 if (!ActiveModule->Parent) {
2105 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2106 }
2107 consumeToken();
2108 } while (true);
2109}
2110
Douglas Gregorfb912652013-03-20 21:10:35 +00002111/// \brief Format a module-id into a string.
2112static std::string formatModuleId(const ModuleId &Id) {
2113 std::string result;
2114 {
2115 llvm::raw_string_ostream OS(result);
2116
2117 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2118 if (I)
2119 OS << ".";
2120 OS << Id[I].first;
2121 }
2122 }
2123
2124 return result;
2125}
2126
2127/// \brief Parse a conflict declaration.
2128///
2129/// module-declaration:
2130/// 'conflict' module-id ',' string-literal
2131void ModuleMapParser::parseConflict() {
2132 assert(Tok.is(MMToken::Conflict));
2133 SourceLocation ConflictLoc = consumeToken();
2134 Module::UnresolvedConflict Conflict;
2135
2136 // Parse the module-id.
2137 if (parseModuleId(Conflict.Id))
2138 return;
2139
2140 // Parse the ','.
2141 if (!Tok.is(MMToken::Comma)) {
2142 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2143 << SourceRange(ConflictLoc);
2144 return;
2145 }
2146 consumeToken();
2147
2148 // Parse the message.
2149 if (!Tok.is(MMToken::StringLiteral)) {
2150 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2151 << formatModuleId(Conflict.Id);
2152 return;
2153 }
2154 Conflict.Message = Tok.getString().str();
2155 consumeToken();
2156
2157 // Add this unresolved conflict.
2158 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2159}
2160
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002161/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002162///
2163/// module-declaration:
2164/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2165/// { inferred-module-member* }
2166///
2167/// inferred-module-member:
2168/// 'export' '*'
2169/// 'exclude' identifier
2170void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002171 assert(Tok.is(MMToken::Star));
2172 SourceLocation StarLoc = consumeToken();
2173 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002174
Douglas Gregor73441092011-12-05 22:27:44 +00002175 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002176 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002177 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2178 Failed = true;
2179 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002180
2181 if (ActiveModule) {
2182 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002183 if (!Failed && ActiveModule->IsAvailable &&
2184 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002185 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2186 Failed = true;
2187 }
2188
2189 // Check for redefinition of an inferred module.
2190 if (!Failed && ActiveModule->InferSubmodules) {
2191 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2192 if (ActiveModule->InferredSubmoduleLoc.isValid())
2193 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2194 diag::note_mmap_prev_definition);
2195 Failed = true;
2196 }
2197
2198 // Check for the 'framework' keyword, which is not permitted here.
2199 if (Framework) {
2200 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2201 Framework = false;
2202 }
2203 } else if (Explicit) {
2204 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2205 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002206 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002207
Douglas Gregor73441092011-12-05 22:27:44 +00002208 // If there were any problems with this inferred submodule, skip its body.
2209 if (Failed) {
2210 if (Tok.is(MMToken::LBrace)) {
2211 consumeToken();
2212 skipUntil(MMToken::RBrace);
2213 if (Tok.is(MMToken::RBrace))
2214 consumeToken();
2215 }
2216 HadError = true;
2217 return;
2218 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002219
2220 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002221 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002222 if (parseOptionalAttributes(Attrs))
2223 return;
Douglas Gregor9194a912012-11-06 19:39:40 +00002224
2225 if (ActiveModule) {
2226 // Note that we have an inferred submodule.
2227 ActiveModule->InferSubmodules = true;
2228 ActiveModule->InferredSubmoduleLoc = StarLoc;
2229 ActiveModule->InferExplicitSubmodules = Explicit;
2230 } else {
2231 // We'll be inferring framework modules for this directory.
2232 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002233 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002234 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002235 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002236 }
2237
Douglas Gregor73441092011-12-05 22:27:44 +00002238 // Parse the opening brace.
2239 if (!Tok.is(MMToken::LBrace)) {
2240 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2241 HadError = true;
2242 return;
2243 }
2244 SourceLocation LBraceLoc = consumeToken();
2245
2246 // Parse the body of the inferred submodule.
2247 bool Done = false;
2248 do {
2249 switch (Tok.Kind) {
2250 case MMToken::EndOfFile:
2251 case MMToken::RBrace:
2252 Done = true;
2253 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002254
2255 case MMToken::ExcludeKeyword: {
2256 if (ActiveModule) {
2257 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002258 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002259 consumeToken();
2260 break;
2261 }
2262
2263 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002264 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002265 if (!Tok.is(MMToken::Identifier)) {
2266 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2267 break;
2268 }
2269
2270 Map.InferredDirectories[Directory].ExcludedModules
2271 .push_back(Tok.getString());
2272 consumeToken();
2273 break;
2274 }
2275
2276 case MMToken::ExportKeyword:
2277 if (!ActiveModule) {
2278 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002279 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002280 consumeToken();
2281 break;
2282 }
2283
Douglas Gregor73441092011-12-05 22:27:44 +00002284 consumeToken();
2285 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002286 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002287 else
2288 Diags.Report(Tok.getLocation(),
2289 diag::err_mmap_expected_export_wildcard);
2290 consumeToken();
2291 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002292
Douglas Gregor73441092011-12-05 22:27:44 +00002293 case MMToken::ExplicitKeyword:
2294 case MMToken::ModuleKeyword:
2295 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002296 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002297 case MMToken::UmbrellaKeyword:
2298 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002299 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002300 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002301 consumeToken();
2302 break;
2303 }
2304 } while (!Done);
2305
2306 if (Tok.is(MMToken::RBrace))
2307 consumeToken();
2308 else {
2309 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2310 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2311 HadError = true;
2312 }
2313}
2314
Douglas Gregor9194a912012-11-06 19:39:40 +00002315/// \brief Parse optional attributes.
2316///
2317/// attributes:
2318/// attribute attributes
2319/// attribute
2320///
2321/// attribute:
2322/// [ identifier ]
2323///
2324/// \param Attrs Will be filled in with the parsed attributes.
2325///
2326/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002327bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002328 bool HadError = false;
2329
2330 while (Tok.is(MMToken::LSquare)) {
2331 // Consume the '['.
2332 SourceLocation LSquareLoc = consumeToken();
2333
2334 // Check whether we have an attribute name here.
2335 if (!Tok.is(MMToken::Identifier)) {
2336 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2337 skipUntil(MMToken::RSquare);
2338 if (Tok.is(MMToken::RSquare))
2339 consumeToken();
2340 HadError = true;
2341 }
2342
2343 // Decode the attribute name.
2344 AttributeKind Attribute
2345 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002346 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002347 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002348 .Case("system", AT_system)
2349 .Default(AT_unknown);
2350 switch (Attribute) {
2351 case AT_unknown:
2352 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2353 << Tok.getString();
2354 break;
2355
2356 case AT_system:
2357 Attrs.IsSystem = true;
2358 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002359
Richard Smith77944862014-03-02 05:58:18 +00002360 case AT_extern_c:
2361 Attrs.IsExternC = true;
2362 break;
2363
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002364 case AT_exhaustive:
2365 Attrs.IsExhaustive = true;
2366 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002367 }
2368 consumeToken();
2369
2370 // Consume the ']'.
2371 if (!Tok.is(MMToken::RSquare)) {
2372 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2373 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2374 skipUntil(MMToken::RSquare);
2375 HadError = true;
2376 }
2377
2378 if (Tok.is(MMToken::RSquare))
2379 consumeToken();
2380 }
2381
2382 return HadError;
2383}
2384
Douglas Gregor718292f2011-11-11 19:10:28 +00002385/// \brief Parse a module map file.
2386///
2387/// module-map-file:
2388/// module-declaration*
2389bool ModuleMapParser::parseModuleMapFile() {
2390 do {
2391 switch (Tok.Kind) {
2392 case MMToken::EndOfFile:
2393 return HadError;
2394
Douglas Gregore7ab3662011-12-07 02:23:45 +00002395 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002396 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002397 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002398 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002399 parseModuleDecl();
2400 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002401
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002402 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002403 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002404 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002405 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002406 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002407 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002408 case MMToken::HeaderKeyword:
2409 case MMToken::Identifier:
2410 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002411 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002412 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002413 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002414 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002415 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002416 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002417 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002418 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002419 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002420 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002421 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002422 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2424 HadError = true;
2425 consumeToken();
2426 break;
2427 }
2428 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002429}
2430
Richard Smith9acb99e32014-12-10 03:09:48 +00002431bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smithae6df272015-07-14 02:06:01 +00002432 const DirectoryEntry *Dir,
2433 SourceLocation ExternModuleLoc) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002434 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2435 = ParsedModuleMap.find(File);
2436 if (Known != ParsedModuleMap.end())
2437 return Known->second;
2438
Craig Topperd2d442c2014-05-17 23:10:59 +00002439 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002440 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
Richard Smithae6df272015-07-14 02:06:01 +00002441 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002442 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002443 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002444 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002445
Douglas Gregor718292f2011-11-11 19:10:28 +00002446 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002447 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Richard Smith2a6edb32015-08-09 04:46:57 +00002448 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002449 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002450 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002451 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002452 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002453
2454 // Notify callbacks that we parsed it.
2455 for (const auto &Cb : Callbacks)
2456 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002457 return Result;
2458}