blob: b4fe98488bc207a21c15619c7c77959b4e4cc9ae [file] [log] [blame]
Douglas Gregor718292f2011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Richard Smith9acb99e32014-12-10 03:09:48 +000022#include "clang/Lex/HeaderSearchOptions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000023#include "clang/Lex/LexDiagnostic.h"
24#include "clang/Lex/Lexer.h"
25#include "clang/Lex/LiteralSupport.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000028#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000029#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000030#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000031#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000032#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000033#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000034#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000035#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000036#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000037using namespace clang;
38
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000039Module::ExportDecl
40ModuleMap::resolveExport(Module *Mod,
41 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000042 bool Complain) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +000043 // We may have just a wildcard.
44 if (Unresolved.Id.empty()) {
45 assert(Unresolved.Wildcard && "Invalid unresolved export");
Craig Topperd2d442c2014-05-17 23:10:59 +000046 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +000047 }
48
Douglas Gregorfb912652013-03-20 21:10:35 +000049 // Resolve the module-id.
50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
51 if (!Context)
52 return Module::ExportDecl();
53
54 return Module::ExportDecl(Context, Unresolved.Wildcard);
55}
56
57Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
58 bool Complain) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000059 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000060 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000061 if (!Context) {
62 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000063 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000064 << Id[0].first << Mod->getFullModuleName();
65
Craig Topperd2d442c2014-05-17 23:10:59 +000066 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000067 }
68
69 // Dig into the module path.
Douglas Gregorfb912652013-03-20 21:10:35 +000070 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
71 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000072 if (!Sub) {
73 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000074 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000075 << Id[I].first << Context->getFullModuleName()
76 << SourceRange(Id[0].second, Id[I-1].second);
77
Craig Topperd2d442c2014-05-17 23:10:59 +000078 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000079 }
Douglas Gregorfb912652013-03-20 21:10:35 +000080
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000081 Context = Sub;
82 }
Douglas Gregorfb912652013-03-20 21:10:35 +000083
84 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000085}
86
Daniel Jasper0761a8a2013-12-17 10:31:37 +000087ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000088 const LangOptions &LangOpts, const TargetInfo *Target,
89 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000090 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Craig Topperd2d442c2014-05-17 23:10:59 +000091 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
Richard Smith0414b852015-02-14 05:32:00 +000092 CompilingModule(nullptr), SourceModule(nullptr) {
93 MMapLangOpts.LineComment = true;
94}
Douglas Gregor718292f2011-11-11 19:10:28 +000095
96ModuleMap::~ModuleMap() {
Douglas Gregor5acdf592011-11-17 02:05:44 +000097 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
98 IEnd = Modules.end();
99 I != IEnd; ++I) {
100 delete I->getValue();
101 }
Douglas Gregor718292f2011-11-11 19:10:28 +0000102}
103
Douglas Gregor89929282012-01-30 06:01:29 +0000104void ModuleMap::setTarget(const TargetInfo &Target) {
105 assert((!this->Target || this->Target == &Target) &&
106 "Improper target override");
107 this->Target = &Target;
108}
109
Douglas Gregor056396a2012-10-12 21:15:50 +0000110/// \brief "Sanitize" a filename so that it can be used as an identifier.
111static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
112 SmallVectorImpl<char> &Buffer) {
113 if (Name.empty())
114 return Name;
115
Jordan Rosea7d03842013-02-08 22:30:41 +0000116 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000117 // If we don't already have something with the form of an identifier,
118 // create a buffer with the sanitized name.
119 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000120 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000121 Buffer.push_back('_');
122 Buffer.reserve(Buffer.size() + Name.size());
123 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000124 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000125 Buffer.push_back(Name[I]);
126 else
127 Buffer.push_back('_');
128 }
129
130 Name = StringRef(Buffer.data(), Buffer.size());
131 }
132
133 while (llvm::StringSwitch<bool>(Name)
134#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
135#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
136#include "clang/Basic/TokenKinds.def"
137 .Default(false)) {
138 if (Name.data() != Buffer.data())
139 Buffer.append(Name.begin(), Name.end());
140 Buffer.push_back('_');
141 Name = StringRef(Buffer.data(), Buffer.size());
142 }
143
144 return Name;
145}
146
Douglas Gregor34d52742013-05-02 17:58:30 +0000147/// \brief Determine whether the given file name is the name of a builtin
148/// header, supplied by Clang to replace, override, or augment existing system
149/// headers.
150static bool isBuiltinHeader(StringRef FileName) {
151 return llvm::StringSwitch<bool>(FileName)
152 .Case("float.h", true)
153 .Case("iso646.h", true)
154 .Case("limits.h", true)
155 .Case("stdalign.h", true)
156 .Case("stdarg.h", true)
157 .Case("stdbool.h", true)
158 .Case("stddef.h", true)
159 .Case("stdint.h", true)
160 .Case("tgmath.h", true)
161 .Case("unwind.h", true)
162 .Default(false);
163}
164
Daniel Jasper92669ee2013-12-20 12:09:36 +0000165ModuleMap::HeadersMap::iterator
166ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000167 HeadersMap::iterator Known = Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000168 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
169 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
170 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000171 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000172 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000173 return Known;
174}
175
Ben Langmuir44691382014-04-10 00:39:10 +0000176ModuleMap::KnownHeader
177ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
178 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
179 const DirectoryEntry *Dir = File->getDir();
180 assert(Dir && "file in no directory");
181
182 // Note: as an egregious but useful hack we use the real path here, because
183 // frameworks moving from top-level frameworks to embedded frameworks tend
184 // to be symlinked from the top-level location to the embedded location,
185 // and we need to resolve lookups as if we had found the embedded location.
186 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
187
188 // Keep walking up the directory hierarchy, looking for a directory with
189 // an umbrella header.
190 do {
191 auto KnownDir = UmbrellaDirs.find(Dir);
192 if (KnownDir != UmbrellaDirs.end())
193 return KnownHeader(KnownDir->second, NormalHeader);
194
195 IntermediateDirs.push_back(Dir);
196
197 // Retrieve our parent path.
198 DirName = llvm::sys::path::parent_path(DirName);
199 if (DirName.empty())
200 break;
201
202 // Resolve the parent path to a directory entry.
203 Dir = SourceMgr.getFileManager().getDirectory(DirName);
204 } while (Dir);
205 return KnownHeader();
206}
207
Richard Smith202210b2014-10-24 20:23:01 +0000208// Returns true if RequestingModule directly uses RequestedModule.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000209static bool directlyUses(const Module *RequestingModule,
210 const Module *RequestedModule) {
211 return std::find(RequestingModule->DirectUses.begin(),
212 RequestingModule->DirectUses.end(),
213 RequestedModule) != RequestingModule->DirectUses.end();
214}
215
216static bool violatesPrivateInclude(Module *RequestingModule,
217 const FileEntry *IncFileEnt,
218 ModuleMap::ModuleHeaderRole Role,
219 Module *RequestedModule) {
Richard Smith202210b2014-10-24 20:23:01 +0000220 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
221#ifndef NDEBUG
Daniel Jasper92669ee2013-12-20 12:09:36 +0000222 // Check for consistency between the module header role
223 // as obtained from the lookup and as obtained from the module.
224 // This check is not cheap, so enable it only for debugging.
Richard Smith00bc95e2015-03-09 23:46:50 +0000225 auto IsInHeaderList = [&](std::initializer_list<SmallVectorImpl<
226 Module::Header>*> HeaderList) -> bool {
227 for (auto *Hs : HeaderList) {
228 if (std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
229 return H.Entry == IncFileEnt;
230 }) != Hs->end())
231 return true;
232 }
233 return false;
234 };
235 // If a header is both public and private, then it's available as a public
236 // header and that's OK.
237 // FIXME: Should we reject this when parsing the module map?
238 bool IsPrivate =
239 IsInHeaderList({&RequestedModule->Headers[Module::HK_Private],
240 &RequestedModule->Headers[Module::HK_PrivateTextual]}) &&
241 !IsInHeaderList({&RequestedModule->Headers[Module::HK_Normal],
242 &RequestedModule->Headers[Module::HK_Textual]});
Richard Smith202210b2014-10-24 20:23:01 +0000243 assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
244#endif
245 return IsPrivateRole &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000246 RequestedModule->getTopLevelModule() != RequestingModule;
247}
248
Ben Langmuir71e1a642014-05-05 21:44:13 +0000249static Module *getTopLevelOrNull(Module *M) {
250 return M ? M->getTopLevelModule() : nullptr;
251}
252
Daniel Jasper92669ee2013-12-20 12:09:36 +0000253void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
254 SourceLocation FilenameLoc,
255 StringRef Filename,
256 const FileEntry *File) {
257 // No errors for indirect modules. This may be a bit of a problem for modules
258 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000259 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000260 return;
261
262 if (RequestingModule)
263 resolveUses(RequestingModule, /*Complain=*/false);
264
Ben Langmuir71e1a642014-05-05 21:44:13 +0000265 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000266 Module *Private = nullptr;
267 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000268
Ben Langmuir71e1a642014-05-05 21:44:13 +0000269 HeadersMap::iterator Known = findKnownHeader(File);
270 if (Known != Headers.end()) {
271 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000272 // If 'File' is part of 'RequestingModule' we can definitely include it.
273 if (Header.getModule() == RequestingModule)
274 return;
275
276 // Remember private headers for later printing of a diagnostic.
277 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
278 Header.getModule())) {
279 Private = Header.getModule();
280 continue;
281 }
282
283 // If uses need to be specified explicitly, we are only allowed to return
284 // modules that are explicitly used by the requesting module.
285 if (RequestingModule && LangOpts.ModulesDeclUse &&
286 !directlyUses(RequestingModule, Header.getModule())) {
287 NotUsed = Header.getModule();
288 continue;
289 }
290
291 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000292 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000293 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000294
295 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000296 }
297
298 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000299 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000300 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000301 << Filename;
302 return;
303 }
304
305 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000306 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000307 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000308 << RequestingModule->getFullModuleName() << Filename;
309 return;
310 }
311
Ben Langmuir71e1a642014-05-05 21:44:13 +0000312 if (Excluded || isHeaderInUmbrellaDirs(File))
313 return;
314
315 // At this point, only non-modular includes remain.
316
317 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000318 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000319 << RequestingModule->getFullModuleName() << Filename;
320 } else if (RequestingModule) {
321 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
322 diag::warn_non_modular_include_in_framework_module :
323 diag::warn_non_modular_include_in_module;
324 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000325 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000326}
327
Richard Smithec87a502015-02-13 23:50:20 +0000328static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
329 const ModuleMap::KnownHeader &Old) {
330 // Prefer a public header over a private header.
331 if ((New.getRole() & ModuleMap::PrivateHeader) !=
332 (Old.getRole() & ModuleMap::PrivateHeader))
333 return !(New.getRole() & ModuleMap::PrivateHeader);
334
335 // Prefer a non-textual header over a textual header.
336 if ((New.getRole() & ModuleMap::TextualHeader) !=
337 (Old.getRole() & ModuleMap::TextualHeader))
338 return !(New.getRole() & ModuleMap::TextualHeader);
339
340 // Don't have a reason to choose between these. Just keep the first one.
341 return false;
342}
343
Daniel Jasper92669ee2013-12-20 12:09:36 +0000344ModuleMap::KnownHeader
345ModuleMap::findModuleForHeader(const FileEntry *File,
Richard Smith306d8922014-10-22 23:50:56 +0000346 Module *RequestingModule,
347 bool IncludeTextualHeaders) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000348 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000349
Richard Smith306d8922014-10-22 23:50:56 +0000350 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Richard Smith202210b2014-10-24 20:23:01 +0000351 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
Richard Smith306d8922014-10-22 23:50:56 +0000352 return ModuleMap::KnownHeader();
353 return R;
354 };
355
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000356 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000357 ModuleMap::KnownHeader Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000358
Daniel Jasper97da9172013-10-22 08:09:47 +0000359 // Iterate over all modules that 'File' is part of to find the best fit.
360 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
361 E = Known->second.end();
362 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000363 // Cannot use a module if it is unavailable.
364 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000365 continue;
366
367 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
368 // module we are looking for.
369 if (I->getModule() == RequestingModule)
Richard Smith306d8922014-10-22 23:50:56 +0000370 return MakeResult(*I);
Daniel Jasper97da9172013-10-22 08:09:47 +0000371
372 // If uses need to be specified explicitly, we are only allowed to return
373 // modules that are explicitly used by the requesting module.
374 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000375 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000376 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000377
Richard Smithec87a502015-02-13 23:50:20 +0000378 if (!Result || isBetterKnownHeader(*I, Result))
Richard Smith202210b2014-10-24 20:23:01 +0000379 Result = *I;
Daniel Jasper97da9172013-10-22 08:09:47 +0000380 }
Richard Smith306d8922014-10-22 23:50:56 +0000381 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000382 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000383
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000384 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000385 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
386 if (H) {
387 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000388
Ben Langmuir44691382014-04-10 00:39:10 +0000389 // Search up the module stack until we find a module with an umbrella
390 // directory.
391 Module *UmbrellaModule = Result;
392 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
393 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000394
Ben Langmuir44691382014-04-10 00:39:10 +0000395 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000396 const FileEntry *UmbrellaModuleMap =
397 getModuleMapFileForUniquing(UmbrellaModule);
398
Ben Langmuir44691382014-04-10 00:39:10 +0000399 // Infer submodules for each of the directories we found between
400 // the directory of the umbrella header and the directory where
401 // the actual header is located.
402 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000403
Ben Langmuir44691382014-04-10 00:39:10 +0000404 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
405 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000406 SmallString<32> NameBuf;
407 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000408 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000409 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
410 Explicit).first;
411 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000412 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000413
414 // Associate the module and the directory.
415 UmbrellaDirs[SkippedDirs[I-1]] = Result;
416
417 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000418 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000419 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000420 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000421 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000422
Ben Langmuir44691382014-04-10 00:39:10 +0000423 // Infer a submodule with the same name as this header file.
424 SmallString<32> NameBuf;
425 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000426 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000427 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
428 Explicit).first;
429 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000430 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000431 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000432
Ben Langmuir44691382014-04-10 00:39:10 +0000433 // If inferred submodules export everything they import, add a
434 // wildcard to the set of exports.
435 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000436 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000437 } else {
438 // Record each of the directories we stepped through as being part of
439 // the module we found, since the umbrella header covers them all.
440 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
441 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000442 }
Ben Langmuir44691382014-04-10 00:39:10 +0000443
444 Headers[File].push_back(KnownHeader(Result, NormalHeader));
445
446 // If a header corresponds to an unavailable module, don't report
447 // that it maps to anything.
448 if (!Result->isAvailable())
449 return KnownHeader();
450
Richard Smith306d8922014-10-22 23:50:56 +0000451 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000452 }
Richard Smith306d8922014-10-22 23:50:56 +0000453
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000454 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000455}
456
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000457bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000458 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000459}
460
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000461bool
462ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
463 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000464 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000465 if (Known != Headers.end()) {
466 for (SmallVectorImpl<KnownHeader>::const_iterator
467 I = Known->second.begin(),
468 E = Known->second.end();
469 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000470 if (I->isAvailable() && (!RequestingModule ||
471 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000472 return false;
473 }
474 return true;
475 }
Richard Smith50996ce2014-04-08 13:13:04 +0000476
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000477 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000478 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000479 StringRef DirName = Dir->getName();
480
Richard Smith50996ce2014-04-08 13:13:04 +0000481 auto IsUnavailable = [&](const Module *M) {
482 return !M->isAvailable() && (!RequestingModule ||
483 M->isSubModuleOf(RequestingModule));
484 };
485
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000486 // Keep walking up the directory hierarchy, looking for a directory with
487 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000488 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000489 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 = UmbrellaDirs.find(Dir);
491 if (KnownDir != UmbrellaDirs.end()) {
492 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000493 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000494 return true;
495
496 // Search up the module stack until we find a module with an umbrella
497 // directory.
498 Module *UmbrellaModule = Found;
499 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
500 UmbrellaModule = UmbrellaModule->Parent;
501
502 if (UmbrellaModule->InferSubmodules) {
503 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
504 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000505 SmallString<32> NameBuf;
506 StringRef Name = sanitizeFilenameAsIdentifier(
507 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
508 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000509 Found = lookupModuleQualified(Name, Found);
510 if (!Found)
511 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000512 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000513 return true;
514 }
515
516 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000517 SmallString<32> NameBuf;
518 StringRef Name = sanitizeFilenameAsIdentifier(
519 llvm::sys::path::stem(Header->getName()),
520 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000521 Found = lookupModuleQualified(Name, Found);
522 if (!Found)
523 return false;
524 }
525
Richard Smith50996ce2014-04-08 13:13:04 +0000526 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000527 }
528
529 SkippedDirs.push_back(Dir);
530
531 // Retrieve our parent path.
532 DirName = llvm::sys::path::parent_path(DirName);
533 if (DirName.empty())
534 break;
535
536 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000537 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000538 } while (Dir);
539
540 return false;
541}
542
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000543Module *ModuleMap::findModule(StringRef Name) const {
544 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000545 if (Known != Modules.end())
546 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000547
548 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000549}
550
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000551Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
552 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000553 for(; Context; Context = Context->Parent) {
554 if (Module *Sub = lookupModuleQualified(Name, Context))
555 return Sub;
556 }
557
558 return findModule(Name);
559}
560
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000561Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000562 if (!Context)
563 return findModule(Name);
564
Douglas Gregoreb90e832012-01-04 23:32:19 +0000565 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000566}
567
Douglas Gregorde3ef502011-11-30 23:21:26 +0000568std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000569ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000570 bool IsExplicit) {
571 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000572 if (Module *Sub = lookupModuleQualified(Name, Parent))
573 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000574
575 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000576 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000577 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000578 if (LangOpts.CurrentModule == Name) {
579 SourceModule = Result;
580 SourceModuleName = Name;
581 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000582 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000583 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000584 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
585 Name == LangOpts.CurrentModule) {
586 CompilingModule = Result;
587 }
588 }
Douglas Gregor69021972011-11-30 17:33:56 +0000589 return std::make_pair(Result, true);
590}
591
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000592/// \brief For a framework module, infer the framework against which we
593/// should link.
594static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
595 FileManager &FileMgr) {
596 assert(Mod->IsFramework && "Can only infer linking for framework modules");
597 assert(!Mod->isSubFramework() &&
598 "Can only infer linking for top-level frameworks");
599
600 SmallString<128> LibName;
601 LibName += FrameworkDir->getName();
602 llvm::sys::path::append(LibName, Mod->Name);
603 if (FileMgr.getFile(LibName)) {
604 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
605 /*IsFramework=*/true));
606 }
607}
608
Douglas Gregorde3ef502011-11-30 23:21:26 +0000609Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000610ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000611 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000612 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000613 Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000614 Attributes Attrs;
615 Attrs.IsSystem = IsSystem;
616 return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
617}
618
619Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
620 const DirectoryEntry *FrameworkDir,
621 Attributes Attrs, Module *Parent) {
622
Douglas Gregor56c64012011-11-17 01:41:17 +0000623 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000624 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
625 return Mod;
626
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000627 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000628
629 // If the framework has a parent path from which we're allowed to infer
630 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000631 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000632 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000633 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000634
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000635 // Note: as an egregious but useful hack we use the real path here, because
636 // we might be looking at an embedded framework that symlinks out to a
637 // top-level framework, and we need to infer as if we were naming the
638 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000639 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000640 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000641
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000642 // In case this is a case-insensitive filesystem, make sure the canonical
643 // directory name matches ModuleName exactly. Modules are case-sensitive.
644 // FIXME: we should be able to give a fix-it hint for the correct spelling.
645 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
646 return nullptr;
647
Douglas Gregor9194a912012-11-06 19:39:40 +0000648 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000649 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000650 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000651 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000652 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
653 // Check whether we have already looked into the parent directory
654 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000655 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000656 inferred = InferredDirectories.find(ParentDir);
657 if (inferred == InferredDirectories.end()) {
658 // We haven't looked here before. Load a module map, if there is
659 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000660 bool IsFrameworkDir = Parent.endswith(".framework");
661 if (const FileEntry *ModMapFile =
662 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000663 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000664 inferred = InferredDirectories.find(ParentDir);
665 }
666
667 if (inferred == InferredDirectories.end())
668 inferred = InferredDirectories.insert(
669 std::make_pair(ParentDir, InferredDirectory())).first;
670 }
671
672 if (inferred->second.InferModules) {
673 // We're allowed to infer for this directory, but make sure it's okay
674 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000675 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000676 canInfer = std::find(inferred->second.ExcludedModules.begin(),
677 inferred->second.ExcludedModules.end(),
678 Name) == inferred->second.ExcludedModules.end();
679
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000680 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
681 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
682 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000683 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000684 }
685 }
686 }
687
688 // If we're not allowed to infer a framework module, don't.
689 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000690 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000691 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000692 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000693
694
Douglas Gregor56c64012011-11-17 01:41:17 +0000695 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000696 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000697 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000698 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000699
700 // FIXME: If there's no umbrella header, we could probably scan the
701 // framework to load *everything*. But, it's not clear that this is a good
702 // idea.
703 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000704 return nullptr;
705
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000706 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000707 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000708 InferredModuleAllowedBy[Result] = ModuleMapFile;
709 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000710 if (LangOpts.CurrentModule == ModuleName) {
711 SourceModule = Result;
712 SourceModuleName = ModuleName;
713 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000714
715 Result->IsSystem |= Attrs.IsSystem;
716 Result->IsExternC |= Attrs.IsExternC;
717 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
718
Douglas Gregoreb90e832012-01-04 23:32:19 +0000719 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000721
Douglas Gregor322f6332011-12-08 18:00:48 +0000722 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000723 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000724 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000725 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000726
727 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000728 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
729
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000730 // module * { export * }
731 Result->InferSubmodules = true;
732 Result->InferExportWildcard = true;
733
Douglas Gregore89dbc12011-12-06 19:39:29 +0000734 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000735 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000736 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000737 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000738 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000739 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000740 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000741 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000742 Dir != DirEnd && !EC; Dir.increment(EC)) {
743 if (!StringRef(Dir->path()).endswith(".framework"))
744 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000745
Douglas Gregore89dbc12011-12-06 19:39:29 +0000746 if (const DirectoryEntry *SubframeworkDir
747 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000748 // Note: as an egregious but useful hack, we use the real path here and
749 // check whether it is actually a subdirectory of the parent directory.
750 // This will not be the case if the 'subframework' is actually a symlink
751 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000752 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
753 bool FoundParent = false;
754 do {
755 // Get the parent directory name.
756 SubframeworkDirName
757 = llvm::sys::path::parent_path(SubframeworkDirName);
758 if (SubframeworkDirName.empty())
759 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000760
Douglas Gregore00c8b22013-01-26 00:55:12 +0000761 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
762 FoundParent = true;
763 break;
764 }
765 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000766
Douglas Gregore00c8b22013-01-26 00:55:12 +0000767 if (!FoundParent)
768 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000769
Douglas Gregore89dbc12011-12-06 19:39:29 +0000770 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000771 SmallString<32> NameBuf;
772 inferFrameworkModule(sanitizeFilenameAsIdentifier(
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000773 llvm::sys::path::stem(Dir->path()), NameBuf),
774 SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000775 }
776 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000777
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000778 // If the module is a top-level framework, automatically link against the
779 // framework.
780 if (!Result->isSubFramework()) {
781 inferFrameworkLink(Result, FrameworkDir, FileMgr);
782 }
783
Douglas Gregor56c64012011-11-17 01:41:17 +0000784 return Result;
785}
786
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000787void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000788 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000789 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000790 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000791}
792
Douglas Gregor524e33e2011-12-08 19:11:24 +0000793void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
794 Mod->Umbrella = UmbrellaDir;
795 UmbrellaDirs[UmbrellaDir] = Mod;
796}
797
Richard Smith3c1a41a2014-12-02 00:08:08 +0000798static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000799 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000800 default: llvm_unreachable("unknown header role");
801 case ModuleMap::NormalHeader:
802 return Module::HK_Normal;
803 case ModuleMap::PrivateHeader:
804 return Module::HK_Private;
805 case ModuleMap::TextualHeader:
806 return Module::HK_Textual;
807 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
808 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000809 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000810}
811
Richard Smith3c1a41a2014-12-02 00:08:08 +0000812void ModuleMap::addHeader(Module *Mod, Module::Header Header,
813 ModuleHeaderRole Role) {
814 if (!(Role & TextualHeader)) {
815 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
816 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
817 isCompilingModuleHeader);
818 }
819 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
Richard Smithfeb54b62014-10-23 02:01:19 +0000820
Richard Smith3c1a41a2014-12-02 00:08:08 +0000821 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
822}
823
824void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000825 // Add this as a known header so we won't implicitly add it to any
826 // umbrella directory module.
827 // FIXME: Should we only exclude it from umbrella modules within the
828 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000829 (void) Headers[Header.Entry];
830
831 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000832}
833
Douglas Gregor514b6362011-11-29 19:06:37 +0000834const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000835ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000836 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000837 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000838
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000839 return SourceMgr.getFileEntryForID(
840 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000841}
842
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000843const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000844 if (M->IsInferred) {
845 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
846 return InferredModuleAllowedBy.find(M)->second;
847 }
848 return getContainingModuleMapFile(M);
849}
850
851void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
852 assert(M->IsInferred && "module not inferred");
853 InferredModuleAllowedBy[M] = ModMap;
854}
855
Douglas Gregor718292f2011-11-11 19:10:28 +0000856void ModuleMap::dump() {
857 llvm::errs() << "Modules:";
858 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
859 MEnd = Modules.end();
860 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000861 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000862
863 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000864 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000865 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000866 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
867 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
868 E = H->second.end();
869 I != E; ++I) {
870 if (I != H->second.begin())
871 llvm::errs() << ",";
872 llvm::errs() << I->getModule()->getFullModuleName();
873 }
874 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000875 }
876}
877
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000878bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
879 bool HadError = false;
880 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
881 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
882 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000883 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000884 Mod->Exports.push_back(Export);
885 else
886 HadError = true;
887 }
888 Mod->UnresolvedExports.clear();
889 return HadError;
890}
891
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000892bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
893 bool HadError = false;
894 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
895 Module *DirectUse =
896 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
897 if (DirectUse)
898 Mod->DirectUses.push_back(DirectUse);
899 else
900 HadError = true;
901 }
902 Mod->UnresolvedDirectUses.clear();
903 return HadError;
904}
905
Douglas Gregorfb912652013-03-20 21:10:35 +0000906bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
907 bool HadError = false;
908 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
909 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
910 Mod, Complain);
911 if (!OtherMod) {
912 HadError = true;
913 continue;
914 }
915
916 Module::Conflict Conflict;
917 Conflict.Other = OtherMod;
918 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
919 Mod->Conflicts.push_back(Conflict);
920 }
921 Mod->UnresolvedConflicts.clear();
922 return HadError;
923}
924
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000925Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
926 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000927 return nullptr;
928
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000929 // Use the expansion location to determine which module we're in.
930 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
931 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000932 return nullptr;
933
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000934 const SourceManager &SrcMgr = Loc.getManager();
935 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000936
Douglas Gregor224d8a72012-01-06 17:19:32 +0000937 while (const FileEntry *ExpansionFile
938 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
939 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000940 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000941 return Mod;
942
943 // No module owns this header, so look up the inclusion chain to see if
944 // any included header has an associated module.
945 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
946 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000947 return nullptr;
948
Douglas Gregor224d8a72012-01-06 17:19:32 +0000949 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
950 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000951
952 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000953}
954
Douglas Gregor718292f2011-11-11 19:10:28 +0000955//----------------------------------------------------------------------------//
956// Module map file parser
957//----------------------------------------------------------------------------//
958
959namespace clang {
960 /// \brief A token in a module map file.
961 struct MMToken {
962 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000963 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000964 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000965 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000966 EndOfFile,
967 HeaderKeyword,
968 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000969 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000970 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000971 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000972 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000973 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000974 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000975 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000976 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000977 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000978 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000979 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000980 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000981 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000982 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000983 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000984 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000985 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000986 RBrace,
987 LSquare,
988 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000989 } Kind;
990
991 unsigned Location;
992 unsigned StringLength;
993 const char *StringData;
994
995 void clear() {
996 Kind = EndOfFile;
997 Location = 0;
998 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000999 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +00001000 }
1001
1002 bool is(TokenKind K) const { return Kind == K; }
1003
1004 SourceLocation getLocation() const {
1005 return SourceLocation::getFromRawEncoding(Location);
1006 }
1007
1008 StringRef getString() const {
1009 return StringRef(StringData, StringLength);
1010 }
1011 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001012
Douglas Gregor718292f2011-11-11 19:10:28 +00001013 class ModuleMapParser {
1014 Lexer &L;
1015 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001016
1017 /// \brief Default target information, used only for string literal
1018 /// parsing.
1019 const TargetInfo *Target;
1020
Douglas Gregor718292f2011-11-11 19:10:28 +00001021 DiagnosticsEngine &Diags;
1022 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001023
1024 /// \brief The current module map file.
1025 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001026
Richard Smith9acb99e32014-12-10 03:09:48 +00001027 /// \brief The directory that file names in this module map file should
1028 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001029 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001030
1031 /// \brief The directory containing Clang-supplied headers.
1032 const DirectoryEntry *BuiltinIncludeDir;
1033
Douglas Gregor963c5532013-06-21 16:28:10 +00001034 /// \brief Whether this module map is in a system header directory.
1035 bool IsSystem;
1036
Douglas Gregor718292f2011-11-11 19:10:28 +00001037 /// \brief Whether an error occurred.
1038 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001039
Douglas Gregor718292f2011-11-11 19:10:28 +00001040 /// \brief Stores string data for the various string literals referenced
1041 /// during parsing.
1042 llvm::BumpPtrAllocator StringData;
1043
1044 /// \brief The current token.
1045 MMToken Tok;
1046
1047 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001048 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001049
1050 /// \brief Consume the current token and return its location.
1051 SourceLocation consumeToken();
1052
1053 /// \brief Skip tokens until we reach the a token with the given kind
1054 /// (or the end of the file).
1055 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001056
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001057 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001058 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001059 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001060 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001061 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001062 void parseHeaderDecl(clang::MMToken::TokenKind,
1063 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001064 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001065 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001066 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001067 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001068 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001069 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001070 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001071
1072 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001073 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001074
Douglas Gregor718292f2011-11-11 19:10:28 +00001075 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001076 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001077 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001078 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001079 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001080 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001081 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001082 const DirectoryEntry *BuiltinIncludeDir,
1083 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001084 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001085 ModuleMapFile(ModuleMapFile), Directory(Directory),
1086 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001087 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001088 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001089 Tok.clear();
1090 consumeToken();
1091 }
1092
1093 bool parseModuleMapFile();
1094 };
1095}
1096
1097SourceLocation ModuleMapParser::consumeToken() {
1098retry:
1099 SourceLocation Result = Tok.getLocation();
1100 Tok.clear();
1101
1102 Token LToken;
1103 L.LexFromRawLexer(LToken);
1104 Tok.Location = LToken.getLocation().getRawEncoding();
1105 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001106 case tok::raw_identifier: {
1107 StringRef RI = LToken.getRawIdentifier();
1108 Tok.StringData = RI.data();
1109 Tok.StringLength = RI.size();
1110 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001111 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001112 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001113 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001114 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001115 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001116 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001117 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001118 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001119 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001120 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001121 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001122 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001123 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001124 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001125 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001126 .Default(MMToken::Identifier);
1127 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001128 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001129
1130 case tok::comma:
1131 Tok.Kind = MMToken::Comma;
1132 break;
1133
Douglas Gregor718292f2011-11-11 19:10:28 +00001134 case tok::eof:
1135 Tok.Kind = MMToken::EndOfFile;
1136 break;
1137
1138 case tok::l_brace:
1139 Tok.Kind = MMToken::LBrace;
1140 break;
1141
Douglas Gregora686e1b2012-01-27 19:52:33 +00001142 case tok::l_square:
1143 Tok.Kind = MMToken::LSquare;
1144 break;
1145
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001146 case tok::period:
1147 Tok.Kind = MMToken::Period;
1148 break;
1149
Douglas Gregor718292f2011-11-11 19:10:28 +00001150 case tok::r_brace:
1151 Tok.Kind = MMToken::RBrace;
1152 break;
1153
Douglas Gregora686e1b2012-01-27 19:52:33 +00001154 case tok::r_square:
1155 Tok.Kind = MMToken::RSquare;
1156 break;
1157
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001158 case tok::star:
1159 Tok.Kind = MMToken::Star;
1160 break;
1161
Richard Smitha3feee22013-10-28 22:18:19 +00001162 case tok::exclaim:
1163 Tok.Kind = MMToken::Exclaim;
1164 break;
1165
Douglas Gregor718292f2011-11-11 19:10:28 +00001166 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001167 if (LToken.hasUDSuffix()) {
1168 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1169 HadError = true;
1170 goto retry;
1171 }
1172
Douglas Gregor718292f2011-11-11 19:10:28 +00001173 // Parse the string literal.
1174 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001175 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001176 if (StringLiteral.hadError)
1177 goto retry;
1178
1179 // Copy the string literal into our string data allocator.
1180 unsigned Length = StringLiteral.GetStringLength();
1181 char *Saved = StringData.Allocate<char>(Length + 1);
1182 memcpy(Saved, StringLiteral.GetString().data(), Length);
1183 Saved[Length] = 0;
1184
1185 // Form the token.
1186 Tok.Kind = MMToken::StringLiteral;
1187 Tok.StringData = Saved;
1188 Tok.StringLength = Length;
1189 break;
1190 }
1191
1192 case tok::comment:
1193 goto retry;
1194
1195 default:
1196 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1197 HadError = true;
1198 goto retry;
1199 }
1200
1201 return Result;
1202}
1203
1204void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1205 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001206 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001207 do {
1208 switch (Tok.Kind) {
1209 case MMToken::EndOfFile:
1210 return;
1211
1212 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001213 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001214 return;
1215
1216 ++braceDepth;
1217 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001218
1219 case MMToken::LSquare:
1220 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1221 return;
1222
1223 ++squareDepth;
1224 break;
1225
Douglas Gregor718292f2011-11-11 19:10:28 +00001226 case MMToken::RBrace:
1227 if (braceDepth > 0)
1228 --braceDepth;
1229 else if (Tok.is(K))
1230 return;
1231 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001232
1233 case MMToken::RSquare:
1234 if (squareDepth > 0)
1235 --squareDepth;
1236 else if (Tok.is(K))
1237 return;
1238 break;
1239
Douglas Gregor718292f2011-11-11 19:10:28 +00001240 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001241 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001242 return;
1243 break;
1244 }
1245
1246 consumeToken();
1247 } while (true);
1248}
1249
Douglas Gregore7ab3662011-12-07 02:23:45 +00001250/// \brief Parse a module-id.
1251///
1252/// module-id:
1253/// identifier
1254/// identifier '.' module-id
1255///
1256/// \returns true if an error occurred, false otherwise.
1257bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1258 Id.clear();
1259 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001260 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001261 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1262 consumeToken();
1263 } else {
1264 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1265 return true;
1266 }
1267
1268 if (!Tok.is(MMToken::Period))
1269 break;
1270
1271 consumeToken();
1272 } while (true);
1273
1274 return false;
1275}
1276
Douglas Gregora686e1b2012-01-27 19:52:33 +00001277namespace {
1278 /// \brief Enumerates the known attributes.
1279 enum AttributeKind {
1280 /// \brief An unknown attribute.
1281 AT_unknown,
1282 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001283 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001284 /// \brief The 'extern_c' attribute.
1285 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001286 /// \brief The 'exhaustive' attribute.
1287 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001288 };
1289}
1290
Douglas Gregor718292f2011-11-11 19:10:28 +00001291/// \brief Parse a module declaration.
1292///
1293/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001294/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001295/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1296/// { module-member* }
1297///
Douglas Gregor718292f2011-11-11 19:10:28 +00001298/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001299/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001300/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001301/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001302/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001303/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001304///
1305/// submodule-declaration:
1306/// module-declaration
1307/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001308void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001309 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001310 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1311 if (Tok.is(MMToken::ExternKeyword)) {
1312 parseExternModuleDecl();
1313 return;
1314 }
1315
Douglas Gregorf2161a72011-12-06 17:16:41 +00001316 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001317 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001318 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001319 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001320
Douglas Gregorf2161a72011-12-06 17:16:41 +00001321 // Parse 'explicit' keyword, if present.
1322 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001323 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001324 Explicit = true;
1325 }
1326
1327 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001328 if (Tok.is(MMToken::FrameworkKeyword)) {
1329 consumeToken();
1330 Framework = true;
1331 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001332
1333 // Parse 'module' keyword.
1334 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001335 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001336 consumeToken();
1337 HadError = true;
1338 return;
1339 }
1340 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001341
1342 // If we have a wildcard for the module name, this is an inferred submodule.
1343 // Parse it.
1344 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001345 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001346
1347 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001348 ModuleId Id;
1349 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001350 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001351 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001352 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001353
Douglas Gregore7ab3662011-12-07 02:23:45 +00001354 if (ActiveModule) {
1355 if (Id.size() > 1) {
1356 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1357 << SourceRange(Id.front().second, Id.back().second);
1358
1359 HadError = true;
1360 return;
1361 }
1362 } else if (Id.size() == 1 && Explicit) {
1363 // Top-level modules can't be explicit.
1364 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1365 Explicit = false;
1366 ExplicitLoc = SourceLocation();
1367 HadError = true;
1368 }
1369
1370 Module *PreviousActiveModule = ActiveModule;
1371 if (Id.size() > 1) {
1372 // This module map defines a submodule. Go find the module of which it
1373 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001374 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001375 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001376 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1377 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001378 if (I == 0)
1379 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001380 ActiveModule = Next;
1381 continue;
1382 }
1383
1384 if (ActiveModule) {
1385 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001386 << Id[I].first
1387 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001388 } else {
1389 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1390 }
1391 HadError = true;
1392 return;
1393 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001394
1395 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1396 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1397 "submodule defined in same file as 'module *' that allowed its "
1398 "top-level module");
1399 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1400 }
1401 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001402
1403 StringRef ModuleName = Id.back().first;
1404 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001405
Douglas Gregora686e1b2012-01-27 19:52:33 +00001406 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001407 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001408 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001409
Douglas Gregor718292f2011-11-11 19:10:28 +00001410 // Parse the opening brace.
1411 if (!Tok.is(MMToken::LBrace)) {
1412 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1413 << ModuleName;
1414 HadError = true;
1415 return;
1416 }
1417 SourceLocation LBraceLoc = consumeToken();
1418
1419 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001420 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001421 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1422 // Skip the module definition.
1423 skipUntil(MMToken::RBrace);
1424 if (Tok.is(MMToken::RBrace))
1425 consumeToken();
1426 else {
1427 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1428 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1429 HadError = true;
1430 }
1431 return;
1432 }
1433
Douglas Gregor718292f2011-11-11 19:10:28 +00001434 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1435 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001436 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001437
1438 // Skip the module definition.
1439 skipUntil(MMToken::RBrace);
1440 if (Tok.is(MMToken::RBrace))
1441 consumeToken();
1442
1443 HadError = true;
1444 return;
1445 }
1446
1447 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001448 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1449 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001450 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001451 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001452 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001453 if (Attrs.IsExternC)
1454 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001455 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001456
Douglas Gregor718292f2011-11-11 19:10:28 +00001457 bool Done = false;
1458 do {
1459 switch (Tok.Kind) {
1460 case MMToken::EndOfFile:
1461 case MMToken::RBrace:
1462 Done = true;
1463 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001464
1465 case MMToken::ConfigMacros:
1466 parseConfigMacros();
1467 break;
1468
Douglas Gregorfb912652013-03-20 21:10:35 +00001469 case MMToken::Conflict:
1470 parseConflict();
1471 break;
1472
Douglas Gregor718292f2011-11-11 19:10:28 +00001473 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001474 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001475 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001476 case MMToken::ModuleKeyword:
1477 parseModuleDecl();
1478 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001479
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001480 case MMToken::ExportKeyword:
1481 parseExportDecl();
1482 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001483
1484 case MMToken::UseKeyword:
1485 parseUseDecl();
1486 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001487
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001488 case MMToken::RequiresKeyword:
1489 parseRequiresDecl();
1490 break;
1491
Richard Smith202210b2014-10-24 20:23:01 +00001492 case MMToken::TextualKeyword:
1493 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001494 break;
Richard Smith306d8922014-10-22 23:50:56 +00001495
Douglas Gregor524e33e2011-12-08 19:11:24 +00001496 case MMToken::UmbrellaKeyword: {
1497 SourceLocation UmbrellaLoc = consumeToken();
1498 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001499 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001500 else
1501 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001502 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001503 }
Richard Smith202210b2014-10-24 20:23:01 +00001504
1505 case MMToken::ExcludeKeyword:
1506 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001507 break;
Richard Smith202210b2014-10-24 20:23:01 +00001508
1509 case MMToken::PrivateKeyword:
1510 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001511 break;
Richard Smith202210b2014-10-24 20:23:01 +00001512
Douglas Gregor322f6332011-12-08 18:00:48 +00001513 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001514 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001515 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001516
1517 case MMToken::LinkKeyword:
1518 parseLinkDecl();
1519 break;
1520
Douglas Gregor718292f2011-11-11 19:10:28 +00001521 default:
1522 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1523 consumeToken();
1524 break;
1525 }
1526 } while (!Done);
1527
1528 if (Tok.is(MMToken::RBrace))
1529 consumeToken();
1530 else {
1531 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1532 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1533 HadError = true;
1534 }
1535
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001536 // If the active module is a top-level framework, and there are no link
1537 // libraries, automatically link against the framework.
1538 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1539 ActiveModule->LinkLibraries.empty()) {
1540 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1541 }
1542
Ben Langmuirec8c9752014-04-18 22:07:31 +00001543 // If the module meets all requirements but is still unavailable, mark the
1544 // whole tree as unavailable to prevent it from building.
1545 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1546 ActiveModule->Parent) {
1547 ActiveModule->getTopLevelModule()->markUnavailable();
1548 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1549 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1550 }
1551
Douglas Gregore7ab3662011-12-07 02:23:45 +00001552 // We're done parsing this module. Pop back to the previous module.
1553 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001554}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001555
Daniel Jasper97292842013-09-11 07:20:44 +00001556/// \brief Parse an extern module declaration.
1557///
1558/// extern module-declaration:
1559/// 'extern' 'module' module-id string-literal
1560void ModuleMapParser::parseExternModuleDecl() {
1561 assert(Tok.is(MMToken::ExternKeyword));
1562 consumeToken(); // 'extern' keyword
1563
1564 // Parse 'module' keyword.
1565 if (!Tok.is(MMToken::ModuleKeyword)) {
1566 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1567 consumeToken();
1568 HadError = true;
1569 return;
1570 }
1571 consumeToken(); // 'module' keyword
1572
1573 // Parse the module name.
1574 ModuleId Id;
1575 if (parseModuleId(Id)) {
1576 HadError = true;
1577 return;
1578 }
1579
1580 // Parse the referenced module map file name.
1581 if (!Tok.is(MMToken::StringLiteral)) {
1582 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1583 HadError = true;
1584 return;
1585 }
1586 std::string FileName = Tok.getString();
1587 consumeToken(); // filename
1588
1589 StringRef FileNameRef = FileName;
1590 SmallString<128> ModuleMapFileName;
1591 if (llvm::sys::path::is_relative(FileNameRef)) {
1592 ModuleMapFileName += Directory->getName();
1593 llvm::sys::path::append(ModuleMapFileName, FileName);
1594 FileNameRef = ModuleMapFileName.str();
1595 }
1596 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001597 Map.parseModuleMapFile(
1598 File, /*IsSystem=*/false,
1599 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1600 ? Directory
1601 : File->getDir());
Daniel Jasper97292842013-09-11 07:20:44 +00001602}
1603
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001604/// \brief Parse a requires declaration.
1605///
1606/// requires-declaration:
1607/// 'requires' feature-list
1608///
1609/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001610/// feature ',' feature-list
1611/// feature
1612///
1613/// feature:
1614/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001615void ModuleMapParser::parseRequiresDecl() {
1616 assert(Tok.is(MMToken::RequiresKeyword));
1617
1618 // Parse 'requires' keyword.
1619 consumeToken();
1620
1621 // Parse the feature-list.
1622 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001623 bool RequiredState = true;
1624 if (Tok.is(MMToken::Exclaim)) {
1625 RequiredState = false;
1626 consumeToken();
1627 }
1628
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001629 if (!Tok.is(MMToken::Identifier)) {
1630 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1631 HadError = true;
1632 return;
1633 }
1634
1635 // Consume the feature name.
1636 std::string Feature = Tok.getString();
1637 consumeToken();
1638
1639 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001640 ActiveModule->addRequirement(Feature, RequiredState,
1641 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001642
1643 if (!Tok.is(MMToken::Comma))
1644 break;
1645
1646 // Consume the comma.
1647 consumeToken();
1648 } while (true);
1649}
1650
Douglas Gregorf2161a72011-12-06 17:16:41 +00001651/// \brief Append to \p Paths the set of paths needed to get to the
1652/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001653static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001654 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001655 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001656 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001657 for (; Mod; Mod = Mod->Parent) {
1658 if (Mod->IsFramework)
1659 Paths.push_back(Mod->Name);
1660 }
1661
1662 if (Paths.empty())
1663 return;
1664
1665 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001666 for (unsigned I = Paths.size() - 1; I != 0; --I)
1667 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001668}
1669
Douglas Gregor718292f2011-11-11 19:10:28 +00001670/// \brief Parse a header declaration.
1671///
1672/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001673/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001674/// 'private' 'textual'[opt] 'header' string-literal
1675/// 'exclude' 'header' string-literal
1676/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001677///
1678/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001679void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1680 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001681 // We've already consumed the first token.
1682 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1683 if (LeadingToken == MMToken::PrivateKeyword) {
1684 Role = ModuleMap::PrivateHeader;
1685 // 'private' may optionally be followed by 'textual'.
1686 if (Tok.is(MMToken::TextualKeyword)) {
1687 LeadingToken = Tok.Kind;
1688 consumeToken();
1689 }
1690 }
1691 if (LeadingToken == MMToken::TextualKeyword)
1692 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1693
1694 if (LeadingToken != MMToken::HeaderKeyword) {
1695 if (!Tok.is(MMToken::HeaderKeyword)) {
1696 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1697 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1698 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1699 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1700 return;
1701 }
1702 consumeToken();
1703 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001704
Douglas Gregor718292f2011-11-11 19:10:28 +00001705 // Parse the header name.
1706 if (!Tok.is(MMToken::StringLiteral)) {
1707 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1708 << "header";
1709 HadError = true;
1710 return;
1711 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001712 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001713 Header.FileName = Tok.getString();
1714 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001715
Douglas Gregor524e33e2011-12-08 19:11:24 +00001716 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001717 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001718 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001719 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001720 HadError = true;
1721 return;
1722 }
1723
Douglas Gregor5257fc62011-11-11 21:55:48 +00001724 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001725 const FileEntry *File = nullptr;
1726 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001727 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001728 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001729 RelativePathName = Header.FileName;
1730 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001731 } else {
1732 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001733 SmallString<128> FullPathName(Directory->getName());
1734 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001735
Douglas Gregorf2161a72011-12-06 17:16:41 +00001736 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001737 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001738
1739 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001740 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1741 llvm::sys::path::append(FullPathName, RelativePathName.str());
1742 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001743
1744 if (!File) {
1745 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001746 // FIXME: Should we retain the subframework paths here?
1747 RelativePathName.clear();
1748 FullPathName.resize(FullPathLength);
1749 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1750 Header.FileName);
1751 llvm::sys::path::append(FullPathName, RelativePathName.str());
1752 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001753 }
1754 } else {
1755 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001756 llvm::sys::path::append(RelativePathName, Header.FileName);
1757 llvm::sys::path::append(FullPathName, RelativePathName.str());
1758 File = SourceMgr.getFileManager().getFile(FullPathName);
1759
Douglas Gregor3ec66632012-02-02 18:42:48 +00001760 // If this is a system module with a top-level header, this header
1761 // may have a counterpart (or replacement) in the set of headers
1762 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001763 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1764 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001765 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001766 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001767 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001768 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001769
Douglas Gregor3ec66632012-02-02 18:42:48 +00001770 // If Clang supplies this header but the underlying system does not,
1771 // just silently swap in our builtin version. Otherwise, we'll end
1772 // up adding both (later).
1773 if (!File && BuiltinFile) {
1774 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001775 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001776 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001777 }
1778 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001779 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001780 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001781
Douglas Gregor5257fc62011-11-11 21:55:48 +00001782 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1783 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001784 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001785 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001786 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001787 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001788 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001789 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001790 HadError = true;
1791 } else {
1792 // Record this umbrella header.
1793 Map.setUmbrellaHeader(ActiveModule, File);
1794 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001795 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001796 Module::Header H = {RelativePathName.str(), File};
1797 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001798 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001799 // If there is a builtin counterpart to this file, add it now, before
1800 // the "real" header, so we build the built-in one first when building
1801 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001802 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001803 // FIXME: Taking the name from the FileEntry is unstable and can give
1804 // different results depending on how we've previously named that file
1805 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001806 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1807 Map.addHeader(ActiveModule, H, Role);
1808 }
Richard Smith25d50752014-10-20 00:15:49 +00001809
Richard Smith202210b2014-10-24 20:23:01 +00001810 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001811 Module::Header H = { RelativePathName.str(), File };
1812 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001813 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001814 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001815 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001816
1817 // If we find a module that has a missing header, we mark this module as
1818 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001819 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001820 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001821 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001822 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001823}
1824
Douglas Gregor524e33e2011-12-08 19:11:24 +00001825/// \brief Parse an umbrella directory declaration.
1826///
1827/// umbrella-dir-declaration:
1828/// umbrella string-literal
1829void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1830 // Parse the directory name.
1831 if (!Tok.is(MMToken::StringLiteral)) {
1832 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1833 << "umbrella";
1834 HadError = true;
1835 return;
1836 }
1837
1838 std::string DirName = Tok.getString();
1839 SourceLocation DirNameLoc = consumeToken();
1840
1841 // Check whether we already have an umbrella.
1842 if (ActiveModule->Umbrella) {
1843 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1844 << ActiveModule->getFullModuleName();
1845 HadError = true;
1846 return;
1847 }
1848
1849 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001850 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001851 if (llvm::sys::path::is_absolute(DirName))
1852 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1853 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001854 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001855 PathName = Directory->getName();
1856 llvm::sys::path::append(PathName, DirName);
1857 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1858 }
1859
1860 if (!Dir) {
1861 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1862 << DirName;
1863 HadError = true;
1864 return;
1865 }
1866
1867 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1868 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1869 << OwningModule->getFullModuleName();
1870 HadError = true;
1871 return;
1872 }
1873
1874 // Record this umbrella directory.
1875 Map.setUmbrellaDir(ActiveModule, Dir);
1876}
1877
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001878/// \brief Parse a module export declaration.
1879///
1880/// export-declaration:
1881/// 'export' wildcard-module-id
1882///
1883/// wildcard-module-id:
1884/// identifier
1885/// '*'
1886/// identifier '.' wildcard-module-id
1887void ModuleMapParser::parseExportDecl() {
1888 assert(Tok.is(MMToken::ExportKeyword));
1889 SourceLocation ExportLoc = consumeToken();
1890
1891 // Parse the module-id with an optional wildcard at the end.
1892 ModuleId ParsedModuleId;
1893 bool Wildcard = false;
1894 do {
Richard Smith306d8922014-10-22 23:50:56 +00001895 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001896 if (Tok.is(MMToken::Identifier)) {
1897 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1898 Tok.getLocation()));
1899 consumeToken();
1900
1901 if (Tok.is(MMToken::Period)) {
1902 consumeToken();
1903 continue;
1904 }
1905
1906 break;
1907 }
1908
1909 if(Tok.is(MMToken::Star)) {
1910 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001911 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001912 break;
1913 }
1914
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001915 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001916 HadError = true;
1917 return;
1918 } while (true);
1919
1920 Module::UnresolvedExportDecl Unresolved = {
1921 ExportLoc, ParsedModuleId, Wildcard
1922 };
1923 ActiveModule->UnresolvedExports.push_back(Unresolved);
1924}
1925
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001926/// \brief Parse a module uses declaration.
1927///
1928/// uses-declaration:
1929/// 'uses' wildcard-module-id
1930void ModuleMapParser::parseUseDecl() {
1931 assert(Tok.is(MMToken::UseKeyword));
1932 consumeToken();
1933 // Parse the module-id.
1934 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001935 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001936
1937 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1938}
1939
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001940/// \brief Parse a link declaration.
1941///
1942/// module-declaration:
1943/// 'link' 'framework'[opt] string-literal
1944void ModuleMapParser::parseLinkDecl() {
1945 assert(Tok.is(MMToken::LinkKeyword));
1946 SourceLocation LinkLoc = consumeToken();
1947
1948 // Parse the optional 'framework' keyword.
1949 bool IsFramework = false;
1950 if (Tok.is(MMToken::FrameworkKeyword)) {
1951 consumeToken();
1952 IsFramework = true;
1953 }
1954
1955 // Parse the library name
1956 if (!Tok.is(MMToken::StringLiteral)) {
1957 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1958 << IsFramework << SourceRange(LinkLoc);
1959 HadError = true;
1960 return;
1961 }
1962
1963 std::string LibraryName = Tok.getString();
1964 consumeToken();
1965 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1966 IsFramework));
1967}
1968
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001969/// \brief Parse a configuration macro declaration.
1970///
1971/// module-declaration:
1972/// 'config_macros' attributes[opt] config-macro-list?
1973///
1974/// config-macro-list:
1975/// identifier (',' identifier)?
1976void ModuleMapParser::parseConfigMacros() {
1977 assert(Tok.is(MMToken::ConfigMacros));
1978 SourceLocation ConfigMacrosLoc = consumeToken();
1979
1980 // Only top-level modules can have configuration macros.
1981 if (ActiveModule->Parent) {
1982 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1983 }
1984
1985 // Parse the optional attributes.
1986 Attributes Attrs;
1987 parseOptionalAttributes(Attrs);
1988 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1989 ActiveModule->ConfigMacrosExhaustive = true;
1990 }
1991
1992 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001993 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001994 if (!Tok.is(MMToken::Identifier))
1995 return;
1996
1997 // Consume the first identifier.
1998 if (!ActiveModule->Parent) {
1999 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2000 }
2001 consumeToken();
2002
2003 do {
2004 // If there's a comma, consume it.
2005 if (!Tok.is(MMToken::Comma))
2006 break;
2007 consumeToken();
2008
2009 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002010 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002011 if (!Tok.is(MMToken::Identifier)) {
2012 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2013 break;
2014 }
2015
2016 // Consume the macro name.
2017 if (!ActiveModule->Parent) {
2018 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2019 }
2020 consumeToken();
2021 } while (true);
2022}
2023
Douglas Gregorfb912652013-03-20 21:10:35 +00002024/// \brief Format a module-id into a string.
2025static std::string formatModuleId(const ModuleId &Id) {
2026 std::string result;
2027 {
2028 llvm::raw_string_ostream OS(result);
2029
2030 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2031 if (I)
2032 OS << ".";
2033 OS << Id[I].first;
2034 }
2035 }
2036
2037 return result;
2038}
2039
2040/// \brief Parse a conflict declaration.
2041///
2042/// module-declaration:
2043/// 'conflict' module-id ',' string-literal
2044void ModuleMapParser::parseConflict() {
2045 assert(Tok.is(MMToken::Conflict));
2046 SourceLocation ConflictLoc = consumeToken();
2047 Module::UnresolvedConflict Conflict;
2048
2049 // Parse the module-id.
2050 if (parseModuleId(Conflict.Id))
2051 return;
2052
2053 // Parse the ','.
2054 if (!Tok.is(MMToken::Comma)) {
2055 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2056 << SourceRange(ConflictLoc);
2057 return;
2058 }
2059 consumeToken();
2060
2061 // Parse the message.
2062 if (!Tok.is(MMToken::StringLiteral)) {
2063 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2064 << formatModuleId(Conflict.Id);
2065 return;
2066 }
2067 Conflict.Message = Tok.getString().str();
2068 consumeToken();
2069
2070 // Add this unresolved conflict.
2071 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2072}
2073
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002074/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002075///
2076/// module-declaration:
2077/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2078/// { inferred-module-member* }
2079///
2080/// inferred-module-member:
2081/// 'export' '*'
2082/// 'exclude' identifier
2083void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002084 assert(Tok.is(MMToken::Star));
2085 SourceLocation StarLoc = consumeToken();
2086 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002087
Douglas Gregor73441092011-12-05 22:27:44 +00002088 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002089 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002090 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2091 Failed = true;
2092 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002093
2094 if (ActiveModule) {
2095 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002096 if (!Failed && ActiveModule->IsAvailable &&
2097 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002098 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2099 Failed = true;
2100 }
2101
2102 // Check for redefinition of an inferred module.
2103 if (!Failed && ActiveModule->InferSubmodules) {
2104 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2105 if (ActiveModule->InferredSubmoduleLoc.isValid())
2106 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2107 diag::note_mmap_prev_definition);
2108 Failed = true;
2109 }
2110
2111 // Check for the 'framework' keyword, which is not permitted here.
2112 if (Framework) {
2113 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2114 Framework = false;
2115 }
2116 } else if (Explicit) {
2117 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2118 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002119 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002120
Douglas Gregor73441092011-12-05 22:27:44 +00002121 // If there were any problems with this inferred submodule, skip its body.
2122 if (Failed) {
2123 if (Tok.is(MMToken::LBrace)) {
2124 consumeToken();
2125 skipUntil(MMToken::RBrace);
2126 if (Tok.is(MMToken::RBrace))
2127 consumeToken();
2128 }
2129 HadError = true;
2130 return;
2131 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002132
2133 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002134 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002135 parseOptionalAttributes(Attrs);
2136
2137 if (ActiveModule) {
2138 // Note that we have an inferred submodule.
2139 ActiveModule->InferSubmodules = true;
2140 ActiveModule->InferredSubmoduleLoc = StarLoc;
2141 ActiveModule->InferExplicitSubmodules = Explicit;
2142 } else {
2143 // We'll be inferring framework modules for this directory.
2144 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002145 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002146 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002147 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002148 }
2149
Douglas Gregor73441092011-12-05 22:27:44 +00002150 // Parse the opening brace.
2151 if (!Tok.is(MMToken::LBrace)) {
2152 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2153 HadError = true;
2154 return;
2155 }
2156 SourceLocation LBraceLoc = consumeToken();
2157
2158 // Parse the body of the inferred submodule.
2159 bool Done = false;
2160 do {
2161 switch (Tok.Kind) {
2162 case MMToken::EndOfFile:
2163 case MMToken::RBrace:
2164 Done = true;
2165 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002166
2167 case MMToken::ExcludeKeyword: {
2168 if (ActiveModule) {
2169 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002170 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002171 consumeToken();
2172 break;
2173 }
2174
2175 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002176 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002177 if (!Tok.is(MMToken::Identifier)) {
2178 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2179 break;
2180 }
2181
2182 Map.InferredDirectories[Directory].ExcludedModules
2183 .push_back(Tok.getString());
2184 consumeToken();
2185 break;
2186 }
2187
2188 case MMToken::ExportKeyword:
2189 if (!ActiveModule) {
2190 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002191 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002192 consumeToken();
2193 break;
2194 }
2195
Douglas Gregor73441092011-12-05 22:27:44 +00002196 consumeToken();
2197 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002198 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002199 else
2200 Diags.Report(Tok.getLocation(),
2201 diag::err_mmap_expected_export_wildcard);
2202 consumeToken();
2203 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002204
Douglas Gregor73441092011-12-05 22:27:44 +00002205 case MMToken::ExplicitKeyword:
2206 case MMToken::ModuleKeyword:
2207 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002208 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002209 case MMToken::UmbrellaKeyword:
2210 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002211 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002212 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002213 consumeToken();
2214 break;
2215 }
2216 } while (!Done);
2217
2218 if (Tok.is(MMToken::RBrace))
2219 consumeToken();
2220 else {
2221 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2222 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2223 HadError = true;
2224 }
2225}
2226
Douglas Gregor9194a912012-11-06 19:39:40 +00002227/// \brief Parse optional attributes.
2228///
2229/// attributes:
2230/// attribute attributes
2231/// attribute
2232///
2233/// attribute:
2234/// [ identifier ]
2235///
2236/// \param Attrs Will be filled in with the parsed attributes.
2237///
2238/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002239bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002240 bool HadError = false;
2241
2242 while (Tok.is(MMToken::LSquare)) {
2243 // Consume the '['.
2244 SourceLocation LSquareLoc = consumeToken();
2245
2246 // Check whether we have an attribute name here.
2247 if (!Tok.is(MMToken::Identifier)) {
2248 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2249 skipUntil(MMToken::RSquare);
2250 if (Tok.is(MMToken::RSquare))
2251 consumeToken();
2252 HadError = true;
2253 }
2254
2255 // Decode the attribute name.
2256 AttributeKind Attribute
2257 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002258 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002259 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002260 .Case("system", AT_system)
2261 .Default(AT_unknown);
2262 switch (Attribute) {
2263 case AT_unknown:
2264 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2265 << Tok.getString();
2266 break;
2267
2268 case AT_system:
2269 Attrs.IsSystem = true;
2270 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002271
Richard Smith77944862014-03-02 05:58:18 +00002272 case AT_extern_c:
2273 Attrs.IsExternC = true;
2274 break;
2275
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002276 case AT_exhaustive:
2277 Attrs.IsExhaustive = true;
2278 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002279 }
2280 consumeToken();
2281
2282 // Consume the ']'.
2283 if (!Tok.is(MMToken::RSquare)) {
2284 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2285 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2286 skipUntil(MMToken::RSquare);
2287 HadError = true;
2288 }
2289
2290 if (Tok.is(MMToken::RSquare))
2291 consumeToken();
2292 }
2293
2294 return HadError;
2295}
2296
Douglas Gregor718292f2011-11-11 19:10:28 +00002297/// \brief Parse a module map file.
2298///
2299/// module-map-file:
2300/// module-declaration*
2301bool ModuleMapParser::parseModuleMapFile() {
2302 do {
2303 switch (Tok.Kind) {
2304 case MMToken::EndOfFile:
2305 return HadError;
2306
Douglas Gregore7ab3662011-12-07 02:23:45 +00002307 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002308 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002309 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002310 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002311 parseModuleDecl();
2312 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002313
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002314 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002315 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002316 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002317 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002318 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002319 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002320 case MMToken::HeaderKeyword:
2321 case MMToken::Identifier:
2322 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002323 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002324 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002325 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002326 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002327 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002328 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002329 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002330 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002331 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002332 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002333 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002334 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002335 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2336 HadError = true;
2337 consumeToken();
2338 break;
2339 }
2340 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002341}
2342
Richard Smith9acb99e32014-12-10 03:09:48 +00002343bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2344 const DirectoryEntry *Dir) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002345 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2346 = ParsedModuleMap.find(File);
2347 if (Known != ParsedModuleMap.end())
2348 return Known->second;
2349
Craig Topperd2d442c2014-05-17 23:10:59 +00002350 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002351 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2352 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002353 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002354 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002355 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002356
Douglas Gregor718292f2011-11-11 19:10:28 +00002357 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002358 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002359 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002360 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002361 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002362 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002363 return Result;
2364}