blob: a4f1c05dc1634d60ad58d5f8b3d5836a518827bd [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
Daniel Jasper92669ee2013-12-20 12:09:36 +0000208static bool violatesPrivateInclude(Module *RequestingModule,
209 const FileEntry *IncFileEnt,
210 ModuleMap::ModuleHeaderRole Role,
211 Module *RequestedModule) {
Richard Smith202210b2014-10-24 20:23:01 +0000212 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
213#ifndef NDEBUG
Richard Smith2708e522015-03-10 00:19:04 +0000214 if (IsPrivateRole) {
215 // Check for consistency between the module header role
216 // as obtained from the lookup and as obtained from the module.
217 // This check is not cheap, so enable it only for debugging.
218 bool IsPrivate = false;
219 SmallVectorImpl<Module::Header> *HeaderList[] = {
220 &RequestedModule->Headers[Module::HK_Private],
221 &RequestedModule->Headers[Module::HK_PrivateTextual]};
222 for (auto *Hs : HeaderList)
223 IsPrivate |=
224 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000225 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000226 }) != Hs->end();
227 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
228 }
Richard Smith202210b2014-10-24 20:23:01 +0000229#endif
230 return IsPrivateRole &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000231 // FIXME: Should we map RequestingModule to its top-level module here
232 // too? This check is redundant with the isSubModuleOf check in
233 // diagnoseHeaderInclusion.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000234 RequestedModule->getTopLevelModule() != RequestingModule;
235}
236
Ben Langmuir71e1a642014-05-05 21:44:13 +0000237static Module *getTopLevelOrNull(Module *M) {
238 return M ? M->getTopLevelModule() : nullptr;
239}
240
Daniel Jasper92669ee2013-12-20 12:09:36 +0000241void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
242 SourceLocation FilenameLoc,
243 StringRef Filename,
244 const FileEntry *File) {
245 // No errors for indirect modules. This may be a bit of a problem for modules
246 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000247 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000248 return;
249
250 if (RequestingModule)
251 resolveUses(RequestingModule, /*Complain=*/false);
252
Ben Langmuir71e1a642014-05-05 21:44:13 +0000253 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000254 Module *Private = nullptr;
255 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000256
Ben Langmuir71e1a642014-05-05 21:44:13 +0000257 HeadersMap::iterator Known = findKnownHeader(File);
258 if (Known != Headers.end()) {
259 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000260 // If 'File' is part of 'RequestingModule' we can definitely include it.
Daniel Jasper0ab544f2015-03-13 14:29:39 +0000261 if (Header.getModule() &&
262 Header.getModule()->isSubModuleOf(RequestingModule))
Ben Langmuir71e1a642014-05-05 21:44:13 +0000263 return;
264
265 // Remember private headers for later printing of a diagnostic.
266 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
267 Header.getModule())) {
268 Private = Header.getModule();
269 continue;
270 }
271
272 // If uses need to be specified explicitly, we are only allowed to return
273 // modules that are explicitly used by the requesting module.
274 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000275 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000276 NotUsed = Header.getModule();
277 continue;
278 }
279
280 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000281 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000282 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000283
284 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000285 }
286
287 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000288 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000289 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000290 << Filename;
291 return;
292 }
293
294 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000295 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000296 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000297 << RequestingModule->getFullModuleName() << Filename;
298 return;
299 }
300
Ben Langmuir71e1a642014-05-05 21:44:13 +0000301 if (Excluded || isHeaderInUmbrellaDirs(File))
302 return;
303
304 // At this point, only non-modular includes remain.
305
306 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000307 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000308 << RequestingModule->getFullModuleName() << Filename;
309 } else if (RequestingModule) {
310 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
311 diag::warn_non_modular_include_in_framework_module :
312 diag::warn_non_modular_include_in_module;
313 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000314 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000315}
316
Richard Smithec87a502015-02-13 23:50:20 +0000317static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
318 const ModuleMap::KnownHeader &Old) {
319 // Prefer a public header over a private header.
320 if ((New.getRole() & ModuleMap::PrivateHeader) !=
321 (Old.getRole() & ModuleMap::PrivateHeader))
322 return !(New.getRole() & ModuleMap::PrivateHeader);
323
324 // Prefer a non-textual header over a textual header.
325 if ((New.getRole() & ModuleMap::TextualHeader) !=
326 (Old.getRole() & ModuleMap::TextualHeader))
327 return !(New.getRole() & ModuleMap::TextualHeader);
328
329 // Don't have a reason to choose between these. Just keep the first one.
330 return false;
331}
332
Daniel Jasper92669ee2013-12-20 12:09:36 +0000333ModuleMap::KnownHeader
334ModuleMap::findModuleForHeader(const FileEntry *File,
Richard Smith306d8922014-10-22 23:50:56 +0000335 Module *RequestingModule,
336 bool IncludeTextualHeaders) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000337 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000338
Richard Smith306d8922014-10-22 23:50:56 +0000339 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Richard Smith202210b2014-10-24 20:23:01 +0000340 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
Richard Smith306d8922014-10-22 23:50:56 +0000341 return ModuleMap::KnownHeader();
342 return R;
343 };
344
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000345 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000346 ModuleMap::KnownHeader Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000347
Daniel Jasper97da9172013-10-22 08:09:47 +0000348 // Iterate over all modules that 'File' is part of to find the best fit.
349 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
350 E = Known->second.end();
351 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000352 // Cannot use a module if it is unavailable.
353 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000354 continue;
355
356 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
357 // module we are looking for.
358 if (I->getModule() == RequestingModule)
Richard Smith306d8922014-10-22 23:50:56 +0000359 return MakeResult(*I);
Daniel Jasper97da9172013-10-22 08:09:47 +0000360
361 // If uses need to be specified explicitly, we are only allowed to return
362 // modules that are explicitly used by the requesting module.
363 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000364 !RequestingModule->directlyUses(I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000365 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000366
Richard Smithec87a502015-02-13 23:50:20 +0000367 if (!Result || isBetterKnownHeader(*I, Result))
Richard Smith202210b2014-10-24 20:23:01 +0000368 Result = *I;
Daniel Jasper97da9172013-10-22 08:09:47 +0000369 }
Richard Smith306d8922014-10-22 23:50:56 +0000370 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000371 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000372
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000373 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000374 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
375 if (H) {
376 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000377
Ben Langmuir44691382014-04-10 00:39:10 +0000378 // Search up the module stack until we find a module with an umbrella
379 // directory.
380 Module *UmbrellaModule = Result;
381 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
382 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000383
Ben Langmuir44691382014-04-10 00:39:10 +0000384 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000385 const FileEntry *UmbrellaModuleMap =
386 getModuleMapFileForUniquing(UmbrellaModule);
387
Ben Langmuir44691382014-04-10 00:39:10 +0000388 // Infer submodules for each of the directories we found between
389 // the directory of the umbrella header and the directory where
390 // the actual header is located.
391 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000392
Ben Langmuir44691382014-04-10 00:39:10 +0000393 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
394 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000395 SmallString<32> NameBuf;
396 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000397 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000398 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
399 Explicit).first;
400 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000401 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000402
403 // Associate the module and the directory.
404 UmbrellaDirs[SkippedDirs[I-1]] = Result;
405
406 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000407 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000408 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000409 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000410 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000411
Ben Langmuir44691382014-04-10 00:39:10 +0000412 // Infer a submodule with the same name as this header file.
413 SmallString<32> NameBuf;
414 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000415 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000416 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
417 Explicit).first;
418 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000419 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000420 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000421
Ben Langmuir44691382014-04-10 00:39:10 +0000422 // If inferred submodules export everything they import, add a
423 // wildcard to the set of exports.
424 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000425 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000426 } else {
427 // Record each of the directories we stepped through as being part of
428 // the module we found, since the umbrella header covers them all.
429 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
430 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000431 }
Ben Langmuir44691382014-04-10 00:39:10 +0000432
433 Headers[File].push_back(KnownHeader(Result, NormalHeader));
434
435 // If a header corresponds to an unavailable module, don't report
436 // that it maps to anything.
437 if (!Result->isAvailable())
438 return KnownHeader();
439
Richard Smith306d8922014-10-22 23:50:56 +0000440 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000441 }
Richard Smith306d8922014-10-22 23:50:56 +0000442
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000443 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000444}
445
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000446bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000447 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000448}
449
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000450bool
451ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
452 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000453 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000454 if (Known != Headers.end()) {
455 for (SmallVectorImpl<KnownHeader>::const_iterator
456 I = Known->second.begin(),
457 E = Known->second.end();
458 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000459 if (I->isAvailable() && (!RequestingModule ||
460 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000461 return false;
462 }
463 return true;
464 }
Richard Smith50996ce2014-04-08 13:13:04 +0000465
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000466 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000467 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000468 StringRef DirName = Dir->getName();
469
Richard Smith50996ce2014-04-08 13:13:04 +0000470 auto IsUnavailable = [&](const Module *M) {
471 return !M->isAvailable() && (!RequestingModule ||
472 M->isSubModuleOf(RequestingModule));
473 };
474
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000475 // Keep walking up the directory hierarchy, looking for a directory with
476 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000477 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000478 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000479 = UmbrellaDirs.find(Dir);
480 if (KnownDir != UmbrellaDirs.end()) {
481 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000482 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000483 return true;
484
485 // Search up the module stack until we find a module with an umbrella
486 // directory.
487 Module *UmbrellaModule = Found;
488 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
489 UmbrellaModule = UmbrellaModule->Parent;
490
491 if (UmbrellaModule->InferSubmodules) {
492 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
493 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000494 SmallString<32> NameBuf;
495 StringRef Name = sanitizeFilenameAsIdentifier(
496 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
497 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000498 Found = lookupModuleQualified(Name, Found);
499 if (!Found)
500 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000501 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000502 return true;
503 }
504
505 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000506 SmallString<32> NameBuf;
507 StringRef Name = sanitizeFilenameAsIdentifier(
508 llvm::sys::path::stem(Header->getName()),
509 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000510 Found = lookupModuleQualified(Name, Found);
511 if (!Found)
512 return false;
513 }
514
Richard Smith50996ce2014-04-08 13:13:04 +0000515 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000516 }
517
518 SkippedDirs.push_back(Dir);
519
520 // Retrieve our parent path.
521 DirName = llvm::sys::path::parent_path(DirName);
522 if (DirName.empty())
523 break;
524
525 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000526 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000527 } while (Dir);
528
529 return false;
530}
531
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000532Module *ModuleMap::findModule(StringRef Name) const {
533 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000534 if (Known != Modules.end())
535 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000536
537 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000538}
539
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000540Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
541 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000542 for(; Context; Context = Context->Parent) {
543 if (Module *Sub = lookupModuleQualified(Name, Context))
544 return Sub;
545 }
546
547 return findModule(Name);
548}
549
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000550Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000551 if (!Context)
552 return findModule(Name);
553
Douglas Gregoreb90e832012-01-04 23:32:19 +0000554 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000555}
556
Douglas Gregorde3ef502011-11-30 23:21:26 +0000557std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000558ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000559 bool IsExplicit) {
560 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000561 if (Module *Sub = lookupModuleQualified(Name, Parent))
562 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000563
564 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000565 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000566 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000567 if (LangOpts.CurrentModule == Name) {
568 SourceModule = Result;
569 SourceModuleName = Name;
570 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000571 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000572 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000573 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
574 Name == LangOpts.CurrentModule) {
575 CompilingModule = Result;
576 }
577 }
Douglas Gregor69021972011-11-30 17:33:56 +0000578 return std::make_pair(Result, true);
579}
580
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000581/// \brief For a framework module, infer the framework against which we
582/// should link.
583static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
584 FileManager &FileMgr) {
585 assert(Mod->IsFramework && "Can only infer linking for framework modules");
586 assert(!Mod->isSubFramework() &&
587 "Can only infer linking for top-level frameworks");
588
589 SmallString<128> LibName;
590 LibName += FrameworkDir->getName();
591 llvm::sys::path::append(LibName, Mod->Name);
592 if (FileMgr.getFile(LibName)) {
593 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
594 /*IsFramework=*/true));
595 }
596}
597
Douglas Gregorde3ef502011-11-30 23:21:26 +0000598Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000599ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000600 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000601 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000602 Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000603 Attributes Attrs;
604 Attrs.IsSystem = IsSystem;
605 return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
606}
607
608Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
609 const DirectoryEntry *FrameworkDir,
610 Attributes Attrs, Module *Parent) {
611
Douglas Gregor56c64012011-11-17 01:41:17 +0000612 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000613 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
614 return Mod;
615
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000616 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000617
618 // If the framework has a parent path from which we're allowed to infer
619 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000620 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000621 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000622 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000623
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000624 // Note: as an egregious but useful hack we use the real path here, because
625 // we might be looking at an embedded framework that symlinks out to a
626 // top-level framework, and we need to infer as if we were naming the
627 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000628 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000629 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000631 // In case this is a case-insensitive filesystem, make sure the canonical
632 // directory name matches ModuleName exactly. Modules are case-sensitive.
633 // FIXME: we should be able to give a fix-it hint for the correct spelling.
634 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
635 return nullptr;
636
Douglas Gregor9194a912012-11-06 19:39:40 +0000637 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000638 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000639 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000640 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000641 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
642 // Check whether we have already looked into the parent directory
643 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000644 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000645 inferred = InferredDirectories.find(ParentDir);
646 if (inferred == InferredDirectories.end()) {
647 // We haven't looked here before. Load a module map, if there is
648 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000649 bool IsFrameworkDir = Parent.endswith(".framework");
650 if (const FileEntry *ModMapFile =
651 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000652 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000653 inferred = InferredDirectories.find(ParentDir);
654 }
655
656 if (inferred == InferredDirectories.end())
657 inferred = InferredDirectories.insert(
658 std::make_pair(ParentDir, InferredDirectory())).first;
659 }
660
661 if (inferred->second.InferModules) {
662 // We're allowed to infer for this directory, but make sure it's okay
663 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000664 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000665 canInfer = std::find(inferred->second.ExcludedModules.begin(),
666 inferred->second.ExcludedModules.end(),
667 Name) == inferred->second.ExcludedModules.end();
668
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000669 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
670 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
671 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000672 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000673 }
674 }
675 }
676
677 // If we're not allowed to infer a framework module, don't.
678 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000679 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000680 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000681 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000682
683
Douglas Gregor56c64012011-11-17 01:41:17 +0000684 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000685 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000686 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000687 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000688
689 // FIXME: If there's no umbrella header, we could probably scan the
690 // framework to load *everything*. But, it's not clear that this is a good
691 // idea.
692 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000693 return nullptr;
694
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000695 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000696 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000697 InferredModuleAllowedBy[Result] = ModuleMapFile;
698 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000699 if (LangOpts.CurrentModule == ModuleName) {
700 SourceModule = Result;
701 SourceModuleName = ModuleName;
702 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000703
704 Result->IsSystem |= Attrs.IsSystem;
705 Result->IsExternC |= Attrs.IsExternC;
706 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
707
Douglas Gregoreb90e832012-01-04 23:32:19 +0000708 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000709 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000710
Douglas Gregor322f6332011-12-08 18:00:48 +0000711 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000712 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000713 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000714 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000715
716 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000717 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
718
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000719 // module * { export * }
720 Result->InferSubmodules = true;
721 Result->InferExportWildcard = true;
722
Douglas Gregore89dbc12011-12-06 19:39:29 +0000723 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000724 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000725 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000726 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000727 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000728 llvm::sys::path::native(SubframeworksDirName);
Yaron Keren92e1b622015-03-18 10:17:07 +0000729 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000730 Dir != DirEnd && !EC; Dir.increment(EC)) {
731 if (!StringRef(Dir->path()).endswith(".framework"))
732 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000733
Douglas Gregore89dbc12011-12-06 19:39:29 +0000734 if (const DirectoryEntry *SubframeworkDir
735 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000736 // Note: as an egregious but useful hack, we use the real path here and
737 // check whether it is actually a subdirectory of the parent directory.
738 // This will not be the case if the 'subframework' is actually a symlink
739 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000740 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
741 bool FoundParent = false;
742 do {
743 // Get the parent directory name.
744 SubframeworkDirName
745 = llvm::sys::path::parent_path(SubframeworkDirName);
746 if (SubframeworkDirName.empty())
747 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000748
Douglas Gregore00c8b22013-01-26 00:55:12 +0000749 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
750 FoundParent = true;
751 break;
752 }
753 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000754
Douglas Gregore00c8b22013-01-26 00:55:12 +0000755 if (!FoundParent)
756 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000757
Douglas Gregore89dbc12011-12-06 19:39:29 +0000758 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000759 SmallString<32> NameBuf;
760 inferFrameworkModule(sanitizeFilenameAsIdentifier(
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000761 llvm::sys::path::stem(Dir->path()), NameBuf),
762 SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000763 }
764 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000765
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000766 // If the module is a top-level framework, automatically link against the
767 // framework.
768 if (!Result->isSubFramework()) {
769 inferFrameworkLink(Result, FrameworkDir, FileMgr);
770 }
771
Douglas Gregor56c64012011-11-17 01:41:17 +0000772 return Result;
773}
774
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000775void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000776 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000777 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000778 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000779}
780
Douglas Gregor524e33e2011-12-08 19:11:24 +0000781void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
782 Mod->Umbrella = UmbrellaDir;
783 UmbrellaDirs[UmbrellaDir] = Mod;
784}
785
Richard Smith3c1a41a2014-12-02 00:08:08 +0000786static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000787 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000788 default: llvm_unreachable("unknown header role");
789 case ModuleMap::NormalHeader:
790 return Module::HK_Normal;
791 case ModuleMap::PrivateHeader:
792 return Module::HK_Private;
793 case ModuleMap::TextualHeader:
794 return Module::HK_Textual;
795 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
796 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000797 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000798}
799
Richard Smith3c1a41a2014-12-02 00:08:08 +0000800void ModuleMap::addHeader(Module *Mod, Module::Header Header,
801 ModuleHeaderRole Role) {
802 if (!(Role & TextualHeader)) {
803 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
804 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
805 isCompilingModuleHeader);
806 }
807 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
Richard Smithfeb54b62014-10-23 02:01:19 +0000808
Richard Smith3c1a41a2014-12-02 00:08:08 +0000809 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
810}
811
812void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000813 // Add this as a known header so we won't implicitly add it to any
814 // umbrella directory module.
815 // FIXME: Should we only exclude it from umbrella modules within the
816 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000817 (void) Headers[Header.Entry];
818
819 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000820}
821
Douglas Gregor514b6362011-11-29 19:06:37 +0000822const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000823ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000824 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000825 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000826
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000827 return SourceMgr.getFileEntryForID(
828 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000829}
830
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000831const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000832 if (M->IsInferred) {
833 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
834 return InferredModuleAllowedBy.find(M)->second;
835 }
836 return getContainingModuleMapFile(M);
837}
838
839void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
840 assert(M->IsInferred && "module not inferred");
841 InferredModuleAllowedBy[M] = ModMap;
842}
843
Douglas Gregor718292f2011-11-11 19:10:28 +0000844void ModuleMap::dump() {
845 llvm::errs() << "Modules:";
846 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
847 MEnd = Modules.end();
848 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000849 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000850
851 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000852 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000853 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000854 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
855 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
856 E = H->second.end();
857 I != E; ++I) {
858 if (I != H->second.begin())
859 llvm::errs() << ",";
860 llvm::errs() << I->getModule()->getFullModuleName();
861 }
862 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000863 }
864}
865
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000866bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
867 bool HadError = false;
868 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
869 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
870 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000871 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000872 Mod->Exports.push_back(Export);
873 else
874 HadError = true;
875 }
876 Mod->UnresolvedExports.clear();
877 return HadError;
878}
879
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000880bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
881 bool HadError = false;
882 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
883 Module *DirectUse =
884 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
885 if (DirectUse)
886 Mod->DirectUses.push_back(DirectUse);
887 else
888 HadError = true;
889 }
890 Mod->UnresolvedDirectUses.clear();
891 return HadError;
892}
893
Douglas Gregorfb912652013-03-20 21:10:35 +0000894bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
895 bool HadError = false;
896 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
897 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
898 Mod, Complain);
899 if (!OtherMod) {
900 HadError = true;
901 continue;
902 }
903
904 Module::Conflict Conflict;
905 Conflict.Other = OtherMod;
906 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
907 Mod->Conflicts.push_back(Conflict);
908 }
909 Mod->UnresolvedConflicts.clear();
910 return HadError;
911}
912
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000913Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
914 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000915 return nullptr;
916
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000917 // Use the expansion location to determine which module we're in.
918 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
919 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000920 return nullptr;
921
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000922 const SourceManager &SrcMgr = Loc.getManager();
923 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000924
Douglas Gregor224d8a72012-01-06 17:19:32 +0000925 while (const FileEntry *ExpansionFile
926 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
927 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000928 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000929 return Mod;
930
931 // No module owns this header, so look up the inclusion chain to see if
932 // any included header has an associated module.
933 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
934 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000935 return nullptr;
936
Douglas Gregor224d8a72012-01-06 17:19:32 +0000937 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
938 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000939
940 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000941}
942
Douglas Gregor718292f2011-11-11 19:10:28 +0000943//----------------------------------------------------------------------------//
944// Module map file parser
945//----------------------------------------------------------------------------//
946
947namespace clang {
948 /// \brief A token in a module map file.
949 struct MMToken {
950 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000951 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000952 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000953 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000954 EndOfFile,
955 HeaderKeyword,
956 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000957 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000958 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000959 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000960 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000961 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000962 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000963 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000965 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000966 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000967 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000968 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000969 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000970 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000971 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000972 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000973 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000974 RBrace,
975 LSquare,
976 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000977 } Kind;
978
979 unsigned Location;
980 unsigned StringLength;
981 const char *StringData;
982
983 void clear() {
984 Kind = EndOfFile;
985 Location = 0;
986 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000987 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000988 }
989
990 bool is(TokenKind K) const { return Kind == K; }
991
992 SourceLocation getLocation() const {
993 return SourceLocation::getFromRawEncoding(Location);
994 }
995
996 StringRef getString() const {
997 return StringRef(StringData, StringLength);
998 }
999 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001000
Douglas Gregor718292f2011-11-11 19:10:28 +00001001 class ModuleMapParser {
1002 Lexer &L;
1003 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001004
1005 /// \brief Default target information, used only for string literal
1006 /// parsing.
1007 const TargetInfo *Target;
1008
Douglas Gregor718292f2011-11-11 19:10:28 +00001009 DiagnosticsEngine &Diags;
1010 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001011
1012 /// \brief The current module map file.
1013 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001014
Richard Smith9acb99e32014-12-10 03:09:48 +00001015 /// \brief The directory that file names in this module map file should
1016 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001017 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001018
1019 /// \brief The directory containing Clang-supplied headers.
1020 const DirectoryEntry *BuiltinIncludeDir;
1021
Douglas Gregor963c5532013-06-21 16:28:10 +00001022 /// \brief Whether this module map is in a system header directory.
1023 bool IsSystem;
1024
Douglas Gregor718292f2011-11-11 19:10:28 +00001025 /// \brief Whether an error occurred.
1026 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001027
Douglas Gregor718292f2011-11-11 19:10:28 +00001028 /// \brief Stores string data for the various string literals referenced
1029 /// during parsing.
1030 llvm::BumpPtrAllocator StringData;
1031
1032 /// \brief The current token.
1033 MMToken Tok;
1034
1035 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001036 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001037
1038 /// \brief Consume the current token and return its location.
1039 SourceLocation consumeToken();
1040
1041 /// \brief Skip tokens until we reach the a token with the given kind
1042 /// (or the end of the file).
1043 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001044
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001045 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001046 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001047 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001048 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001049 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001050 void parseHeaderDecl(clang::MMToken::TokenKind,
1051 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001052 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001053 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001054 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001055 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001056 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001057 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001058 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001059
1060 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001061 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001062
Douglas Gregor718292f2011-11-11 19:10:28 +00001063 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001064 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001065 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001066 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001067 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001068 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001069 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001070 const DirectoryEntry *BuiltinIncludeDir,
1071 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001072 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001073 ModuleMapFile(ModuleMapFile), Directory(Directory),
1074 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001075 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001076 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001077 Tok.clear();
1078 consumeToken();
1079 }
1080
1081 bool parseModuleMapFile();
1082 };
1083}
1084
1085SourceLocation ModuleMapParser::consumeToken() {
1086retry:
1087 SourceLocation Result = Tok.getLocation();
1088 Tok.clear();
1089
1090 Token LToken;
1091 L.LexFromRawLexer(LToken);
1092 Tok.Location = LToken.getLocation().getRawEncoding();
1093 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001094 case tok::raw_identifier: {
1095 StringRef RI = LToken.getRawIdentifier();
1096 Tok.StringData = RI.data();
1097 Tok.StringLength = RI.size();
1098 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001099 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001100 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001101 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001102 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001103 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001104 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001105 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001106 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001107 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001108 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001109 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001110 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001111 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001112 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001113 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001114 .Default(MMToken::Identifier);
1115 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001116 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001117
1118 case tok::comma:
1119 Tok.Kind = MMToken::Comma;
1120 break;
1121
Douglas Gregor718292f2011-11-11 19:10:28 +00001122 case tok::eof:
1123 Tok.Kind = MMToken::EndOfFile;
1124 break;
1125
1126 case tok::l_brace:
1127 Tok.Kind = MMToken::LBrace;
1128 break;
1129
Douglas Gregora686e1b2012-01-27 19:52:33 +00001130 case tok::l_square:
1131 Tok.Kind = MMToken::LSquare;
1132 break;
1133
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001134 case tok::period:
1135 Tok.Kind = MMToken::Period;
1136 break;
1137
Douglas Gregor718292f2011-11-11 19:10:28 +00001138 case tok::r_brace:
1139 Tok.Kind = MMToken::RBrace;
1140 break;
1141
Douglas Gregora686e1b2012-01-27 19:52:33 +00001142 case tok::r_square:
1143 Tok.Kind = MMToken::RSquare;
1144 break;
1145
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001146 case tok::star:
1147 Tok.Kind = MMToken::Star;
1148 break;
1149
Richard Smitha3feee22013-10-28 22:18:19 +00001150 case tok::exclaim:
1151 Tok.Kind = MMToken::Exclaim;
1152 break;
1153
Douglas Gregor718292f2011-11-11 19:10:28 +00001154 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001155 if (LToken.hasUDSuffix()) {
1156 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1157 HadError = true;
1158 goto retry;
1159 }
1160
Douglas Gregor718292f2011-11-11 19:10:28 +00001161 // Parse the string literal.
1162 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001163 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001164 if (StringLiteral.hadError)
1165 goto retry;
1166
1167 // Copy the string literal into our string data allocator.
1168 unsigned Length = StringLiteral.GetStringLength();
1169 char *Saved = StringData.Allocate<char>(Length + 1);
1170 memcpy(Saved, StringLiteral.GetString().data(), Length);
1171 Saved[Length] = 0;
1172
1173 // Form the token.
1174 Tok.Kind = MMToken::StringLiteral;
1175 Tok.StringData = Saved;
1176 Tok.StringLength = Length;
1177 break;
1178 }
1179
1180 case tok::comment:
1181 goto retry;
1182
1183 default:
1184 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1185 HadError = true;
1186 goto retry;
1187 }
1188
1189 return Result;
1190}
1191
1192void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1193 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001194 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001195 do {
1196 switch (Tok.Kind) {
1197 case MMToken::EndOfFile:
1198 return;
1199
1200 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001201 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001202 return;
1203
1204 ++braceDepth;
1205 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001206
1207 case MMToken::LSquare:
1208 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1209 return;
1210
1211 ++squareDepth;
1212 break;
1213
Douglas Gregor718292f2011-11-11 19:10:28 +00001214 case MMToken::RBrace:
1215 if (braceDepth > 0)
1216 --braceDepth;
1217 else if (Tok.is(K))
1218 return;
1219 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001220
1221 case MMToken::RSquare:
1222 if (squareDepth > 0)
1223 --squareDepth;
1224 else if (Tok.is(K))
1225 return;
1226 break;
1227
Douglas Gregor718292f2011-11-11 19:10:28 +00001228 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001229 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001230 return;
1231 break;
1232 }
1233
1234 consumeToken();
1235 } while (true);
1236}
1237
Douglas Gregore7ab3662011-12-07 02:23:45 +00001238/// \brief Parse a module-id.
1239///
1240/// module-id:
1241/// identifier
1242/// identifier '.' module-id
1243///
1244/// \returns true if an error occurred, false otherwise.
1245bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1246 Id.clear();
1247 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001248 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001249 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1250 consumeToken();
1251 } else {
1252 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1253 return true;
1254 }
1255
1256 if (!Tok.is(MMToken::Period))
1257 break;
1258
1259 consumeToken();
1260 } while (true);
1261
1262 return false;
1263}
1264
Douglas Gregora686e1b2012-01-27 19:52:33 +00001265namespace {
1266 /// \brief Enumerates the known attributes.
1267 enum AttributeKind {
1268 /// \brief An unknown attribute.
1269 AT_unknown,
1270 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001271 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001272 /// \brief The 'extern_c' attribute.
1273 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001274 /// \brief The 'exhaustive' attribute.
1275 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001276 };
1277}
1278
Douglas Gregor718292f2011-11-11 19:10:28 +00001279/// \brief Parse a module declaration.
1280///
1281/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001282/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001283/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1284/// { module-member* }
1285///
Douglas Gregor718292f2011-11-11 19:10:28 +00001286/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001287/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001288/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001289/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001290/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001291/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001292///
1293/// submodule-declaration:
1294/// module-declaration
1295/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001296void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001297 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001298 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1299 if (Tok.is(MMToken::ExternKeyword)) {
1300 parseExternModuleDecl();
1301 return;
1302 }
1303
Douglas Gregorf2161a72011-12-06 17:16:41 +00001304 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001305 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001306 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001307 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001308
Douglas Gregorf2161a72011-12-06 17:16:41 +00001309 // Parse 'explicit' keyword, if present.
1310 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001311 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001312 Explicit = true;
1313 }
1314
1315 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001316 if (Tok.is(MMToken::FrameworkKeyword)) {
1317 consumeToken();
1318 Framework = true;
1319 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001320
1321 // Parse 'module' keyword.
1322 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001323 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001324 consumeToken();
1325 HadError = true;
1326 return;
1327 }
1328 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001329
1330 // If we have a wildcard for the module name, this is an inferred submodule.
1331 // Parse it.
1332 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001333 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001334
1335 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001336 ModuleId Id;
1337 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001338 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001339 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001340 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001341
Douglas Gregore7ab3662011-12-07 02:23:45 +00001342 if (ActiveModule) {
1343 if (Id.size() > 1) {
1344 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1345 << SourceRange(Id.front().second, Id.back().second);
1346
1347 HadError = true;
1348 return;
1349 }
1350 } else if (Id.size() == 1 && Explicit) {
1351 // Top-level modules can't be explicit.
1352 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1353 Explicit = false;
1354 ExplicitLoc = SourceLocation();
1355 HadError = true;
1356 }
1357
1358 Module *PreviousActiveModule = ActiveModule;
1359 if (Id.size() > 1) {
1360 // This module map defines a submodule. Go find the module of which it
1361 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001362 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001363 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001364 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1365 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001366 if (I == 0)
1367 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001368 ActiveModule = Next;
1369 continue;
1370 }
1371
1372 if (ActiveModule) {
1373 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001374 << Id[I].first
1375 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001376 } else {
1377 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1378 }
1379 HadError = true;
1380 return;
1381 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001382
1383 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1384 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1385 "submodule defined in same file as 'module *' that allowed its "
1386 "top-level module");
1387 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1388 }
1389 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001390
1391 StringRef ModuleName = Id.back().first;
1392 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001393
Douglas Gregora686e1b2012-01-27 19:52:33 +00001394 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001395 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001396 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001397
Douglas Gregor718292f2011-11-11 19:10:28 +00001398 // Parse the opening brace.
1399 if (!Tok.is(MMToken::LBrace)) {
1400 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1401 << ModuleName;
1402 HadError = true;
1403 return;
1404 }
1405 SourceLocation LBraceLoc = consumeToken();
1406
1407 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001408 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001409 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1410 // Skip the module definition.
1411 skipUntil(MMToken::RBrace);
1412 if (Tok.is(MMToken::RBrace))
1413 consumeToken();
1414 else {
1415 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1416 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1417 HadError = true;
1418 }
1419 return;
1420 }
1421
Douglas Gregor718292f2011-11-11 19:10:28 +00001422 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1423 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001424 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001425
1426 // Skip the module definition.
1427 skipUntil(MMToken::RBrace);
1428 if (Tok.is(MMToken::RBrace))
1429 consumeToken();
1430
1431 HadError = true;
1432 return;
1433 }
1434
1435 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001436 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1437 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001438 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001439 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001440 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001441 if (Attrs.IsExternC)
1442 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001443 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001444
Douglas Gregor718292f2011-11-11 19:10:28 +00001445 bool Done = false;
1446 do {
1447 switch (Tok.Kind) {
1448 case MMToken::EndOfFile:
1449 case MMToken::RBrace:
1450 Done = true;
1451 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001452
1453 case MMToken::ConfigMacros:
1454 parseConfigMacros();
1455 break;
1456
Douglas Gregorfb912652013-03-20 21:10:35 +00001457 case MMToken::Conflict:
1458 parseConflict();
1459 break;
1460
Douglas Gregor718292f2011-11-11 19:10:28 +00001461 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001462 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001463 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001464 case MMToken::ModuleKeyword:
1465 parseModuleDecl();
1466 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001467
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001468 case MMToken::ExportKeyword:
1469 parseExportDecl();
1470 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001471
1472 case MMToken::UseKeyword:
1473 parseUseDecl();
1474 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001475
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001476 case MMToken::RequiresKeyword:
1477 parseRequiresDecl();
1478 break;
1479
Richard Smith202210b2014-10-24 20:23:01 +00001480 case MMToken::TextualKeyword:
1481 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001482 break;
Richard Smith306d8922014-10-22 23:50:56 +00001483
Douglas Gregor524e33e2011-12-08 19:11:24 +00001484 case MMToken::UmbrellaKeyword: {
1485 SourceLocation UmbrellaLoc = consumeToken();
1486 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001487 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001488 else
1489 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001490 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001491 }
Richard Smith202210b2014-10-24 20:23:01 +00001492
1493 case MMToken::ExcludeKeyword:
1494 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001495 break;
Richard Smith202210b2014-10-24 20:23:01 +00001496
1497 case MMToken::PrivateKeyword:
1498 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001499 break;
Richard Smith202210b2014-10-24 20:23:01 +00001500
Douglas Gregor322f6332011-12-08 18:00:48 +00001501 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001502 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001503 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001504
1505 case MMToken::LinkKeyword:
1506 parseLinkDecl();
1507 break;
1508
Douglas Gregor718292f2011-11-11 19:10:28 +00001509 default:
1510 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1511 consumeToken();
1512 break;
1513 }
1514 } while (!Done);
1515
1516 if (Tok.is(MMToken::RBrace))
1517 consumeToken();
1518 else {
1519 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1520 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1521 HadError = true;
1522 }
1523
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001524 // If the active module is a top-level framework, and there are no link
1525 // libraries, automatically link against the framework.
1526 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1527 ActiveModule->LinkLibraries.empty()) {
1528 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1529 }
1530
Ben Langmuirec8c9752014-04-18 22:07:31 +00001531 // If the module meets all requirements but is still unavailable, mark the
1532 // whole tree as unavailable to prevent it from building.
1533 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1534 ActiveModule->Parent) {
1535 ActiveModule->getTopLevelModule()->markUnavailable();
1536 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1537 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1538 }
1539
Douglas Gregore7ab3662011-12-07 02:23:45 +00001540 // We're done parsing this module. Pop back to the previous module.
1541 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001542}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001543
Daniel Jasper97292842013-09-11 07:20:44 +00001544/// \brief Parse an extern module declaration.
1545///
1546/// extern module-declaration:
1547/// 'extern' 'module' module-id string-literal
1548void ModuleMapParser::parseExternModuleDecl() {
1549 assert(Tok.is(MMToken::ExternKeyword));
1550 consumeToken(); // 'extern' keyword
1551
1552 // Parse 'module' keyword.
1553 if (!Tok.is(MMToken::ModuleKeyword)) {
1554 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1555 consumeToken();
1556 HadError = true;
1557 return;
1558 }
1559 consumeToken(); // 'module' keyword
1560
1561 // Parse the module name.
1562 ModuleId Id;
1563 if (parseModuleId(Id)) {
1564 HadError = true;
1565 return;
1566 }
1567
1568 // Parse the referenced module map file name.
1569 if (!Tok.is(MMToken::StringLiteral)) {
1570 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1571 HadError = true;
1572 return;
1573 }
1574 std::string FileName = Tok.getString();
1575 consumeToken(); // filename
1576
1577 StringRef FileNameRef = FileName;
1578 SmallString<128> ModuleMapFileName;
1579 if (llvm::sys::path::is_relative(FileNameRef)) {
1580 ModuleMapFileName += Directory->getName();
1581 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001582 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001583 }
1584 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001585 Map.parseModuleMapFile(
1586 File, /*IsSystem=*/false,
1587 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1588 ? Directory
1589 : File->getDir());
Daniel Jasper97292842013-09-11 07:20:44 +00001590}
1591
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001592/// \brief Parse a requires declaration.
1593///
1594/// requires-declaration:
1595/// 'requires' feature-list
1596///
1597/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001598/// feature ',' feature-list
1599/// feature
1600///
1601/// feature:
1602/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001603void ModuleMapParser::parseRequiresDecl() {
1604 assert(Tok.is(MMToken::RequiresKeyword));
1605
1606 // Parse 'requires' keyword.
1607 consumeToken();
1608
1609 // Parse the feature-list.
1610 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001611 bool RequiredState = true;
1612 if (Tok.is(MMToken::Exclaim)) {
1613 RequiredState = false;
1614 consumeToken();
1615 }
1616
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001617 if (!Tok.is(MMToken::Identifier)) {
1618 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1619 HadError = true;
1620 return;
1621 }
1622
1623 // Consume the feature name.
1624 std::string Feature = Tok.getString();
1625 consumeToken();
1626
1627 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001628 ActiveModule->addRequirement(Feature, RequiredState,
1629 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001630
1631 if (!Tok.is(MMToken::Comma))
1632 break;
1633
1634 // Consume the comma.
1635 consumeToken();
1636 } while (true);
1637}
1638
Douglas Gregorf2161a72011-12-06 17:16:41 +00001639/// \brief Append to \p Paths the set of paths needed to get to the
1640/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001641static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001642 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001643 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001644 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001645 for (; Mod; Mod = Mod->Parent) {
1646 if (Mod->IsFramework)
1647 Paths.push_back(Mod->Name);
1648 }
1649
1650 if (Paths.empty())
1651 return;
1652
1653 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001654 for (unsigned I = Paths.size() - 1; I != 0; --I)
1655 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001656}
1657
Douglas Gregor718292f2011-11-11 19:10:28 +00001658/// \brief Parse a header declaration.
1659///
1660/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001661/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001662/// 'private' 'textual'[opt] 'header' string-literal
1663/// 'exclude' 'header' string-literal
1664/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001665///
1666/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001667void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1668 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001669 // We've already consumed the first token.
1670 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1671 if (LeadingToken == MMToken::PrivateKeyword) {
1672 Role = ModuleMap::PrivateHeader;
1673 // 'private' may optionally be followed by 'textual'.
1674 if (Tok.is(MMToken::TextualKeyword)) {
1675 LeadingToken = Tok.Kind;
1676 consumeToken();
1677 }
1678 }
1679 if (LeadingToken == MMToken::TextualKeyword)
1680 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1681
1682 if (LeadingToken != MMToken::HeaderKeyword) {
1683 if (!Tok.is(MMToken::HeaderKeyword)) {
1684 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1685 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1686 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1687 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1688 return;
1689 }
1690 consumeToken();
1691 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001692
Douglas Gregor718292f2011-11-11 19:10:28 +00001693 // Parse the header name.
1694 if (!Tok.is(MMToken::StringLiteral)) {
1695 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1696 << "header";
1697 HadError = true;
1698 return;
1699 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001700 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001701 Header.FileName = Tok.getString();
1702 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001703
Douglas Gregor524e33e2011-12-08 19:11:24 +00001704 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001705 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001706 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001707 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001708 HadError = true;
1709 return;
1710 }
1711
Douglas Gregor5257fc62011-11-11 21:55:48 +00001712 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001713 const FileEntry *File = nullptr;
1714 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001715 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001716 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001717 RelativePathName = Header.FileName;
1718 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001719 } else {
1720 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001721 SmallString<128> FullPathName(Directory->getName());
1722 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001723
Douglas Gregorf2161a72011-12-06 17:16:41 +00001724 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001725 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001726
1727 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001728 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001729 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001730 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001731
1732 if (!File) {
1733 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001734 // FIXME: Should we retain the subframework paths here?
1735 RelativePathName.clear();
1736 FullPathName.resize(FullPathLength);
1737 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1738 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001739 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001740 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001741 }
1742 } else {
1743 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001744 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001745 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001746 File = SourceMgr.getFileManager().getFile(FullPathName);
1747
Douglas Gregor3ec66632012-02-02 18:42:48 +00001748 // If this is a system module with a top-level header, this header
1749 // may have a counterpart (or replacement) in the set of headers
1750 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001751 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1752 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001753 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001754 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001755 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001756 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001757
Douglas Gregor3ec66632012-02-02 18:42:48 +00001758 // If Clang supplies this header but the underlying system does not,
1759 // just silently swap in our builtin version. Otherwise, we'll end
1760 // up adding both (later).
1761 if (!File && BuiltinFile) {
1762 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001763 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001764 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001765 }
1766 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001767 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001768 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001769
Douglas Gregor5257fc62011-11-11 21:55:48 +00001770 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1771 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001772 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001773 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001774 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001775 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001776 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001777 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001778 HadError = true;
1779 } else {
1780 // Record this umbrella header.
1781 Map.setUmbrellaHeader(ActiveModule, File);
1782 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001783 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001784 Module::Header H = {RelativePathName.str(), File};
1785 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001786 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001787 // If there is a builtin counterpart to this file, add it now, before
1788 // the "real" header, so we build the built-in one first when building
1789 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001790 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001791 // FIXME: Taking the name from the FileEntry is unstable and can give
1792 // different results depending on how we've previously named that file
1793 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001794 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1795 Map.addHeader(ActiveModule, H, Role);
1796 }
Richard Smith25d50752014-10-20 00:15:49 +00001797
Richard Smith202210b2014-10-24 20:23:01 +00001798 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001799 Module::Header H = { RelativePathName.str(), File };
1800 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001801 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001802 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001803 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001804
1805 // If we find a module that has a missing header, we mark this module as
1806 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001807 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001808 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001809 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001810 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001811}
1812
Douglas Gregor524e33e2011-12-08 19:11:24 +00001813/// \brief Parse an umbrella directory declaration.
1814///
1815/// umbrella-dir-declaration:
1816/// umbrella string-literal
1817void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1818 // Parse the directory name.
1819 if (!Tok.is(MMToken::StringLiteral)) {
1820 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1821 << "umbrella";
1822 HadError = true;
1823 return;
1824 }
1825
1826 std::string DirName = Tok.getString();
1827 SourceLocation DirNameLoc = consumeToken();
1828
1829 // Check whether we already have an umbrella.
1830 if (ActiveModule->Umbrella) {
1831 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1832 << ActiveModule->getFullModuleName();
1833 HadError = true;
1834 return;
1835 }
1836
1837 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001838 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001839 if (llvm::sys::path::is_absolute(DirName))
1840 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1841 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001842 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001843 PathName = Directory->getName();
1844 llvm::sys::path::append(PathName, DirName);
1845 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1846 }
1847
1848 if (!Dir) {
1849 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1850 << DirName;
1851 HadError = true;
1852 return;
1853 }
1854
1855 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1856 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1857 << OwningModule->getFullModuleName();
1858 HadError = true;
1859 return;
1860 }
1861
1862 // Record this umbrella directory.
1863 Map.setUmbrellaDir(ActiveModule, Dir);
1864}
1865
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001866/// \brief Parse a module export declaration.
1867///
1868/// export-declaration:
1869/// 'export' wildcard-module-id
1870///
1871/// wildcard-module-id:
1872/// identifier
1873/// '*'
1874/// identifier '.' wildcard-module-id
1875void ModuleMapParser::parseExportDecl() {
1876 assert(Tok.is(MMToken::ExportKeyword));
1877 SourceLocation ExportLoc = consumeToken();
1878
1879 // Parse the module-id with an optional wildcard at the end.
1880 ModuleId ParsedModuleId;
1881 bool Wildcard = false;
1882 do {
Richard Smith306d8922014-10-22 23:50:56 +00001883 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001884 if (Tok.is(MMToken::Identifier)) {
1885 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1886 Tok.getLocation()));
1887 consumeToken();
1888
1889 if (Tok.is(MMToken::Period)) {
1890 consumeToken();
1891 continue;
1892 }
1893
1894 break;
1895 }
1896
1897 if(Tok.is(MMToken::Star)) {
1898 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001899 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001900 break;
1901 }
1902
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001903 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001904 HadError = true;
1905 return;
1906 } while (true);
1907
1908 Module::UnresolvedExportDecl Unresolved = {
1909 ExportLoc, ParsedModuleId, Wildcard
1910 };
1911 ActiveModule->UnresolvedExports.push_back(Unresolved);
1912}
1913
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001914/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001915///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001916/// use-declaration:
1917/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001918void ModuleMapParser::parseUseDecl() {
1919 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001920 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001921 // Parse the module-id.
1922 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001923 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001924
Richard Smith8f4d3ff2015-03-26 22:10:01 +00001925 if (ActiveModule->Parent)
1926 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
1927 else
1928 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001929}
1930
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001931/// \brief Parse a link declaration.
1932///
1933/// module-declaration:
1934/// 'link' 'framework'[opt] string-literal
1935void ModuleMapParser::parseLinkDecl() {
1936 assert(Tok.is(MMToken::LinkKeyword));
1937 SourceLocation LinkLoc = consumeToken();
1938
1939 // Parse the optional 'framework' keyword.
1940 bool IsFramework = false;
1941 if (Tok.is(MMToken::FrameworkKeyword)) {
1942 consumeToken();
1943 IsFramework = true;
1944 }
1945
1946 // Parse the library name
1947 if (!Tok.is(MMToken::StringLiteral)) {
1948 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1949 << IsFramework << SourceRange(LinkLoc);
1950 HadError = true;
1951 return;
1952 }
1953
1954 std::string LibraryName = Tok.getString();
1955 consumeToken();
1956 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1957 IsFramework));
1958}
1959
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001960/// \brief Parse a configuration macro declaration.
1961///
1962/// module-declaration:
1963/// 'config_macros' attributes[opt] config-macro-list?
1964///
1965/// config-macro-list:
1966/// identifier (',' identifier)?
1967void ModuleMapParser::parseConfigMacros() {
1968 assert(Tok.is(MMToken::ConfigMacros));
1969 SourceLocation ConfigMacrosLoc = consumeToken();
1970
1971 // Only top-level modules can have configuration macros.
1972 if (ActiveModule->Parent) {
1973 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1974 }
1975
1976 // Parse the optional attributes.
1977 Attributes Attrs;
1978 parseOptionalAttributes(Attrs);
1979 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1980 ActiveModule->ConfigMacrosExhaustive = true;
1981 }
1982
1983 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001984 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001985 if (!Tok.is(MMToken::Identifier))
1986 return;
1987
1988 // Consume the first identifier.
1989 if (!ActiveModule->Parent) {
1990 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1991 }
1992 consumeToken();
1993
1994 do {
1995 // If there's a comma, consume it.
1996 if (!Tok.is(MMToken::Comma))
1997 break;
1998 consumeToken();
1999
2000 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002001 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002002 if (!Tok.is(MMToken::Identifier)) {
2003 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2004 break;
2005 }
2006
2007 // Consume the macro name.
2008 if (!ActiveModule->Parent) {
2009 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2010 }
2011 consumeToken();
2012 } while (true);
2013}
2014
Douglas Gregorfb912652013-03-20 21:10:35 +00002015/// \brief Format a module-id into a string.
2016static std::string formatModuleId(const ModuleId &Id) {
2017 std::string result;
2018 {
2019 llvm::raw_string_ostream OS(result);
2020
2021 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2022 if (I)
2023 OS << ".";
2024 OS << Id[I].first;
2025 }
2026 }
2027
2028 return result;
2029}
2030
2031/// \brief Parse a conflict declaration.
2032///
2033/// module-declaration:
2034/// 'conflict' module-id ',' string-literal
2035void ModuleMapParser::parseConflict() {
2036 assert(Tok.is(MMToken::Conflict));
2037 SourceLocation ConflictLoc = consumeToken();
2038 Module::UnresolvedConflict Conflict;
2039
2040 // Parse the module-id.
2041 if (parseModuleId(Conflict.Id))
2042 return;
2043
2044 // Parse the ','.
2045 if (!Tok.is(MMToken::Comma)) {
2046 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2047 << SourceRange(ConflictLoc);
2048 return;
2049 }
2050 consumeToken();
2051
2052 // Parse the message.
2053 if (!Tok.is(MMToken::StringLiteral)) {
2054 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2055 << formatModuleId(Conflict.Id);
2056 return;
2057 }
2058 Conflict.Message = Tok.getString().str();
2059 consumeToken();
2060
2061 // Add this unresolved conflict.
2062 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2063}
2064
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002065/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002066///
2067/// module-declaration:
2068/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2069/// { inferred-module-member* }
2070///
2071/// inferred-module-member:
2072/// 'export' '*'
2073/// 'exclude' identifier
2074void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002075 assert(Tok.is(MMToken::Star));
2076 SourceLocation StarLoc = consumeToken();
2077 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002078
Douglas Gregor73441092011-12-05 22:27:44 +00002079 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002080 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002081 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2082 Failed = true;
2083 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002084
2085 if (ActiveModule) {
2086 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002087 if (!Failed && ActiveModule->IsAvailable &&
2088 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002089 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2090 Failed = true;
2091 }
2092
2093 // Check for redefinition of an inferred module.
2094 if (!Failed && ActiveModule->InferSubmodules) {
2095 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2096 if (ActiveModule->InferredSubmoduleLoc.isValid())
2097 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2098 diag::note_mmap_prev_definition);
2099 Failed = true;
2100 }
2101
2102 // Check for the 'framework' keyword, which is not permitted here.
2103 if (Framework) {
2104 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2105 Framework = false;
2106 }
2107 } else if (Explicit) {
2108 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2109 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002110 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002111
Douglas Gregor73441092011-12-05 22:27:44 +00002112 // If there were any problems with this inferred submodule, skip its body.
2113 if (Failed) {
2114 if (Tok.is(MMToken::LBrace)) {
2115 consumeToken();
2116 skipUntil(MMToken::RBrace);
2117 if (Tok.is(MMToken::RBrace))
2118 consumeToken();
2119 }
2120 HadError = true;
2121 return;
2122 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002123
2124 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002125 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002126 parseOptionalAttributes(Attrs);
2127
2128 if (ActiveModule) {
2129 // Note that we have an inferred submodule.
2130 ActiveModule->InferSubmodules = true;
2131 ActiveModule->InferredSubmoduleLoc = StarLoc;
2132 ActiveModule->InferExplicitSubmodules = Explicit;
2133 } else {
2134 // We'll be inferring framework modules for this directory.
2135 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002136 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002137 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002138 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002139 }
2140
Douglas Gregor73441092011-12-05 22:27:44 +00002141 // Parse the opening brace.
2142 if (!Tok.is(MMToken::LBrace)) {
2143 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2144 HadError = true;
2145 return;
2146 }
2147 SourceLocation LBraceLoc = consumeToken();
2148
2149 // Parse the body of the inferred submodule.
2150 bool Done = false;
2151 do {
2152 switch (Tok.Kind) {
2153 case MMToken::EndOfFile:
2154 case MMToken::RBrace:
2155 Done = true;
2156 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002157
2158 case MMToken::ExcludeKeyword: {
2159 if (ActiveModule) {
2160 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002161 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002162 consumeToken();
2163 break;
2164 }
2165
2166 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002167 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002168 if (!Tok.is(MMToken::Identifier)) {
2169 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2170 break;
2171 }
2172
2173 Map.InferredDirectories[Directory].ExcludedModules
2174 .push_back(Tok.getString());
2175 consumeToken();
2176 break;
2177 }
2178
2179 case MMToken::ExportKeyword:
2180 if (!ActiveModule) {
2181 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002182 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002183 consumeToken();
2184 break;
2185 }
2186
Douglas Gregor73441092011-12-05 22:27:44 +00002187 consumeToken();
2188 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002189 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002190 else
2191 Diags.Report(Tok.getLocation(),
2192 diag::err_mmap_expected_export_wildcard);
2193 consumeToken();
2194 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002195
Douglas Gregor73441092011-12-05 22:27:44 +00002196 case MMToken::ExplicitKeyword:
2197 case MMToken::ModuleKeyword:
2198 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002199 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002200 case MMToken::UmbrellaKeyword:
2201 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002202 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002203 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002204 consumeToken();
2205 break;
2206 }
2207 } while (!Done);
2208
2209 if (Tok.is(MMToken::RBrace))
2210 consumeToken();
2211 else {
2212 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2213 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2214 HadError = true;
2215 }
2216}
2217
Douglas Gregor9194a912012-11-06 19:39:40 +00002218/// \brief Parse optional attributes.
2219///
2220/// attributes:
2221/// attribute attributes
2222/// attribute
2223///
2224/// attribute:
2225/// [ identifier ]
2226///
2227/// \param Attrs Will be filled in with the parsed attributes.
2228///
2229/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002230bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002231 bool HadError = false;
2232
2233 while (Tok.is(MMToken::LSquare)) {
2234 // Consume the '['.
2235 SourceLocation LSquareLoc = consumeToken();
2236
2237 // Check whether we have an attribute name here.
2238 if (!Tok.is(MMToken::Identifier)) {
2239 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2240 skipUntil(MMToken::RSquare);
2241 if (Tok.is(MMToken::RSquare))
2242 consumeToken();
2243 HadError = true;
2244 }
2245
2246 // Decode the attribute name.
2247 AttributeKind Attribute
2248 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002249 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002250 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002251 .Case("system", AT_system)
2252 .Default(AT_unknown);
2253 switch (Attribute) {
2254 case AT_unknown:
2255 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2256 << Tok.getString();
2257 break;
2258
2259 case AT_system:
2260 Attrs.IsSystem = true;
2261 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002262
Richard Smith77944862014-03-02 05:58:18 +00002263 case AT_extern_c:
2264 Attrs.IsExternC = true;
2265 break;
2266
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002267 case AT_exhaustive:
2268 Attrs.IsExhaustive = true;
2269 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002270 }
2271 consumeToken();
2272
2273 // Consume the ']'.
2274 if (!Tok.is(MMToken::RSquare)) {
2275 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2276 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2277 skipUntil(MMToken::RSquare);
2278 HadError = true;
2279 }
2280
2281 if (Tok.is(MMToken::RSquare))
2282 consumeToken();
2283 }
2284
2285 return HadError;
2286}
2287
Douglas Gregor718292f2011-11-11 19:10:28 +00002288/// \brief Parse a module map file.
2289///
2290/// module-map-file:
2291/// module-declaration*
2292bool ModuleMapParser::parseModuleMapFile() {
2293 do {
2294 switch (Tok.Kind) {
2295 case MMToken::EndOfFile:
2296 return HadError;
2297
Douglas Gregore7ab3662011-12-07 02:23:45 +00002298 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002299 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002300 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002301 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002302 parseModuleDecl();
2303 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002304
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002305 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002306 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002307 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002308 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002309 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002310 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002311 case MMToken::HeaderKeyword:
2312 case MMToken::Identifier:
2313 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002314 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002315 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002316 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002317 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002318 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002319 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002320 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002321 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002322 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002323 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002324 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002325 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002326 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2327 HadError = true;
2328 consumeToken();
2329 break;
2330 }
2331 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002332}
2333
Richard Smith9acb99e32014-12-10 03:09:48 +00002334bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2335 const DirectoryEntry *Dir) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002336 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2337 = ParsedModuleMap.find(File);
2338 if (Known != ParsedModuleMap.end())
2339 return Known->second;
2340
Craig Topperd2d442c2014-05-17 23:10:59 +00002341 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002342 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2343 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002344 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002345 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002346 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002347
Douglas Gregor718292f2011-11-11 19:10:28 +00002348 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002349 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002350 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002351 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002352 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002353 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002354 return Result;
2355}