blob: 1134cce84f97b6207fa62da24dcba13b76c1a089 [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 Smith0414b852015-02-14 05:32:00 +000092 CompilingModule(nullptr), SourceModule(nullptr) {
93 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);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000168 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
169 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
170 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000171 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000172 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000173 return Known;
174}
175
Ben Langmuir44691382014-04-10 00:39:10 +0000176ModuleMap::KnownHeader
177ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
178 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
179 const DirectoryEntry *Dir = File->getDir();
180 assert(Dir && "file in no directory");
181
182 // Note: as an egregious but useful hack we use the real path here, because
183 // frameworks moving from top-level frameworks to embedded frameworks tend
184 // to be symlinked from the top-level location to the embedded location,
185 // and we need to resolve lookups as if we had found the embedded location.
186 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
187
188 // Keep walking up the directory hierarchy, looking for a directory with
189 // an umbrella header.
190 do {
191 auto KnownDir = UmbrellaDirs.find(Dir);
192 if (KnownDir != UmbrellaDirs.end())
193 return KnownHeader(KnownDir->second, NormalHeader);
194
195 IntermediateDirs.push_back(Dir);
196
197 // Retrieve our parent path.
198 DirName = llvm::sys::path::parent_path(DirName);
199 if (DirName.empty())
200 break;
201
202 // Resolve the parent path to a directory entry.
203 Dir = SourceMgr.getFileManager().getDirectory(DirName);
204 } while (Dir);
205 return KnownHeader();
206}
207
Richard Smith202210b2014-10-24 20:23:01 +0000208// Returns true if RequestingModule directly uses RequestedModule.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000209static bool directlyUses(const Module *RequestingModule,
210 const Module *RequestedModule) {
Daniel Jasperb6ba46e2015-03-13 11:26:16 +0000211 for (const Module* DirectUse : RequestingModule->DirectUses) {
212 if (RequestedModule->isSubModuleOf(DirectUse))
213 return true;
214 }
215 return false;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000216}
217
218static bool violatesPrivateInclude(Module *RequestingModule,
219 const FileEntry *IncFileEnt,
220 ModuleMap::ModuleHeaderRole Role,
221 Module *RequestedModule) {
Richard Smith202210b2014-10-24 20:23:01 +0000222 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
223#ifndef NDEBUG
Richard Smith2708e522015-03-10 00:19:04 +0000224 if (IsPrivateRole) {
225 // Check for consistency between the module header role
226 // as obtained from the lookup and as obtained from the module.
227 // This check is not cheap, so enable it only for debugging.
228 bool IsPrivate = false;
229 SmallVectorImpl<Module::Header> *HeaderList[] = {
230 &RequestedModule->Headers[Module::HK_Private],
231 &RequestedModule->Headers[Module::HK_PrivateTextual]};
232 for (auto *Hs : HeaderList)
233 IsPrivate |=
234 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000235 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000236 }) != Hs->end();
237 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
238 }
Richard Smith202210b2014-10-24 20:23:01 +0000239#endif
240 return IsPrivateRole &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000241 RequestedModule->getTopLevelModule() != RequestingModule;
242}
243
Ben Langmuir71e1a642014-05-05 21:44:13 +0000244static Module *getTopLevelOrNull(Module *M) {
245 return M ? M->getTopLevelModule() : nullptr;
246}
247
Daniel Jasper92669ee2013-12-20 12:09:36 +0000248void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
249 SourceLocation FilenameLoc,
250 StringRef Filename,
251 const FileEntry *File) {
252 // No errors for indirect modules. This may be a bit of a problem for modules
253 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000254 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000255 return;
256
257 if (RequestingModule)
258 resolveUses(RequestingModule, /*Complain=*/false);
259
Ben Langmuir71e1a642014-05-05 21:44:13 +0000260 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000261 Module *Private = nullptr;
262 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000263
Ben Langmuir71e1a642014-05-05 21:44:13 +0000264 HeadersMap::iterator Known = findKnownHeader(File);
265 if (Known != Headers.end()) {
266 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000267 // If 'File' is part of 'RequestingModule' we can definitely include it.
Daniel Jasper0ab544f2015-03-13 14:29:39 +0000268 if (Header.getModule() &&
269 Header.getModule()->isSubModuleOf(RequestingModule))
Ben Langmuir71e1a642014-05-05 21:44:13 +0000270 return;
271
272 // Remember private headers for later printing of a diagnostic.
273 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
274 Header.getModule())) {
275 Private = Header.getModule();
276 continue;
277 }
278
279 // If uses need to be specified explicitly, we are only allowed to return
280 // modules that are explicitly used by the requesting module.
281 if (RequestingModule && LangOpts.ModulesDeclUse &&
282 !directlyUses(RequestingModule, Header.getModule())) {
283 NotUsed = Header.getModule();
284 continue;
285 }
286
287 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000288 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000289 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000290
291 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000292 }
293
294 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000295 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000296 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000297 << Filename;
298 return;
299 }
300
301 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000302 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000303 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000304 << RequestingModule->getFullModuleName() << Filename;
305 return;
306 }
307
Ben Langmuir71e1a642014-05-05 21:44:13 +0000308 if (Excluded || isHeaderInUmbrellaDirs(File))
309 return;
310
311 // At this point, only non-modular includes remain.
312
313 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000314 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000315 << RequestingModule->getFullModuleName() << Filename;
316 } else if (RequestingModule) {
317 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
318 diag::warn_non_modular_include_in_framework_module :
319 diag::warn_non_modular_include_in_module;
320 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000321 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000322}
323
Richard Smithec87a502015-02-13 23:50:20 +0000324static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
325 const ModuleMap::KnownHeader &Old) {
326 // Prefer a public header over a private header.
327 if ((New.getRole() & ModuleMap::PrivateHeader) !=
328 (Old.getRole() & ModuleMap::PrivateHeader))
329 return !(New.getRole() & ModuleMap::PrivateHeader);
330
331 // Prefer a non-textual header over a textual header.
332 if ((New.getRole() & ModuleMap::TextualHeader) !=
333 (Old.getRole() & ModuleMap::TextualHeader))
334 return !(New.getRole() & ModuleMap::TextualHeader);
335
336 // Don't have a reason to choose between these. Just keep the first one.
337 return false;
338}
339
Daniel Jasper92669ee2013-12-20 12:09:36 +0000340ModuleMap::KnownHeader
341ModuleMap::findModuleForHeader(const FileEntry *File,
Richard Smith306d8922014-10-22 23:50:56 +0000342 Module *RequestingModule,
343 bool IncludeTextualHeaders) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000344 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000345
Richard Smith306d8922014-10-22 23:50:56 +0000346 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Richard Smith202210b2014-10-24 20:23:01 +0000347 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
Richard Smith306d8922014-10-22 23:50:56 +0000348 return ModuleMap::KnownHeader();
349 return R;
350 };
351
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000352 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000353 ModuleMap::KnownHeader Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000354
Daniel Jasper97da9172013-10-22 08:09:47 +0000355 // Iterate over all modules that 'File' is part of to find the best fit.
356 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
357 E = Known->second.end();
358 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000359 // Cannot use a module if it is unavailable.
360 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000361 continue;
362
363 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
364 // module we are looking for.
365 if (I->getModule() == RequestingModule)
Richard Smith306d8922014-10-22 23:50:56 +0000366 return MakeResult(*I);
Daniel Jasper97da9172013-10-22 08:09:47 +0000367
368 // If uses need to be specified explicitly, we are only allowed to return
369 // modules that are explicitly used by the requesting module.
370 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000371 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000372 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000373
Richard Smithec87a502015-02-13 23:50:20 +0000374 if (!Result || isBetterKnownHeader(*I, Result))
Richard Smith202210b2014-10-24 20:23:01 +0000375 Result = *I;
Daniel Jasper97da9172013-10-22 08:09:47 +0000376 }
Richard Smith306d8922014-10-22 23:50:56 +0000377 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000378 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000379
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000380 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000381 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
382 if (H) {
383 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000384
Ben Langmuir44691382014-04-10 00:39:10 +0000385 // Search up the module stack until we find a module with an umbrella
386 // directory.
387 Module *UmbrellaModule = Result;
388 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
389 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000390
Ben Langmuir44691382014-04-10 00:39:10 +0000391 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000392 const FileEntry *UmbrellaModuleMap =
393 getModuleMapFileForUniquing(UmbrellaModule);
394
Ben Langmuir44691382014-04-10 00:39:10 +0000395 // Infer submodules for each of the directories we found between
396 // the directory of the umbrella header and the directory where
397 // the actual header is located.
398 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000399
Ben Langmuir44691382014-04-10 00:39:10 +0000400 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
401 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000402 SmallString<32> NameBuf;
403 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000404 llvm::sys::path::stem(SkippedDirs[I-1]->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
410 // Associate the module and the directory.
411 UmbrellaDirs[SkippedDirs[I-1]] = Result;
412
413 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000414 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000415 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000416 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000417 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000418
Ben Langmuir44691382014-04-10 00:39:10 +0000419 // Infer a submodule with the same name as this header file.
420 SmallString<32> NameBuf;
421 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000422 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000423 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
424 Explicit).first;
425 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000426 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000427 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000428
Ben Langmuir44691382014-04-10 00:39:10 +0000429 // If inferred submodules export everything they import, add a
430 // wildcard to the set of exports.
431 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000432 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000433 } else {
434 // Record each of the directories we stepped through as being part of
435 // the module we found, since the umbrella header covers them all.
436 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
437 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000438 }
Ben Langmuir44691382014-04-10 00:39:10 +0000439
440 Headers[File].push_back(KnownHeader(Result, NormalHeader));
441
442 // If a header corresponds to an unavailable module, don't report
443 // that it maps to anything.
444 if (!Result->isAvailable())
445 return KnownHeader();
446
Richard Smith306d8922014-10-22 23:50:56 +0000447 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000448 }
Richard Smith306d8922014-10-22 23:50:56 +0000449
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000450 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000451}
452
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000453bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000454 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000455}
456
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000457bool
458ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
459 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000460 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000461 if (Known != Headers.end()) {
462 for (SmallVectorImpl<KnownHeader>::const_iterator
463 I = Known->second.begin(),
464 E = Known->second.end();
465 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000466 if (I->isAvailable() && (!RequestingModule ||
467 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000468 return false;
469 }
470 return true;
471 }
Richard Smith50996ce2014-04-08 13:13:04 +0000472
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000473 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000474 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000475 StringRef DirName = Dir->getName();
476
Richard Smith50996ce2014-04-08 13:13:04 +0000477 auto IsUnavailable = [&](const Module *M) {
478 return !M->isAvailable() && (!RequestingModule ||
479 M->isSubModuleOf(RequestingModule));
480 };
481
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000482 // Keep walking up the directory hierarchy, looking for a directory with
483 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000484 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000485 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000486 = UmbrellaDirs.find(Dir);
487 if (KnownDir != UmbrellaDirs.end()) {
488 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000489 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 return true;
491
492 // Search up the module stack until we find a module with an umbrella
493 // directory.
494 Module *UmbrellaModule = Found;
495 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
496 UmbrellaModule = UmbrellaModule->Parent;
497
498 if (UmbrellaModule->InferSubmodules) {
499 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
500 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000501 SmallString<32> NameBuf;
502 StringRef Name = sanitizeFilenameAsIdentifier(
503 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
504 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000505 Found = lookupModuleQualified(Name, Found);
506 if (!Found)
507 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000508 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000509 return true;
510 }
511
512 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000513 SmallString<32> NameBuf;
514 StringRef Name = sanitizeFilenameAsIdentifier(
515 llvm::sys::path::stem(Header->getName()),
516 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000517 Found = lookupModuleQualified(Name, Found);
518 if (!Found)
519 return false;
520 }
521
Richard Smith50996ce2014-04-08 13:13:04 +0000522 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000523 }
524
525 SkippedDirs.push_back(Dir);
526
527 // Retrieve our parent path.
528 DirName = llvm::sys::path::parent_path(DirName);
529 if (DirName.empty())
530 break;
531
532 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000533 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000534 } while (Dir);
535
536 return false;
537}
538
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000539Module *ModuleMap::findModule(StringRef Name) const {
540 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000541 if (Known != Modules.end())
542 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000543
544 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000545}
546
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000547Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
548 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000549 for(; Context; Context = Context->Parent) {
550 if (Module *Sub = lookupModuleQualified(Name, Context))
551 return Sub;
552 }
553
554 return findModule(Name);
555}
556
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000557Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000558 if (!Context)
559 return findModule(Name);
560
Douglas Gregoreb90e832012-01-04 23:32:19 +0000561 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000562}
563
Douglas Gregorde3ef502011-11-30 23:21:26 +0000564std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000565ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000566 bool IsExplicit) {
567 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000568 if (Module *Sub = lookupModuleQualified(Name, Parent))
569 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000570
571 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000572 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000573 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000574 if (LangOpts.CurrentModule == Name) {
575 SourceModule = Result;
576 SourceModuleName = Name;
577 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000578 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000579 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000580 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
581 Name == LangOpts.CurrentModule) {
582 CompilingModule = Result;
583 }
584 }
Douglas Gregor69021972011-11-30 17:33:56 +0000585 return std::make_pair(Result, true);
586}
587
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000588/// \brief For a framework module, infer the framework against which we
589/// should link.
590static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
591 FileManager &FileMgr) {
592 assert(Mod->IsFramework && "Can only infer linking for framework modules");
593 assert(!Mod->isSubFramework() &&
594 "Can only infer linking for top-level frameworks");
595
596 SmallString<128> LibName;
597 LibName += FrameworkDir->getName();
598 llvm::sys::path::append(LibName, Mod->Name);
599 if (FileMgr.getFile(LibName)) {
600 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
601 /*IsFramework=*/true));
602 }
603}
604
Douglas Gregorde3ef502011-11-30 23:21:26 +0000605Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000606ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000607 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000608 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000609 Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000610 Attributes Attrs;
611 Attrs.IsSystem = IsSystem;
612 return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
613}
614
615Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
616 const DirectoryEntry *FrameworkDir,
617 Attributes Attrs, Module *Parent) {
618
Douglas Gregor56c64012011-11-17 01:41:17 +0000619 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000620 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
621 return Mod;
622
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000623 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000624
625 // If the framework has a parent path from which we're allowed to infer
626 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000627 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000628 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000629 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000630
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000631 // Note: as an egregious but useful hack we use the real path here, because
632 // we might be looking at an embedded framework that symlinks out to a
633 // top-level framework, and we need to infer as if we were naming the
634 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000635 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000636 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000637
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000638 // In case this is a case-insensitive filesystem, make sure the canonical
639 // directory name matches ModuleName exactly. Modules are case-sensitive.
640 // FIXME: we should be able to give a fix-it hint for the correct spelling.
641 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
642 return nullptr;
643
Douglas Gregor9194a912012-11-06 19:39:40 +0000644 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000645 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000646 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000647 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000648 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
649 // Check whether we have already looked into the parent directory
650 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000651 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000652 inferred = InferredDirectories.find(ParentDir);
653 if (inferred == InferredDirectories.end()) {
654 // We haven't looked here before. Load a module map, if there is
655 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000656 bool IsFrameworkDir = Parent.endswith(".framework");
657 if (const FileEntry *ModMapFile =
658 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000659 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000660 inferred = InferredDirectories.find(ParentDir);
661 }
662
663 if (inferred == InferredDirectories.end())
664 inferred = InferredDirectories.insert(
665 std::make_pair(ParentDir, InferredDirectory())).first;
666 }
667
668 if (inferred->second.InferModules) {
669 // We're allowed to infer for this directory, but make sure it's okay
670 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000671 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000672 canInfer = std::find(inferred->second.ExcludedModules.begin(),
673 inferred->second.ExcludedModules.end(),
674 Name) == inferred->second.ExcludedModules.end();
675
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000676 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
677 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
678 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000679 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000680 }
681 }
682 }
683
684 // If we're not allowed to infer a framework module, don't.
685 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000686 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000687 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000688 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000689
690
Douglas Gregor56c64012011-11-17 01:41:17 +0000691 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000692 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000693 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000694 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000695
696 // FIXME: If there's no umbrella header, we could probably scan the
697 // framework to load *everything*. But, it's not clear that this is a good
698 // idea.
699 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000700 return nullptr;
701
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000702 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000703 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000704 InferredModuleAllowedBy[Result] = ModuleMapFile;
705 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000706 if (LangOpts.CurrentModule == ModuleName) {
707 SourceModule = Result;
708 SourceModuleName = ModuleName;
709 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000710
711 Result->IsSystem |= Attrs.IsSystem;
712 Result->IsExternC |= Attrs.IsExternC;
713 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
714
Douglas Gregoreb90e832012-01-04 23:32:19 +0000715 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000716 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000717
Douglas Gregor322f6332011-12-08 18:00:48 +0000718 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000719 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000720 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000721 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000722
723 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000724 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
725
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000726 // module * { export * }
727 Result->InferSubmodules = true;
728 Result->InferExportWildcard = true;
729
Douglas Gregore89dbc12011-12-06 19:39:29 +0000730 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000731 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000732 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000733 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000734 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000735 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000736 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000737 Dir != DirEnd && !EC; Dir.increment(EC)) {
738 if (!StringRef(Dir->path()).endswith(".framework"))
739 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000740
Douglas Gregore89dbc12011-12-06 19:39:29 +0000741 if (const DirectoryEntry *SubframeworkDir
742 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000743 // Note: as an egregious but useful hack, we use the real path here and
744 // check whether it is actually a subdirectory of the parent directory.
745 // This will not be the case if the 'subframework' is actually a symlink
746 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000747 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
748 bool FoundParent = false;
749 do {
750 // Get the parent directory name.
751 SubframeworkDirName
752 = llvm::sys::path::parent_path(SubframeworkDirName);
753 if (SubframeworkDirName.empty())
754 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000755
Douglas Gregore00c8b22013-01-26 00:55:12 +0000756 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
757 FoundParent = true;
758 break;
759 }
760 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000761
Douglas Gregore00c8b22013-01-26 00:55:12 +0000762 if (!FoundParent)
763 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000764
Douglas Gregore89dbc12011-12-06 19:39:29 +0000765 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000766 SmallString<32> NameBuf;
767 inferFrameworkModule(sanitizeFilenameAsIdentifier(
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000768 llvm::sys::path::stem(Dir->path()), NameBuf),
769 SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000770 }
771 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000772
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000773 // If the module is a top-level framework, automatically link against the
774 // framework.
775 if (!Result->isSubFramework()) {
776 inferFrameworkLink(Result, FrameworkDir, FileMgr);
777 }
778
Douglas Gregor56c64012011-11-17 01:41:17 +0000779 return Result;
780}
781
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000782void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000783 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000784 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000785 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000786}
787
Douglas Gregor524e33e2011-12-08 19:11:24 +0000788void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
789 Mod->Umbrella = UmbrellaDir;
790 UmbrellaDirs[UmbrellaDir] = Mod;
791}
792
Richard Smith3c1a41a2014-12-02 00:08:08 +0000793static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000794 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000795 default: llvm_unreachable("unknown header role");
796 case ModuleMap::NormalHeader:
797 return Module::HK_Normal;
798 case ModuleMap::PrivateHeader:
799 return Module::HK_Private;
800 case ModuleMap::TextualHeader:
801 return Module::HK_Textual;
802 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
803 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000804 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000805}
806
Richard Smith3c1a41a2014-12-02 00:08:08 +0000807void ModuleMap::addHeader(Module *Mod, Module::Header Header,
808 ModuleHeaderRole Role) {
809 if (!(Role & TextualHeader)) {
810 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
811 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
812 isCompilingModuleHeader);
813 }
814 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
Richard Smithfeb54b62014-10-23 02:01:19 +0000815
Richard Smith3c1a41a2014-12-02 00:08:08 +0000816 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
817}
818
819void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000820 // Add this as a known header so we won't implicitly add it to any
821 // umbrella directory module.
822 // FIXME: Should we only exclude it from umbrella modules within the
823 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000824 (void) Headers[Header.Entry];
825
826 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000827}
828
Douglas Gregor514b6362011-11-29 19:06:37 +0000829const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000830ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000831 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000832 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000833
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000834 return SourceMgr.getFileEntryForID(
835 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000836}
837
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000838const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000839 if (M->IsInferred) {
840 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
841 return InferredModuleAllowedBy.find(M)->second;
842 }
843 return getContainingModuleMapFile(M);
844}
845
846void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
847 assert(M->IsInferred && "module not inferred");
848 InferredModuleAllowedBy[M] = ModMap;
849}
850
Douglas Gregor718292f2011-11-11 19:10:28 +0000851void ModuleMap::dump() {
852 llvm::errs() << "Modules:";
853 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
854 MEnd = Modules.end();
855 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000856 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000857
858 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000859 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000860 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000861 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
862 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
863 E = H->second.end();
864 I != E; ++I) {
865 if (I != H->second.begin())
866 llvm::errs() << ",";
867 llvm::errs() << I->getModule()->getFullModuleName();
868 }
869 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000870 }
871}
872
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000873bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
874 bool HadError = false;
875 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
876 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
877 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000878 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000879 Mod->Exports.push_back(Export);
880 else
881 HadError = true;
882 }
883 Mod->UnresolvedExports.clear();
884 return HadError;
885}
886
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000887bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
888 bool HadError = false;
889 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
890 Module *DirectUse =
891 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
892 if (DirectUse)
893 Mod->DirectUses.push_back(DirectUse);
894 else
895 HadError = true;
896 }
897 Mod->UnresolvedDirectUses.clear();
898 return HadError;
899}
900
Douglas Gregorfb912652013-03-20 21:10:35 +0000901bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
902 bool HadError = false;
903 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
904 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
905 Mod, Complain);
906 if (!OtherMod) {
907 HadError = true;
908 continue;
909 }
910
911 Module::Conflict Conflict;
912 Conflict.Other = OtherMod;
913 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
914 Mod->Conflicts.push_back(Conflict);
915 }
916 Mod->UnresolvedConflicts.clear();
917 return HadError;
918}
919
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000920Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
921 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000922 return nullptr;
923
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000924 // Use the expansion location to determine which module we're in.
925 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
926 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000927 return nullptr;
928
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000929 const SourceManager &SrcMgr = Loc.getManager();
930 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000931
Douglas Gregor224d8a72012-01-06 17:19:32 +0000932 while (const FileEntry *ExpansionFile
933 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
934 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000935 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000936 return Mod;
937
938 // No module owns this header, so look up the inclusion chain to see if
939 // any included header has an associated module.
940 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
941 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000942 return nullptr;
943
Douglas Gregor224d8a72012-01-06 17:19:32 +0000944 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
945 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000946
947 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000948}
949
Douglas Gregor718292f2011-11-11 19:10:28 +0000950//----------------------------------------------------------------------------//
951// Module map file parser
952//----------------------------------------------------------------------------//
953
954namespace clang {
955 /// \brief A token in a module map file.
956 struct MMToken {
957 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000958 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000959 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000960 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000961 EndOfFile,
962 HeaderKeyword,
963 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000964 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000965 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000966 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000967 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000968 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000969 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000970 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000971 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000972 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000973 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000974 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000975 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000976 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000977 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000978 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000979 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000980 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000981 RBrace,
982 LSquare,
983 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000984 } Kind;
985
986 unsigned Location;
987 unsigned StringLength;
988 const char *StringData;
989
990 void clear() {
991 Kind = EndOfFile;
992 Location = 0;
993 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000994 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000995 }
996
997 bool is(TokenKind K) const { return Kind == K; }
998
999 SourceLocation getLocation() const {
1000 return SourceLocation::getFromRawEncoding(Location);
1001 }
1002
1003 StringRef getString() const {
1004 return StringRef(StringData, StringLength);
1005 }
1006 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001007
Douglas Gregor718292f2011-11-11 19:10:28 +00001008 class ModuleMapParser {
1009 Lexer &L;
1010 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001011
1012 /// \brief Default target information, used only for string literal
1013 /// parsing.
1014 const TargetInfo *Target;
1015
Douglas Gregor718292f2011-11-11 19:10:28 +00001016 DiagnosticsEngine &Diags;
1017 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001018
1019 /// \brief The current module map file.
1020 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001021
Richard Smith9acb99e32014-12-10 03:09:48 +00001022 /// \brief The directory that file names in this module map file should
1023 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001024 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001025
1026 /// \brief The directory containing Clang-supplied headers.
1027 const DirectoryEntry *BuiltinIncludeDir;
1028
Douglas Gregor963c5532013-06-21 16:28:10 +00001029 /// \brief Whether this module map is in a system header directory.
1030 bool IsSystem;
1031
Douglas Gregor718292f2011-11-11 19:10:28 +00001032 /// \brief Whether an error occurred.
1033 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001034
Douglas Gregor718292f2011-11-11 19:10:28 +00001035 /// \brief Stores string data for the various string literals referenced
1036 /// during parsing.
1037 llvm::BumpPtrAllocator StringData;
1038
1039 /// \brief The current token.
1040 MMToken Tok;
1041
1042 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001043 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001044
1045 /// \brief Consume the current token and return its location.
1046 SourceLocation consumeToken();
1047
1048 /// \brief Skip tokens until we reach the a token with the given kind
1049 /// (or the end of the file).
1050 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001051
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001052 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001053 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001054 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001055 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001056 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001057 void parseHeaderDecl(clang::MMToken::TokenKind,
1058 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001059 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001060 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001061 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001062 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001063 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001064 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001065 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001066
1067 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001068 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001069
Douglas Gregor718292f2011-11-11 19:10:28 +00001070 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001071 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001072 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001073 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001074 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001075 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001076 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001077 const DirectoryEntry *BuiltinIncludeDir,
1078 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001079 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001080 ModuleMapFile(ModuleMapFile), Directory(Directory),
1081 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001082 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001084 Tok.clear();
1085 consumeToken();
1086 }
1087
1088 bool parseModuleMapFile();
1089 };
1090}
1091
1092SourceLocation ModuleMapParser::consumeToken() {
1093retry:
1094 SourceLocation Result = Tok.getLocation();
1095 Tok.clear();
1096
1097 Token LToken;
1098 L.LexFromRawLexer(LToken);
1099 Tok.Location = LToken.getLocation().getRawEncoding();
1100 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001101 case tok::raw_identifier: {
1102 StringRef RI = LToken.getRawIdentifier();
1103 Tok.StringData = RI.data();
1104 Tok.StringLength = RI.size();
1105 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001106 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001107 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001108 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001109 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001110 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001111 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001112 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001113 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001114 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001115 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001116 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001117 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001118 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001119 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001120 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001121 .Default(MMToken::Identifier);
1122 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001123 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001124
1125 case tok::comma:
1126 Tok.Kind = MMToken::Comma;
1127 break;
1128
Douglas Gregor718292f2011-11-11 19:10:28 +00001129 case tok::eof:
1130 Tok.Kind = MMToken::EndOfFile;
1131 break;
1132
1133 case tok::l_brace:
1134 Tok.Kind = MMToken::LBrace;
1135 break;
1136
Douglas Gregora686e1b2012-01-27 19:52:33 +00001137 case tok::l_square:
1138 Tok.Kind = MMToken::LSquare;
1139 break;
1140
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001141 case tok::period:
1142 Tok.Kind = MMToken::Period;
1143 break;
1144
Douglas Gregor718292f2011-11-11 19:10:28 +00001145 case tok::r_brace:
1146 Tok.Kind = MMToken::RBrace;
1147 break;
1148
Douglas Gregora686e1b2012-01-27 19:52:33 +00001149 case tok::r_square:
1150 Tok.Kind = MMToken::RSquare;
1151 break;
1152
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001153 case tok::star:
1154 Tok.Kind = MMToken::Star;
1155 break;
1156
Richard Smitha3feee22013-10-28 22:18:19 +00001157 case tok::exclaim:
1158 Tok.Kind = MMToken::Exclaim;
1159 break;
1160
Douglas Gregor718292f2011-11-11 19:10:28 +00001161 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001162 if (LToken.hasUDSuffix()) {
1163 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1164 HadError = true;
1165 goto retry;
1166 }
1167
Douglas Gregor718292f2011-11-11 19:10:28 +00001168 // Parse the string literal.
1169 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001170 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001171 if (StringLiteral.hadError)
1172 goto retry;
1173
1174 // Copy the string literal into our string data allocator.
1175 unsigned Length = StringLiteral.GetStringLength();
1176 char *Saved = StringData.Allocate<char>(Length + 1);
1177 memcpy(Saved, StringLiteral.GetString().data(), Length);
1178 Saved[Length] = 0;
1179
1180 // Form the token.
1181 Tok.Kind = MMToken::StringLiteral;
1182 Tok.StringData = Saved;
1183 Tok.StringLength = Length;
1184 break;
1185 }
1186
1187 case tok::comment:
1188 goto retry;
1189
1190 default:
1191 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1192 HadError = true;
1193 goto retry;
1194 }
1195
1196 return Result;
1197}
1198
1199void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1200 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001201 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001202 do {
1203 switch (Tok.Kind) {
1204 case MMToken::EndOfFile:
1205 return;
1206
1207 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001208 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001209 return;
1210
1211 ++braceDepth;
1212 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001213
1214 case MMToken::LSquare:
1215 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1216 return;
1217
1218 ++squareDepth;
1219 break;
1220
Douglas Gregor718292f2011-11-11 19:10:28 +00001221 case MMToken::RBrace:
1222 if (braceDepth > 0)
1223 --braceDepth;
1224 else if (Tok.is(K))
1225 return;
1226 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001227
1228 case MMToken::RSquare:
1229 if (squareDepth > 0)
1230 --squareDepth;
1231 else if (Tok.is(K))
1232 return;
1233 break;
1234
Douglas Gregor718292f2011-11-11 19:10:28 +00001235 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001236 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 return;
1238 break;
1239 }
1240
1241 consumeToken();
1242 } while (true);
1243}
1244
Douglas Gregore7ab3662011-12-07 02:23:45 +00001245/// \brief Parse a module-id.
1246///
1247/// module-id:
1248/// identifier
1249/// identifier '.' module-id
1250///
1251/// \returns true if an error occurred, false otherwise.
1252bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1253 Id.clear();
1254 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001255 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001256 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1257 consumeToken();
1258 } else {
1259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1260 return true;
1261 }
1262
1263 if (!Tok.is(MMToken::Period))
1264 break;
1265
1266 consumeToken();
1267 } while (true);
1268
1269 return false;
1270}
1271
Douglas Gregora686e1b2012-01-27 19:52:33 +00001272namespace {
1273 /// \brief Enumerates the known attributes.
1274 enum AttributeKind {
1275 /// \brief An unknown attribute.
1276 AT_unknown,
1277 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001278 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001279 /// \brief The 'extern_c' attribute.
1280 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001281 /// \brief The 'exhaustive' attribute.
1282 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001283 };
1284}
1285
Douglas Gregor718292f2011-11-11 19:10:28 +00001286/// \brief Parse a module declaration.
1287///
1288/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001289/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001290/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1291/// { module-member* }
1292///
Douglas Gregor718292f2011-11-11 19:10:28 +00001293/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001294/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001295/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001296/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001297/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001298/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001299///
1300/// submodule-declaration:
1301/// module-declaration
1302/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001303void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001304 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001305 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1306 if (Tok.is(MMToken::ExternKeyword)) {
1307 parseExternModuleDecl();
1308 return;
1309 }
1310
Douglas Gregorf2161a72011-12-06 17:16:41 +00001311 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001312 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001313 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001314 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001315
Douglas Gregorf2161a72011-12-06 17:16:41 +00001316 // Parse 'explicit' keyword, if present.
1317 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001318 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001319 Explicit = true;
1320 }
1321
1322 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001323 if (Tok.is(MMToken::FrameworkKeyword)) {
1324 consumeToken();
1325 Framework = true;
1326 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001327
1328 // Parse 'module' keyword.
1329 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001330 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001331 consumeToken();
1332 HadError = true;
1333 return;
1334 }
1335 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001336
1337 // If we have a wildcard for the module name, this is an inferred submodule.
1338 // Parse it.
1339 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001340 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001341
1342 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001343 ModuleId Id;
1344 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001345 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001346 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001347 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001348
Douglas Gregore7ab3662011-12-07 02:23:45 +00001349 if (ActiveModule) {
1350 if (Id.size() > 1) {
1351 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1352 << SourceRange(Id.front().second, Id.back().second);
1353
1354 HadError = true;
1355 return;
1356 }
1357 } else if (Id.size() == 1 && Explicit) {
1358 // Top-level modules can't be explicit.
1359 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1360 Explicit = false;
1361 ExplicitLoc = SourceLocation();
1362 HadError = true;
1363 }
1364
1365 Module *PreviousActiveModule = ActiveModule;
1366 if (Id.size() > 1) {
1367 // This module map defines a submodule. Go find the module of which it
1368 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001369 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001370 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001371 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1372 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001373 if (I == 0)
1374 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001375 ActiveModule = Next;
1376 continue;
1377 }
1378
1379 if (ActiveModule) {
1380 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001381 << Id[I].first
1382 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001383 } else {
1384 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1385 }
1386 HadError = true;
1387 return;
1388 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001389
1390 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1391 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1392 "submodule defined in same file as 'module *' that allowed its "
1393 "top-level module");
1394 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1395 }
1396 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001397
1398 StringRef ModuleName = Id.back().first;
1399 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001400
Douglas Gregora686e1b2012-01-27 19:52:33 +00001401 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001402 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001403 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001404
Douglas Gregor718292f2011-11-11 19:10:28 +00001405 // Parse the opening brace.
1406 if (!Tok.is(MMToken::LBrace)) {
1407 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1408 << ModuleName;
1409 HadError = true;
1410 return;
1411 }
1412 SourceLocation LBraceLoc = consumeToken();
1413
1414 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001415 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001416 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1417 // Skip the module definition.
1418 skipUntil(MMToken::RBrace);
1419 if (Tok.is(MMToken::RBrace))
1420 consumeToken();
1421 else {
1422 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1423 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1424 HadError = true;
1425 }
1426 return;
1427 }
1428
Douglas Gregor718292f2011-11-11 19:10:28 +00001429 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1430 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001431 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001432
1433 // Skip the module definition.
1434 skipUntil(MMToken::RBrace);
1435 if (Tok.is(MMToken::RBrace))
1436 consumeToken();
1437
1438 HadError = true;
1439 return;
1440 }
1441
1442 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001443 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1444 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001445 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001446 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001447 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001448 if (Attrs.IsExternC)
1449 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001450 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001451
Douglas Gregor718292f2011-11-11 19:10:28 +00001452 bool Done = false;
1453 do {
1454 switch (Tok.Kind) {
1455 case MMToken::EndOfFile:
1456 case MMToken::RBrace:
1457 Done = true;
1458 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001459
1460 case MMToken::ConfigMacros:
1461 parseConfigMacros();
1462 break;
1463
Douglas Gregorfb912652013-03-20 21:10:35 +00001464 case MMToken::Conflict:
1465 parseConflict();
1466 break;
1467
Douglas Gregor718292f2011-11-11 19:10:28 +00001468 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001469 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001470 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001471 case MMToken::ModuleKeyword:
1472 parseModuleDecl();
1473 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001474
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001475 case MMToken::ExportKeyword:
1476 parseExportDecl();
1477 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001478
1479 case MMToken::UseKeyword:
1480 parseUseDecl();
1481 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001482
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001483 case MMToken::RequiresKeyword:
1484 parseRequiresDecl();
1485 break;
1486
Richard Smith202210b2014-10-24 20:23:01 +00001487 case MMToken::TextualKeyword:
1488 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001489 break;
Richard Smith306d8922014-10-22 23:50:56 +00001490
Douglas Gregor524e33e2011-12-08 19:11:24 +00001491 case MMToken::UmbrellaKeyword: {
1492 SourceLocation UmbrellaLoc = consumeToken();
1493 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001494 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001495 else
1496 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001497 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001498 }
Richard Smith202210b2014-10-24 20:23:01 +00001499
1500 case MMToken::ExcludeKeyword:
1501 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001502 break;
Richard Smith202210b2014-10-24 20:23:01 +00001503
1504 case MMToken::PrivateKeyword:
1505 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001506 break;
Richard Smith202210b2014-10-24 20:23:01 +00001507
Douglas Gregor322f6332011-12-08 18:00:48 +00001508 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001509 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001510 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001511
1512 case MMToken::LinkKeyword:
1513 parseLinkDecl();
1514 break;
1515
Douglas Gregor718292f2011-11-11 19:10:28 +00001516 default:
1517 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1518 consumeToken();
1519 break;
1520 }
1521 } while (!Done);
1522
1523 if (Tok.is(MMToken::RBrace))
1524 consumeToken();
1525 else {
1526 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1527 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1528 HadError = true;
1529 }
1530
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001531 // If the active module is a top-level framework, and there are no link
1532 // libraries, automatically link against the framework.
1533 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1534 ActiveModule->LinkLibraries.empty()) {
1535 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1536 }
1537
Ben Langmuirec8c9752014-04-18 22:07:31 +00001538 // If the module meets all requirements but is still unavailable, mark the
1539 // whole tree as unavailable to prevent it from building.
1540 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1541 ActiveModule->Parent) {
1542 ActiveModule->getTopLevelModule()->markUnavailable();
1543 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1544 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1545 }
1546
Douglas Gregore7ab3662011-12-07 02:23:45 +00001547 // We're done parsing this module. Pop back to the previous module.
1548 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001549}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001550
Daniel Jasper97292842013-09-11 07:20:44 +00001551/// \brief Parse an extern module declaration.
1552///
1553/// extern module-declaration:
1554/// 'extern' 'module' module-id string-literal
1555void ModuleMapParser::parseExternModuleDecl() {
1556 assert(Tok.is(MMToken::ExternKeyword));
1557 consumeToken(); // 'extern' keyword
1558
1559 // Parse 'module' keyword.
1560 if (!Tok.is(MMToken::ModuleKeyword)) {
1561 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1562 consumeToken();
1563 HadError = true;
1564 return;
1565 }
1566 consumeToken(); // 'module' keyword
1567
1568 // Parse the module name.
1569 ModuleId Id;
1570 if (parseModuleId(Id)) {
1571 HadError = true;
1572 return;
1573 }
1574
1575 // Parse the referenced module map file name.
1576 if (!Tok.is(MMToken::StringLiteral)) {
1577 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1578 HadError = true;
1579 return;
1580 }
1581 std::string FileName = Tok.getString();
1582 consumeToken(); // filename
1583
1584 StringRef FileNameRef = FileName;
1585 SmallString<128> ModuleMapFileName;
1586 if (llvm::sys::path::is_relative(FileNameRef)) {
1587 ModuleMapFileName += Directory->getName();
1588 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001589 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001590 }
1591 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001592 Map.parseModuleMapFile(
1593 File, /*IsSystem=*/false,
1594 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1595 ? Directory
1596 : File->getDir());
Daniel Jasper97292842013-09-11 07:20:44 +00001597}
1598
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001599/// \brief Parse a requires declaration.
1600///
1601/// requires-declaration:
1602/// 'requires' feature-list
1603///
1604/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001605/// feature ',' feature-list
1606/// feature
1607///
1608/// feature:
1609/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001610void ModuleMapParser::parseRequiresDecl() {
1611 assert(Tok.is(MMToken::RequiresKeyword));
1612
1613 // Parse 'requires' keyword.
1614 consumeToken();
1615
1616 // Parse the feature-list.
1617 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001618 bool RequiredState = true;
1619 if (Tok.is(MMToken::Exclaim)) {
1620 RequiredState = false;
1621 consumeToken();
1622 }
1623
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001624 if (!Tok.is(MMToken::Identifier)) {
1625 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1626 HadError = true;
1627 return;
1628 }
1629
1630 // Consume the feature name.
1631 std::string Feature = Tok.getString();
1632 consumeToken();
1633
1634 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001635 ActiveModule->addRequirement(Feature, RequiredState,
1636 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001637
1638 if (!Tok.is(MMToken::Comma))
1639 break;
1640
1641 // Consume the comma.
1642 consumeToken();
1643 } while (true);
1644}
1645
Douglas Gregorf2161a72011-12-06 17:16:41 +00001646/// \brief Append to \p Paths the set of paths needed to get to the
1647/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001648static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001649 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001650 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001651 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001652 for (; Mod; Mod = Mod->Parent) {
1653 if (Mod->IsFramework)
1654 Paths.push_back(Mod->Name);
1655 }
1656
1657 if (Paths.empty())
1658 return;
1659
1660 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001661 for (unsigned I = Paths.size() - 1; I != 0; --I)
1662 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001663}
1664
Douglas Gregor718292f2011-11-11 19:10:28 +00001665/// \brief Parse a header declaration.
1666///
1667/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001668/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001669/// 'private' 'textual'[opt] 'header' string-literal
1670/// 'exclude' 'header' string-literal
1671/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001672///
1673/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001674void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1675 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001676 // We've already consumed the first token.
1677 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1678 if (LeadingToken == MMToken::PrivateKeyword) {
1679 Role = ModuleMap::PrivateHeader;
1680 // 'private' may optionally be followed by 'textual'.
1681 if (Tok.is(MMToken::TextualKeyword)) {
1682 LeadingToken = Tok.Kind;
1683 consumeToken();
1684 }
1685 }
1686 if (LeadingToken == MMToken::TextualKeyword)
1687 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1688
1689 if (LeadingToken != MMToken::HeaderKeyword) {
1690 if (!Tok.is(MMToken::HeaderKeyword)) {
1691 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1692 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1693 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1694 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1695 return;
1696 }
1697 consumeToken();
1698 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001699
Douglas Gregor718292f2011-11-11 19:10:28 +00001700 // Parse the header name.
1701 if (!Tok.is(MMToken::StringLiteral)) {
1702 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1703 << "header";
1704 HadError = true;
1705 return;
1706 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001707 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001708 Header.FileName = Tok.getString();
1709 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001710
Douglas Gregor524e33e2011-12-08 19:11:24 +00001711 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001712 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001713 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001714 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001715 HadError = true;
1716 return;
1717 }
1718
Douglas Gregor5257fc62011-11-11 21:55:48 +00001719 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001720 const FileEntry *File = nullptr;
1721 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001722 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001723 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001724 RelativePathName = Header.FileName;
1725 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001726 } else {
1727 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001728 SmallString<128> FullPathName(Directory->getName());
1729 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001730
Douglas Gregorf2161a72011-12-06 17:16:41 +00001731 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001732 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001733
1734 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001735 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001736 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001737 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001738
1739 if (!File) {
1740 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001741 // FIXME: Should we retain the subframework paths here?
1742 RelativePathName.clear();
1743 FullPathName.resize(FullPathLength);
1744 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1745 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001746 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001747 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001748 }
1749 } else {
1750 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001751 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001752 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001753 File = SourceMgr.getFileManager().getFile(FullPathName);
1754
Douglas Gregor3ec66632012-02-02 18:42:48 +00001755 // If this is a system module with a top-level header, this header
1756 // may have a counterpart (or replacement) in the set of headers
1757 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001758 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1759 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001760 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001761 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001762 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001763 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001764
Douglas Gregor3ec66632012-02-02 18:42:48 +00001765 // If Clang supplies this header but the underlying system does not,
1766 // just silently swap in our builtin version. Otherwise, we'll end
1767 // up adding both (later).
1768 if (!File && BuiltinFile) {
1769 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001770 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001771 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001772 }
1773 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001774 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001775 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001776
Douglas Gregor5257fc62011-11-11 21:55:48 +00001777 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1778 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001779 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001780 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001781 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001782 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001783 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001784 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001785 HadError = true;
1786 } else {
1787 // Record this umbrella header.
1788 Map.setUmbrellaHeader(ActiveModule, File);
1789 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001790 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001791 Module::Header H = {RelativePathName.str(), File};
1792 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001793 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001794 // If there is a builtin counterpart to this file, add it now, before
1795 // the "real" header, so we build the built-in one first when building
1796 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001797 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001798 // FIXME: Taking the name from the FileEntry is unstable and can give
1799 // different results depending on how we've previously named that file
1800 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001801 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1802 Map.addHeader(ActiveModule, H, Role);
1803 }
Richard Smith25d50752014-10-20 00:15:49 +00001804
Richard Smith202210b2014-10-24 20:23:01 +00001805 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001806 Module::Header H = { RelativePathName.str(), File };
1807 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001808 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001809 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001810 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001811
1812 // If we find a module that has a missing header, we mark this module as
1813 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001814 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001815 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001816 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001817 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001818}
1819
Douglas Gregor524e33e2011-12-08 19:11:24 +00001820/// \brief Parse an umbrella directory declaration.
1821///
1822/// umbrella-dir-declaration:
1823/// umbrella string-literal
1824void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1825 // Parse the directory name.
1826 if (!Tok.is(MMToken::StringLiteral)) {
1827 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1828 << "umbrella";
1829 HadError = true;
1830 return;
1831 }
1832
1833 std::string DirName = Tok.getString();
1834 SourceLocation DirNameLoc = consumeToken();
1835
1836 // Check whether we already have an umbrella.
1837 if (ActiveModule->Umbrella) {
1838 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1839 << ActiveModule->getFullModuleName();
1840 HadError = true;
1841 return;
1842 }
1843
1844 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001845 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001846 if (llvm::sys::path::is_absolute(DirName))
1847 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1848 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001849 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001850 PathName = Directory->getName();
1851 llvm::sys::path::append(PathName, DirName);
1852 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1853 }
1854
1855 if (!Dir) {
1856 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1857 << DirName;
1858 HadError = true;
1859 return;
1860 }
1861
1862 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1863 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1864 << OwningModule->getFullModuleName();
1865 HadError = true;
1866 return;
1867 }
1868
1869 // Record this umbrella directory.
1870 Map.setUmbrellaDir(ActiveModule, Dir);
1871}
1872
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001873/// \brief Parse a module export declaration.
1874///
1875/// export-declaration:
1876/// 'export' wildcard-module-id
1877///
1878/// wildcard-module-id:
1879/// identifier
1880/// '*'
1881/// identifier '.' wildcard-module-id
1882void ModuleMapParser::parseExportDecl() {
1883 assert(Tok.is(MMToken::ExportKeyword));
1884 SourceLocation ExportLoc = consumeToken();
1885
1886 // Parse the module-id with an optional wildcard at the end.
1887 ModuleId ParsedModuleId;
1888 bool Wildcard = false;
1889 do {
Richard Smith306d8922014-10-22 23:50:56 +00001890 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001891 if (Tok.is(MMToken::Identifier)) {
1892 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1893 Tok.getLocation()));
1894 consumeToken();
1895
1896 if (Tok.is(MMToken::Period)) {
1897 consumeToken();
1898 continue;
1899 }
1900
1901 break;
1902 }
1903
1904 if(Tok.is(MMToken::Star)) {
1905 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001906 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001907 break;
1908 }
1909
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001910 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001911 HadError = true;
1912 return;
1913 } while (true);
1914
1915 Module::UnresolvedExportDecl Unresolved = {
1916 ExportLoc, ParsedModuleId, Wildcard
1917 };
1918 ActiveModule->UnresolvedExports.push_back(Unresolved);
1919}
1920
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001921/// \brief Parse a module uses declaration.
1922///
1923/// uses-declaration:
1924/// 'uses' wildcard-module-id
1925void ModuleMapParser::parseUseDecl() {
1926 assert(Tok.is(MMToken::UseKeyword));
1927 consumeToken();
1928 // Parse the module-id.
1929 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001930 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001931
1932 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1933}
1934
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001935/// \brief Parse a link declaration.
1936///
1937/// module-declaration:
1938/// 'link' 'framework'[opt] string-literal
1939void ModuleMapParser::parseLinkDecl() {
1940 assert(Tok.is(MMToken::LinkKeyword));
1941 SourceLocation LinkLoc = consumeToken();
1942
1943 // Parse the optional 'framework' keyword.
1944 bool IsFramework = false;
1945 if (Tok.is(MMToken::FrameworkKeyword)) {
1946 consumeToken();
1947 IsFramework = true;
1948 }
1949
1950 // Parse the library name
1951 if (!Tok.is(MMToken::StringLiteral)) {
1952 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1953 << IsFramework << SourceRange(LinkLoc);
1954 HadError = true;
1955 return;
1956 }
1957
1958 std::string LibraryName = Tok.getString();
1959 consumeToken();
1960 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1961 IsFramework));
1962}
1963
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001964/// \brief Parse a configuration macro declaration.
1965///
1966/// module-declaration:
1967/// 'config_macros' attributes[opt] config-macro-list?
1968///
1969/// config-macro-list:
1970/// identifier (',' identifier)?
1971void ModuleMapParser::parseConfigMacros() {
1972 assert(Tok.is(MMToken::ConfigMacros));
1973 SourceLocation ConfigMacrosLoc = consumeToken();
1974
1975 // Only top-level modules can have configuration macros.
1976 if (ActiveModule->Parent) {
1977 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1978 }
1979
1980 // Parse the optional attributes.
1981 Attributes Attrs;
1982 parseOptionalAttributes(Attrs);
1983 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1984 ActiveModule->ConfigMacrosExhaustive = true;
1985 }
1986
1987 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001988 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001989 if (!Tok.is(MMToken::Identifier))
1990 return;
1991
1992 // Consume the first identifier.
1993 if (!ActiveModule->Parent) {
1994 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1995 }
1996 consumeToken();
1997
1998 do {
1999 // If there's a comma, consume it.
2000 if (!Tok.is(MMToken::Comma))
2001 break;
2002 consumeToken();
2003
2004 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002005 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002006 if (!Tok.is(MMToken::Identifier)) {
2007 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2008 break;
2009 }
2010
2011 // Consume the macro name.
2012 if (!ActiveModule->Parent) {
2013 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2014 }
2015 consumeToken();
2016 } while (true);
2017}
2018
Douglas Gregorfb912652013-03-20 21:10:35 +00002019/// \brief Format a module-id into a string.
2020static std::string formatModuleId(const ModuleId &Id) {
2021 std::string result;
2022 {
2023 llvm::raw_string_ostream OS(result);
2024
2025 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2026 if (I)
2027 OS << ".";
2028 OS << Id[I].first;
2029 }
2030 }
2031
2032 return result;
2033}
2034
2035/// \brief Parse a conflict declaration.
2036///
2037/// module-declaration:
2038/// 'conflict' module-id ',' string-literal
2039void ModuleMapParser::parseConflict() {
2040 assert(Tok.is(MMToken::Conflict));
2041 SourceLocation ConflictLoc = consumeToken();
2042 Module::UnresolvedConflict Conflict;
2043
2044 // Parse the module-id.
2045 if (parseModuleId(Conflict.Id))
2046 return;
2047
2048 // Parse the ','.
2049 if (!Tok.is(MMToken::Comma)) {
2050 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2051 << SourceRange(ConflictLoc);
2052 return;
2053 }
2054 consumeToken();
2055
2056 // Parse the message.
2057 if (!Tok.is(MMToken::StringLiteral)) {
2058 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2059 << formatModuleId(Conflict.Id);
2060 return;
2061 }
2062 Conflict.Message = Tok.getString().str();
2063 consumeToken();
2064
2065 // Add this unresolved conflict.
2066 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2067}
2068
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002069/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002070///
2071/// module-declaration:
2072/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2073/// { inferred-module-member* }
2074///
2075/// inferred-module-member:
2076/// 'export' '*'
2077/// 'exclude' identifier
2078void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002079 assert(Tok.is(MMToken::Star));
2080 SourceLocation StarLoc = consumeToken();
2081 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002082
Douglas Gregor73441092011-12-05 22:27:44 +00002083 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002084 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002085 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2086 Failed = true;
2087 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002088
2089 if (ActiveModule) {
2090 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002091 if (!Failed && ActiveModule->IsAvailable &&
2092 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002093 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2094 Failed = true;
2095 }
2096
2097 // Check for redefinition of an inferred module.
2098 if (!Failed && ActiveModule->InferSubmodules) {
2099 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2100 if (ActiveModule->InferredSubmoduleLoc.isValid())
2101 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2102 diag::note_mmap_prev_definition);
2103 Failed = true;
2104 }
2105
2106 // Check for the 'framework' keyword, which is not permitted here.
2107 if (Framework) {
2108 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2109 Framework = false;
2110 }
2111 } else if (Explicit) {
2112 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2113 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002114 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002115
Douglas Gregor73441092011-12-05 22:27:44 +00002116 // If there were any problems with this inferred submodule, skip its body.
2117 if (Failed) {
2118 if (Tok.is(MMToken::LBrace)) {
2119 consumeToken();
2120 skipUntil(MMToken::RBrace);
2121 if (Tok.is(MMToken::RBrace))
2122 consumeToken();
2123 }
2124 HadError = true;
2125 return;
2126 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002127
2128 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002129 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002130 parseOptionalAttributes(Attrs);
2131
2132 if (ActiveModule) {
2133 // Note that we have an inferred submodule.
2134 ActiveModule->InferSubmodules = true;
2135 ActiveModule->InferredSubmoduleLoc = StarLoc;
2136 ActiveModule->InferExplicitSubmodules = Explicit;
2137 } else {
2138 // We'll be inferring framework modules for this directory.
2139 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002140 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002141 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002142 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002143 }
2144
Douglas Gregor73441092011-12-05 22:27:44 +00002145 // Parse the opening brace.
2146 if (!Tok.is(MMToken::LBrace)) {
2147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2148 HadError = true;
2149 return;
2150 }
2151 SourceLocation LBraceLoc = consumeToken();
2152
2153 // Parse the body of the inferred submodule.
2154 bool Done = false;
2155 do {
2156 switch (Tok.Kind) {
2157 case MMToken::EndOfFile:
2158 case MMToken::RBrace:
2159 Done = true;
2160 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002161
2162 case MMToken::ExcludeKeyword: {
2163 if (ActiveModule) {
2164 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002165 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002166 consumeToken();
2167 break;
2168 }
2169
2170 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002171 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002172 if (!Tok.is(MMToken::Identifier)) {
2173 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2174 break;
2175 }
2176
2177 Map.InferredDirectories[Directory].ExcludedModules
2178 .push_back(Tok.getString());
2179 consumeToken();
2180 break;
2181 }
2182
2183 case MMToken::ExportKeyword:
2184 if (!ActiveModule) {
2185 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002186 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002187 consumeToken();
2188 break;
2189 }
2190
Douglas Gregor73441092011-12-05 22:27:44 +00002191 consumeToken();
2192 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002193 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002194 else
2195 Diags.Report(Tok.getLocation(),
2196 diag::err_mmap_expected_export_wildcard);
2197 consumeToken();
2198 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002199
Douglas Gregor73441092011-12-05 22:27:44 +00002200 case MMToken::ExplicitKeyword:
2201 case MMToken::ModuleKeyword:
2202 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002203 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002204 case MMToken::UmbrellaKeyword:
2205 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002206 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002207 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002208 consumeToken();
2209 break;
2210 }
2211 } while (!Done);
2212
2213 if (Tok.is(MMToken::RBrace))
2214 consumeToken();
2215 else {
2216 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2217 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2218 HadError = true;
2219 }
2220}
2221
Douglas Gregor9194a912012-11-06 19:39:40 +00002222/// \brief Parse optional attributes.
2223///
2224/// attributes:
2225/// attribute attributes
2226/// attribute
2227///
2228/// attribute:
2229/// [ identifier ]
2230///
2231/// \param Attrs Will be filled in with the parsed attributes.
2232///
2233/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002234bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002235 bool HadError = false;
2236
2237 while (Tok.is(MMToken::LSquare)) {
2238 // Consume the '['.
2239 SourceLocation LSquareLoc = consumeToken();
2240
2241 // Check whether we have an attribute name here.
2242 if (!Tok.is(MMToken::Identifier)) {
2243 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2244 skipUntil(MMToken::RSquare);
2245 if (Tok.is(MMToken::RSquare))
2246 consumeToken();
2247 HadError = true;
2248 }
2249
2250 // Decode the attribute name.
2251 AttributeKind Attribute
2252 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002253 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002254 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002255 .Case("system", AT_system)
2256 .Default(AT_unknown);
2257 switch (Attribute) {
2258 case AT_unknown:
2259 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2260 << Tok.getString();
2261 break;
2262
2263 case AT_system:
2264 Attrs.IsSystem = true;
2265 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002266
Richard Smith77944862014-03-02 05:58:18 +00002267 case AT_extern_c:
2268 Attrs.IsExternC = true;
2269 break;
2270
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002271 case AT_exhaustive:
2272 Attrs.IsExhaustive = true;
2273 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002274 }
2275 consumeToken();
2276
2277 // Consume the ']'.
2278 if (!Tok.is(MMToken::RSquare)) {
2279 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2280 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2281 skipUntil(MMToken::RSquare);
2282 HadError = true;
2283 }
2284
2285 if (Tok.is(MMToken::RSquare))
2286 consumeToken();
2287 }
2288
2289 return HadError;
2290}
2291
Douglas Gregor718292f2011-11-11 19:10:28 +00002292/// \brief Parse a module map file.
2293///
2294/// module-map-file:
2295/// module-declaration*
2296bool ModuleMapParser::parseModuleMapFile() {
2297 do {
2298 switch (Tok.Kind) {
2299 case MMToken::EndOfFile:
2300 return HadError;
2301
Douglas Gregore7ab3662011-12-07 02:23:45 +00002302 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002303 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002304 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002305 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002306 parseModuleDecl();
2307 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002308
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002309 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002310 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002311 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002312 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002313 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002314 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002315 case MMToken::HeaderKeyword:
2316 case MMToken::Identifier:
2317 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002318 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002319 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002320 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002321 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002322 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002323 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002324 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002325 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002326 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002327 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002328 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002329 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002330 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2331 HadError = true;
2332 consumeToken();
2333 break;
2334 }
2335 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002336}
2337
Richard Smith9acb99e32014-12-10 03:09:48 +00002338bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2339 const DirectoryEntry *Dir) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002340 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2341 = ParsedModuleMap.find(File);
2342 if (Known != ParsedModuleMap.end())
2343 return Known->second;
2344
Craig Topperd2d442c2014-05-17 23:10:59 +00002345 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002346 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2347 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002348 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002349 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002350 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002351
Douglas Gregor718292f2011-11-11 19:10:28 +00002352 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002353 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002354 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002355 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002356 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002357 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002358 return Result;
2359}