blob: 018a0b8825319e83fe1979089b89be1a2496944f [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 Smith202210b2014-10-24 20:23:01 +0000225 bool IsPrivate = false;
Richard Smith3c1a41a2014-12-02 00:08:08 +0000226 SmallVectorImpl<Module::Header> *HeaderList[] =
227 {&RequestedModule->Headers[Module::HK_Private],
228 &RequestedModule->Headers[Module::HK_PrivateTextual]};
Hans Wennborg0ef0aec2014-10-26 19:39:46 +0000229 for (auto *Hdrs : HeaderList)
Richard Smith202210b2014-10-24 20:23:01 +0000230 IsPrivate |=
Richard Smith3c1a41a2014-12-02 00:08:08 +0000231 std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) {
232 return H.Entry == IncFileEnt;
233 }) != Hdrs->end();
Richard Smith202210b2014-10-24 20:23:01 +0000234 assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
235#endif
236 return IsPrivateRole &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000237 RequestedModule->getTopLevelModule() != RequestingModule;
238}
239
Ben Langmuir71e1a642014-05-05 21:44:13 +0000240static Module *getTopLevelOrNull(Module *M) {
241 return M ? M->getTopLevelModule() : nullptr;
242}
243
Daniel Jasper92669ee2013-12-20 12:09:36 +0000244void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
245 SourceLocation FilenameLoc,
246 StringRef Filename,
247 const FileEntry *File) {
248 // No errors for indirect modules. This may be a bit of a problem for modules
249 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000250 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000251 return;
252
253 if (RequestingModule)
254 resolveUses(RequestingModule, /*Complain=*/false);
255
Ben Langmuir71e1a642014-05-05 21:44:13 +0000256 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000257 Module *Private = nullptr;
258 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000259
Ben Langmuir71e1a642014-05-05 21:44:13 +0000260 HeadersMap::iterator Known = findKnownHeader(File);
261 if (Known != Headers.end()) {
262 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000263 // If 'File' is part of 'RequestingModule' we can definitely include it.
264 if (Header.getModule() == RequestingModule)
265 return;
266
267 // Remember private headers for later printing of a diagnostic.
268 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
269 Header.getModule())) {
270 Private = Header.getModule();
271 continue;
272 }
273
274 // If uses need to be specified explicitly, we are only allowed to return
275 // modules that are explicitly used by the requesting module.
276 if (RequestingModule && LangOpts.ModulesDeclUse &&
277 !directlyUses(RequestingModule, Header.getModule())) {
278 NotUsed = Header.getModule();
279 continue;
280 }
281
282 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000283 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000284 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000285
286 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000287 }
288
289 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000290 if (Private) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000291 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
292 << Filename;
293 return;
294 }
295
296 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000297 if (NotUsed) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000298 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
299 << RequestingModule->getFullModuleName() << Filename;
300 return;
301 }
302
Ben Langmuir71e1a642014-05-05 21:44:13 +0000303 if (Excluded || isHeaderInUmbrellaDirs(File))
304 return;
305
306 // At this point, only non-modular includes remain.
307
308 if (LangOpts.ModulesStrictDeclUse) {
309 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
310 << RequestingModule->getFullModuleName() << Filename;
311 } else if (RequestingModule) {
312 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
313 diag::warn_non_modular_include_in_framework_module :
314 diag::warn_non_modular_include_in_module;
315 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000316 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000317}
318
Richard Smithec87a502015-02-13 23:50:20 +0000319static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
320 const ModuleMap::KnownHeader &Old) {
321 // Prefer a public header over a private header.
322 if ((New.getRole() & ModuleMap::PrivateHeader) !=
323 (Old.getRole() & ModuleMap::PrivateHeader))
324 return !(New.getRole() & ModuleMap::PrivateHeader);
325
326 // Prefer a non-textual header over a textual header.
327 if ((New.getRole() & ModuleMap::TextualHeader) !=
328 (Old.getRole() & ModuleMap::TextualHeader))
329 return !(New.getRole() & ModuleMap::TextualHeader);
330
331 // Don't have a reason to choose between these. Just keep the first one.
332 return false;
333}
334
Daniel Jasper92669ee2013-12-20 12:09:36 +0000335ModuleMap::KnownHeader
336ModuleMap::findModuleForHeader(const FileEntry *File,
Richard Smith306d8922014-10-22 23:50:56 +0000337 Module *RequestingModule,
338 bool IncludeTextualHeaders) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000339 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000340
Richard Smith306d8922014-10-22 23:50:56 +0000341 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Richard Smith202210b2014-10-24 20:23:01 +0000342 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
Richard Smith306d8922014-10-22 23:50:56 +0000343 return ModuleMap::KnownHeader();
344 return R;
345 };
346
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000347 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000348 ModuleMap::KnownHeader Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000349
Daniel Jasper97da9172013-10-22 08:09:47 +0000350 // Iterate over all modules that 'File' is part of to find the best fit.
351 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
352 E = Known->second.end();
353 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000354 // Cannot use a module if it is unavailable.
355 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000356 continue;
357
358 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
359 // module we are looking for.
360 if (I->getModule() == RequestingModule)
Richard Smith306d8922014-10-22 23:50:56 +0000361 return MakeResult(*I);
Daniel Jasper97da9172013-10-22 08:09:47 +0000362
363 // If uses need to be specified explicitly, we are only allowed to return
364 // modules that are explicitly used by the requesting module.
365 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000366 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000367 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000368
Richard Smithec87a502015-02-13 23:50:20 +0000369 if (!Result || isBetterKnownHeader(*I, Result))
Richard Smith202210b2014-10-24 20:23:01 +0000370 Result = *I;
Daniel Jasper97da9172013-10-22 08:09:47 +0000371 }
Richard Smith306d8922014-10-22 23:50:56 +0000372 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000373 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000374
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000375 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000376 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
377 if (H) {
378 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000379
Ben Langmuir44691382014-04-10 00:39:10 +0000380 // Search up the module stack until we find a module with an umbrella
381 // directory.
382 Module *UmbrellaModule = Result;
383 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
384 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000385
Ben Langmuir44691382014-04-10 00:39:10 +0000386 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000387 const FileEntry *UmbrellaModuleMap =
388 getModuleMapFileForUniquing(UmbrellaModule);
389
Ben Langmuir44691382014-04-10 00:39:10 +0000390 // Infer submodules for each of the directories we found between
391 // the directory of the umbrella header and the directory where
392 // the actual header is located.
393 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000394
Ben Langmuir44691382014-04-10 00:39:10 +0000395 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
396 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000397 SmallString<32> NameBuf;
398 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000399 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000400 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
401 Explicit).first;
402 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000403 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000404
405 // Associate the module and the directory.
406 UmbrellaDirs[SkippedDirs[I-1]] = Result;
407
408 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000409 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000410 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000411 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000412 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000413
Ben Langmuir44691382014-04-10 00:39:10 +0000414 // Infer a submodule with the same name as this header file.
415 SmallString<32> NameBuf;
416 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000417 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000418 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
419 Explicit).first;
420 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000421 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000422 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000423
Ben Langmuir44691382014-04-10 00:39:10 +0000424 // If inferred submodules export everything they import, add a
425 // wildcard to the set of exports.
426 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000427 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000428 } else {
429 // Record each of the directories we stepped through as being part of
430 // the module we found, since the umbrella header covers them all.
431 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
432 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000433 }
Ben Langmuir44691382014-04-10 00:39:10 +0000434
435 Headers[File].push_back(KnownHeader(Result, NormalHeader));
436
437 // If a header corresponds to an unavailable module, don't report
438 // that it maps to anything.
439 if (!Result->isAvailable())
440 return KnownHeader();
441
Richard Smith306d8922014-10-22 23:50:56 +0000442 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000443 }
Richard Smith306d8922014-10-22 23:50:56 +0000444
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000445 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000446}
447
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000448bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000449 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000450}
451
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000452bool
453ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
454 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000455 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000456 if (Known != Headers.end()) {
457 for (SmallVectorImpl<KnownHeader>::const_iterator
458 I = Known->second.begin(),
459 E = Known->second.end();
460 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000461 if (I->isAvailable() && (!RequestingModule ||
462 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000463 return false;
464 }
465 return true;
466 }
Richard Smith50996ce2014-04-08 13:13:04 +0000467
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000468 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000469 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000470 StringRef DirName = Dir->getName();
471
Richard Smith50996ce2014-04-08 13:13:04 +0000472 auto IsUnavailable = [&](const Module *M) {
473 return !M->isAvailable() && (!RequestingModule ||
474 M->isSubModuleOf(RequestingModule));
475 };
476
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000477 // Keep walking up the directory hierarchy, looking for a directory with
478 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000479 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000480 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000481 = UmbrellaDirs.find(Dir);
482 if (KnownDir != UmbrellaDirs.end()) {
483 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000484 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000485 return true;
486
487 // Search up the module stack until we find a module with an umbrella
488 // directory.
489 Module *UmbrellaModule = Found;
490 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
491 UmbrellaModule = UmbrellaModule->Parent;
492
493 if (UmbrellaModule->InferSubmodules) {
494 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
495 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000496 SmallString<32> NameBuf;
497 StringRef Name = sanitizeFilenameAsIdentifier(
498 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
499 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000500 Found = lookupModuleQualified(Name, Found);
501 if (!Found)
502 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000503 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000504 return true;
505 }
506
507 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000508 SmallString<32> NameBuf;
509 StringRef Name = sanitizeFilenameAsIdentifier(
510 llvm::sys::path::stem(Header->getName()),
511 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000512 Found = lookupModuleQualified(Name, Found);
513 if (!Found)
514 return false;
515 }
516
Richard Smith50996ce2014-04-08 13:13:04 +0000517 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000518 }
519
520 SkippedDirs.push_back(Dir);
521
522 // Retrieve our parent path.
523 DirName = llvm::sys::path::parent_path(DirName);
524 if (DirName.empty())
525 break;
526
527 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000528 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000529 } while (Dir);
530
531 return false;
532}
533
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000534Module *ModuleMap::findModule(StringRef Name) const {
535 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000536 if (Known != Modules.end())
537 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000538
539 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000540}
541
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000542Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
543 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000544 for(; Context; Context = Context->Parent) {
545 if (Module *Sub = lookupModuleQualified(Name, Context))
546 return Sub;
547 }
548
549 return findModule(Name);
550}
551
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000552Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000553 if (!Context)
554 return findModule(Name);
555
Douglas Gregoreb90e832012-01-04 23:32:19 +0000556 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000557}
558
Douglas Gregorde3ef502011-11-30 23:21:26 +0000559std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000560ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000561 bool IsExplicit) {
562 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000563 if (Module *Sub = lookupModuleQualified(Name, Parent))
564 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000565
566 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000567 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000568 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000569 if (LangOpts.CurrentModule == Name) {
570 SourceModule = Result;
571 SourceModuleName = Name;
572 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000573 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000574 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000575 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
576 Name == LangOpts.CurrentModule) {
577 CompilingModule = Result;
578 }
579 }
Douglas Gregor69021972011-11-30 17:33:56 +0000580 return std::make_pair(Result, true);
581}
582
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000583/// \brief For a framework module, infer the framework against which we
584/// should link.
585static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
586 FileManager &FileMgr) {
587 assert(Mod->IsFramework && "Can only infer linking for framework modules");
588 assert(!Mod->isSubFramework() &&
589 "Can only infer linking for top-level frameworks");
590
591 SmallString<128> LibName;
592 LibName += FrameworkDir->getName();
593 llvm::sys::path::append(LibName, Mod->Name);
594 if (FileMgr.getFile(LibName)) {
595 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
596 /*IsFramework=*/true));
597 }
598}
599
Douglas Gregorde3ef502011-11-30 23:21:26 +0000600Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000601ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000602 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000603 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000604 Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000605 Attributes Attrs;
606 Attrs.IsSystem = IsSystem;
607 return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent);
608}
609
610Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
611 const DirectoryEntry *FrameworkDir,
612 Attributes Attrs, Module *Parent) {
613
Douglas Gregor56c64012011-11-17 01:41:17 +0000614 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000615 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
616 return Mod;
617
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000618 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000619
620 // If the framework has a parent path from which we're allowed to infer
621 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000622 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000623 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000624 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000625
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000626 // Note: as an egregious but useful hack we use the real path here, because
627 // we might be looking at an embedded framework that symlinks out to a
628 // top-level framework, and we need to infer as if we were naming the
629 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000630 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000631 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000632
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000633 // In case this is a case-insensitive filesystem, make sure the canonical
634 // directory name matches ModuleName exactly. Modules are case-sensitive.
635 // FIXME: we should be able to give a fix-it hint for the correct spelling.
636 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
637 return nullptr;
638
Douglas Gregor9194a912012-11-06 19:39:40 +0000639 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000640 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000641 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000642 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000643 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
644 // Check whether we have already looked into the parent directory
645 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000646 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000647 inferred = InferredDirectories.find(ParentDir);
648 if (inferred == InferredDirectories.end()) {
649 // We haven't looked here before. Load a module map, if there is
650 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000651 bool IsFrameworkDir = Parent.endswith(".framework");
652 if (const FileEntry *ModMapFile =
653 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000654 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000655 inferred = InferredDirectories.find(ParentDir);
656 }
657
658 if (inferred == InferredDirectories.end())
659 inferred = InferredDirectories.insert(
660 std::make_pair(ParentDir, InferredDirectory())).first;
661 }
662
663 if (inferred->second.InferModules) {
664 // We're allowed to infer for this directory, but make sure it's okay
665 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000666 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000667 canInfer = std::find(inferred->second.ExcludedModules.begin(),
668 inferred->second.ExcludedModules.end(),
669 Name) == inferred->second.ExcludedModules.end();
670
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000671 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
672 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
673 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000674 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000675 }
676 }
677 }
678
679 // If we're not allowed to infer a framework module, don't.
680 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000681 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000682 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000683 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000684
685
Douglas Gregor56c64012011-11-17 01:41:17 +0000686 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000687 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000688 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000689 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000690
691 // FIXME: If there's no umbrella header, we could probably scan the
692 // framework to load *everything*. But, it's not clear that this is a good
693 // idea.
694 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000695 return nullptr;
696
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000697 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000698 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000699 InferredModuleAllowedBy[Result] = ModuleMapFile;
700 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000701 if (LangOpts.CurrentModule == ModuleName) {
702 SourceModule = Result;
703 SourceModuleName = ModuleName;
704 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000705
706 Result->IsSystem |= Attrs.IsSystem;
707 Result->IsExternC |= Attrs.IsExternC;
708 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
709
Douglas Gregoreb90e832012-01-04 23:32:19 +0000710 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000711 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000712
Douglas Gregor322f6332011-12-08 18:00:48 +0000713 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000714 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000715 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000716 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000717
718 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000719 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
720
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000721 // module * { export * }
722 Result->InferSubmodules = true;
723 Result->InferExportWildcard = true;
724
Douglas Gregore89dbc12011-12-06 19:39:29 +0000725 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000726 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000727 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000728 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000729 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000730 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000731 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000732 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000733 Dir != DirEnd && !EC; Dir.increment(EC)) {
734 if (!StringRef(Dir->path()).endswith(".framework"))
735 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000736
Douglas Gregore89dbc12011-12-06 19:39:29 +0000737 if (const DirectoryEntry *SubframeworkDir
738 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000739 // Note: as an egregious but useful hack, we use the real path here and
740 // check whether it is actually a subdirectory of the parent directory.
741 // This will not be the case if the 'subframework' is actually a symlink
742 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000743 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
744 bool FoundParent = false;
745 do {
746 // Get the parent directory name.
747 SubframeworkDirName
748 = llvm::sys::path::parent_path(SubframeworkDirName);
749 if (SubframeworkDirName.empty())
750 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000751
Douglas Gregore00c8b22013-01-26 00:55:12 +0000752 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
753 FoundParent = true;
754 break;
755 }
756 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000757
Douglas Gregore00c8b22013-01-26 00:55:12 +0000758 if (!FoundParent)
759 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000760
Douglas Gregore89dbc12011-12-06 19:39:29 +0000761 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000762 SmallString<32> NameBuf;
763 inferFrameworkModule(sanitizeFilenameAsIdentifier(
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000764 llvm::sys::path::stem(Dir->path()), NameBuf),
765 SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000766 }
767 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000768
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000769 // If the module is a top-level framework, automatically link against the
770 // framework.
771 if (!Result->isSubFramework()) {
772 inferFrameworkLink(Result, FrameworkDir, FileMgr);
773 }
774
Douglas Gregor56c64012011-11-17 01:41:17 +0000775 return Result;
776}
777
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000778void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000779 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000780 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000781 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000782}
783
Douglas Gregor524e33e2011-12-08 19:11:24 +0000784void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
785 Mod->Umbrella = UmbrellaDir;
786 UmbrellaDirs[UmbrellaDir] = Mod;
787}
788
Richard Smith3c1a41a2014-12-02 00:08:08 +0000789static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000790 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000791 default: llvm_unreachable("unknown header role");
792 case ModuleMap::NormalHeader:
793 return Module::HK_Normal;
794 case ModuleMap::PrivateHeader:
795 return Module::HK_Private;
796 case ModuleMap::TextualHeader:
797 return Module::HK_Textual;
798 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
799 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000800 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000801}
802
Richard Smith3c1a41a2014-12-02 00:08:08 +0000803void ModuleMap::addHeader(Module *Mod, Module::Header Header,
804 ModuleHeaderRole Role) {
805 if (!(Role & TextualHeader)) {
806 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
807 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
808 isCompilingModuleHeader);
809 }
810 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
Richard Smithfeb54b62014-10-23 02:01:19 +0000811
Richard Smith3c1a41a2014-12-02 00:08:08 +0000812 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
813}
814
815void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000816 // Add this as a known header so we won't implicitly add it to any
817 // umbrella directory module.
818 // FIXME: Should we only exclude it from umbrella modules within the
819 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000820 (void) Headers[Header.Entry];
821
822 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000823}
824
Douglas Gregor514b6362011-11-29 19:06:37 +0000825const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000826ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000827 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000828 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000829
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000830 return SourceMgr.getFileEntryForID(
831 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000832}
833
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000834const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000835 if (M->IsInferred) {
836 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
837 return InferredModuleAllowedBy.find(M)->second;
838 }
839 return getContainingModuleMapFile(M);
840}
841
842void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
843 assert(M->IsInferred && "module not inferred");
844 InferredModuleAllowedBy[M] = ModMap;
845}
846
Douglas Gregor718292f2011-11-11 19:10:28 +0000847void ModuleMap::dump() {
848 llvm::errs() << "Modules:";
849 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
850 MEnd = Modules.end();
851 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000852 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000853
854 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000855 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000856 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000857 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
858 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
859 E = H->second.end();
860 I != E; ++I) {
861 if (I != H->second.begin())
862 llvm::errs() << ",";
863 llvm::errs() << I->getModule()->getFullModuleName();
864 }
865 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000866 }
867}
868
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000869bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
870 bool HadError = false;
871 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
872 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
873 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000874 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000875 Mod->Exports.push_back(Export);
876 else
877 HadError = true;
878 }
879 Mod->UnresolvedExports.clear();
880 return HadError;
881}
882
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000883bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
884 bool HadError = false;
885 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
886 Module *DirectUse =
887 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
888 if (DirectUse)
889 Mod->DirectUses.push_back(DirectUse);
890 else
891 HadError = true;
892 }
893 Mod->UnresolvedDirectUses.clear();
894 return HadError;
895}
896
Douglas Gregorfb912652013-03-20 21:10:35 +0000897bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
898 bool HadError = false;
899 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
900 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
901 Mod, Complain);
902 if (!OtherMod) {
903 HadError = true;
904 continue;
905 }
906
907 Module::Conflict Conflict;
908 Conflict.Other = OtherMod;
909 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
910 Mod->Conflicts.push_back(Conflict);
911 }
912 Mod->UnresolvedConflicts.clear();
913 return HadError;
914}
915
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000916Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
917 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000918 return nullptr;
919
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000920 // Use the expansion location to determine which module we're in.
921 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
922 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000923 return nullptr;
924
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000925 const SourceManager &SrcMgr = Loc.getManager();
926 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000927
Douglas Gregor224d8a72012-01-06 17:19:32 +0000928 while (const FileEntry *ExpansionFile
929 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
930 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000931 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000932 return Mod;
933
934 // No module owns this header, so look up the inclusion chain to see if
935 // any included header has an associated module.
936 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
937 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000938 return nullptr;
939
Douglas Gregor224d8a72012-01-06 17:19:32 +0000940 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
941 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000942
943 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000944}
945
Douglas Gregor718292f2011-11-11 19:10:28 +0000946//----------------------------------------------------------------------------//
947// Module map file parser
948//----------------------------------------------------------------------------//
949
950namespace clang {
951 /// \brief A token in a module map file.
952 struct MMToken {
953 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000954 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000955 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000956 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000957 EndOfFile,
958 HeaderKeyword,
959 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000960 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000961 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000962 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000963 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000964 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000965 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000966 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000967 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000968 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000969 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000970 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000971 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000972 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000973 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000974 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000975 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000976 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000977 RBrace,
978 LSquare,
979 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000980 } Kind;
981
982 unsigned Location;
983 unsigned StringLength;
984 const char *StringData;
985
986 void clear() {
987 Kind = EndOfFile;
988 Location = 0;
989 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000990 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000991 }
992
993 bool is(TokenKind K) const { return Kind == K; }
994
995 SourceLocation getLocation() const {
996 return SourceLocation::getFromRawEncoding(Location);
997 }
998
999 StringRef getString() const {
1000 return StringRef(StringData, StringLength);
1001 }
1002 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001003
Douglas Gregor718292f2011-11-11 19:10:28 +00001004 class ModuleMapParser {
1005 Lexer &L;
1006 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001007
1008 /// \brief Default target information, used only for string literal
1009 /// parsing.
1010 const TargetInfo *Target;
1011
Douglas Gregor718292f2011-11-11 19:10:28 +00001012 DiagnosticsEngine &Diags;
1013 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001014
1015 /// \brief The current module map file.
1016 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001017
Richard Smith9acb99e32014-12-10 03:09:48 +00001018 /// \brief The directory that file names in this module map file should
1019 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001020 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001021
1022 /// \brief The directory containing Clang-supplied headers.
1023 const DirectoryEntry *BuiltinIncludeDir;
1024
Douglas Gregor963c5532013-06-21 16:28:10 +00001025 /// \brief Whether this module map is in a system header directory.
1026 bool IsSystem;
1027
Douglas Gregor718292f2011-11-11 19:10:28 +00001028 /// \brief Whether an error occurred.
1029 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001030
Douglas Gregor718292f2011-11-11 19:10:28 +00001031 /// \brief Stores string data for the various string literals referenced
1032 /// during parsing.
1033 llvm::BumpPtrAllocator StringData;
1034
1035 /// \brief The current token.
1036 MMToken Tok;
1037
1038 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001039 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001040
1041 /// \brief Consume the current token and return its location.
1042 SourceLocation consumeToken();
1043
1044 /// \brief Skip tokens until we reach the a token with the given kind
1045 /// (or the end of the file).
1046 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001047
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001048 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001049 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001050 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001051 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001052 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001053 void parseHeaderDecl(clang::MMToken::TokenKind,
1054 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001055 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001056 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001057 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001058 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001059 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001060 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001061 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001062
1063 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001064 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001065
Douglas Gregor718292f2011-11-11 19:10:28 +00001066 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001067 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001068 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001069 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001070 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001071 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001072 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001073 const DirectoryEntry *BuiltinIncludeDir,
1074 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001075 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001076 ModuleMapFile(ModuleMapFile), Directory(Directory),
1077 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001078 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001079 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001080 Tok.clear();
1081 consumeToken();
1082 }
1083
1084 bool parseModuleMapFile();
1085 };
1086}
1087
1088SourceLocation ModuleMapParser::consumeToken() {
1089retry:
1090 SourceLocation Result = Tok.getLocation();
1091 Tok.clear();
1092
1093 Token LToken;
1094 L.LexFromRawLexer(LToken);
1095 Tok.Location = LToken.getLocation().getRawEncoding();
1096 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001097 case tok::raw_identifier: {
1098 StringRef RI = LToken.getRawIdentifier();
1099 Tok.StringData = RI.data();
1100 Tok.StringLength = RI.size();
1101 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001102 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001103 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001104 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001105 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001106 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001107 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001108 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001109 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001110 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001111 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001112 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001113 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001114 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001115 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001116 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001117 .Default(MMToken::Identifier);
1118 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001119 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001120
1121 case tok::comma:
1122 Tok.Kind = MMToken::Comma;
1123 break;
1124
Douglas Gregor718292f2011-11-11 19:10:28 +00001125 case tok::eof:
1126 Tok.Kind = MMToken::EndOfFile;
1127 break;
1128
1129 case tok::l_brace:
1130 Tok.Kind = MMToken::LBrace;
1131 break;
1132
Douglas Gregora686e1b2012-01-27 19:52:33 +00001133 case tok::l_square:
1134 Tok.Kind = MMToken::LSquare;
1135 break;
1136
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001137 case tok::period:
1138 Tok.Kind = MMToken::Period;
1139 break;
1140
Douglas Gregor718292f2011-11-11 19:10:28 +00001141 case tok::r_brace:
1142 Tok.Kind = MMToken::RBrace;
1143 break;
1144
Douglas Gregora686e1b2012-01-27 19:52:33 +00001145 case tok::r_square:
1146 Tok.Kind = MMToken::RSquare;
1147 break;
1148
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001149 case tok::star:
1150 Tok.Kind = MMToken::Star;
1151 break;
1152
Richard Smitha3feee22013-10-28 22:18:19 +00001153 case tok::exclaim:
1154 Tok.Kind = MMToken::Exclaim;
1155 break;
1156
Douglas Gregor718292f2011-11-11 19:10:28 +00001157 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001158 if (LToken.hasUDSuffix()) {
1159 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1160 HadError = true;
1161 goto retry;
1162 }
1163
Douglas Gregor718292f2011-11-11 19:10:28 +00001164 // Parse the string literal.
1165 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001166 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001167 if (StringLiteral.hadError)
1168 goto retry;
1169
1170 // Copy the string literal into our string data allocator.
1171 unsigned Length = StringLiteral.GetStringLength();
1172 char *Saved = StringData.Allocate<char>(Length + 1);
1173 memcpy(Saved, StringLiteral.GetString().data(), Length);
1174 Saved[Length] = 0;
1175
1176 // Form the token.
1177 Tok.Kind = MMToken::StringLiteral;
1178 Tok.StringData = Saved;
1179 Tok.StringLength = Length;
1180 break;
1181 }
1182
1183 case tok::comment:
1184 goto retry;
1185
1186 default:
1187 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1188 HadError = true;
1189 goto retry;
1190 }
1191
1192 return Result;
1193}
1194
1195void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1196 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001197 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001198 do {
1199 switch (Tok.Kind) {
1200 case MMToken::EndOfFile:
1201 return;
1202
1203 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001204 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001205 return;
1206
1207 ++braceDepth;
1208 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001209
1210 case MMToken::LSquare:
1211 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1212 return;
1213
1214 ++squareDepth;
1215 break;
1216
Douglas Gregor718292f2011-11-11 19:10:28 +00001217 case MMToken::RBrace:
1218 if (braceDepth > 0)
1219 --braceDepth;
1220 else if (Tok.is(K))
1221 return;
1222 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001223
1224 case MMToken::RSquare:
1225 if (squareDepth > 0)
1226 --squareDepth;
1227 else if (Tok.is(K))
1228 return;
1229 break;
1230
Douglas Gregor718292f2011-11-11 19:10:28 +00001231 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001232 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001233 return;
1234 break;
1235 }
1236
1237 consumeToken();
1238 } while (true);
1239}
1240
Douglas Gregore7ab3662011-12-07 02:23:45 +00001241/// \brief Parse a module-id.
1242///
1243/// module-id:
1244/// identifier
1245/// identifier '.' module-id
1246///
1247/// \returns true if an error occurred, false otherwise.
1248bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1249 Id.clear();
1250 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001251 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001252 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1253 consumeToken();
1254 } else {
1255 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1256 return true;
1257 }
1258
1259 if (!Tok.is(MMToken::Period))
1260 break;
1261
1262 consumeToken();
1263 } while (true);
1264
1265 return false;
1266}
1267
Douglas Gregora686e1b2012-01-27 19:52:33 +00001268namespace {
1269 /// \brief Enumerates the known attributes.
1270 enum AttributeKind {
1271 /// \brief An unknown attribute.
1272 AT_unknown,
1273 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001274 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001275 /// \brief The 'extern_c' attribute.
1276 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001277 /// \brief The 'exhaustive' attribute.
1278 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001279 };
1280}
1281
Douglas Gregor718292f2011-11-11 19:10:28 +00001282/// \brief Parse a module declaration.
1283///
1284/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001285/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001286/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1287/// { module-member* }
1288///
Douglas Gregor718292f2011-11-11 19:10:28 +00001289/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001290/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001291/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001292/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001293/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001294/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001295///
1296/// submodule-declaration:
1297/// module-declaration
1298/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001299void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001300 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001301 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1302 if (Tok.is(MMToken::ExternKeyword)) {
1303 parseExternModuleDecl();
1304 return;
1305 }
1306
Douglas Gregorf2161a72011-12-06 17:16:41 +00001307 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001308 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001309 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001310 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001311
Douglas Gregorf2161a72011-12-06 17:16:41 +00001312 // Parse 'explicit' keyword, if present.
1313 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001314 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001315 Explicit = true;
1316 }
1317
1318 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001319 if (Tok.is(MMToken::FrameworkKeyword)) {
1320 consumeToken();
1321 Framework = true;
1322 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001323
1324 // Parse 'module' keyword.
1325 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001326 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001327 consumeToken();
1328 HadError = true;
1329 return;
1330 }
1331 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001332
1333 // If we have a wildcard for the module name, this is an inferred submodule.
1334 // Parse it.
1335 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001336 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001337
1338 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001339 ModuleId Id;
1340 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001341 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001342 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001343 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001344
Douglas Gregore7ab3662011-12-07 02:23:45 +00001345 if (ActiveModule) {
1346 if (Id.size() > 1) {
1347 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1348 << SourceRange(Id.front().second, Id.back().second);
1349
1350 HadError = true;
1351 return;
1352 }
1353 } else if (Id.size() == 1 && Explicit) {
1354 // Top-level modules can't be explicit.
1355 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1356 Explicit = false;
1357 ExplicitLoc = SourceLocation();
1358 HadError = true;
1359 }
1360
1361 Module *PreviousActiveModule = ActiveModule;
1362 if (Id.size() > 1) {
1363 // This module map defines a submodule. Go find the module of which it
1364 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001365 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001366 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001367 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1368 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001369 if (I == 0)
1370 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001371 ActiveModule = Next;
1372 continue;
1373 }
1374
1375 if (ActiveModule) {
1376 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001377 << Id[I].first
1378 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001379 } else {
1380 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1381 }
1382 HadError = true;
1383 return;
1384 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001385
1386 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1387 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1388 "submodule defined in same file as 'module *' that allowed its "
1389 "top-level module");
1390 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1391 }
1392 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001393
1394 StringRef ModuleName = Id.back().first;
1395 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001396
Douglas Gregora686e1b2012-01-27 19:52:33 +00001397 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001398 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001399 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001400
Douglas Gregor718292f2011-11-11 19:10:28 +00001401 // Parse the opening brace.
1402 if (!Tok.is(MMToken::LBrace)) {
1403 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1404 << ModuleName;
1405 HadError = true;
1406 return;
1407 }
1408 SourceLocation LBraceLoc = consumeToken();
1409
1410 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001411 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001412 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1413 // Skip the module definition.
1414 skipUntil(MMToken::RBrace);
1415 if (Tok.is(MMToken::RBrace))
1416 consumeToken();
1417 else {
1418 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1419 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1420 HadError = true;
1421 }
1422 return;
1423 }
1424
Douglas Gregor718292f2011-11-11 19:10:28 +00001425 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1426 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001427 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001428
1429 // Skip the module definition.
1430 skipUntil(MMToken::RBrace);
1431 if (Tok.is(MMToken::RBrace))
1432 consumeToken();
1433
1434 HadError = true;
1435 return;
1436 }
1437
1438 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001439 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1440 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001441 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001442 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001443 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001444 if (Attrs.IsExternC)
1445 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001446 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001447
Douglas Gregor718292f2011-11-11 19:10:28 +00001448 bool Done = false;
1449 do {
1450 switch (Tok.Kind) {
1451 case MMToken::EndOfFile:
1452 case MMToken::RBrace:
1453 Done = true;
1454 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001455
1456 case MMToken::ConfigMacros:
1457 parseConfigMacros();
1458 break;
1459
Douglas Gregorfb912652013-03-20 21:10:35 +00001460 case MMToken::Conflict:
1461 parseConflict();
1462 break;
1463
Douglas Gregor718292f2011-11-11 19:10:28 +00001464 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001465 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001466 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001467 case MMToken::ModuleKeyword:
1468 parseModuleDecl();
1469 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001470
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001471 case MMToken::ExportKeyword:
1472 parseExportDecl();
1473 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001474
1475 case MMToken::UseKeyword:
1476 parseUseDecl();
1477 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001478
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001479 case MMToken::RequiresKeyword:
1480 parseRequiresDecl();
1481 break;
1482
Richard Smith202210b2014-10-24 20:23:01 +00001483 case MMToken::TextualKeyword:
1484 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001485 break;
Richard Smith306d8922014-10-22 23:50:56 +00001486
Douglas Gregor524e33e2011-12-08 19:11:24 +00001487 case MMToken::UmbrellaKeyword: {
1488 SourceLocation UmbrellaLoc = consumeToken();
1489 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001490 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001491 else
1492 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001493 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001494 }
Richard Smith202210b2014-10-24 20:23:01 +00001495
1496 case MMToken::ExcludeKeyword:
1497 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001498 break;
Richard Smith202210b2014-10-24 20:23:01 +00001499
1500 case MMToken::PrivateKeyword:
1501 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001502 break;
Richard Smith202210b2014-10-24 20:23:01 +00001503
Douglas Gregor322f6332011-12-08 18:00:48 +00001504 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001505 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001506 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001507
1508 case MMToken::LinkKeyword:
1509 parseLinkDecl();
1510 break;
1511
Douglas Gregor718292f2011-11-11 19:10:28 +00001512 default:
1513 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1514 consumeToken();
1515 break;
1516 }
1517 } while (!Done);
1518
1519 if (Tok.is(MMToken::RBrace))
1520 consumeToken();
1521 else {
1522 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1523 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1524 HadError = true;
1525 }
1526
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001527 // If the active module is a top-level framework, and there are no link
1528 // libraries, automatically link against the framework.
1529 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1530 ActiveModule->LinkLibraries.empty()) {
1531 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1532 }
1533
Ben Langmuirec8c9752014-04-18 22:07:31 +00001534 // If the module meets all requirements but is still unavailable, mark the
1535 // whole tree as unavailable to prevent it from building.
1536 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1537 ActiveModule->Parent) {
1538 ActiveModule->getTopLevelModule()->markUnavailable();
1539 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1540 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1541 }
1542
Douglas Gregore7ab3662011-12-07 02:23:45 +00001543 // We're done parsing this module. Pop back to the previous module.
1544 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001545}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001546
Daniel Jasper97292842013-09-11 07:20:44 +00001547/// \brief Parse an extern module declaration.
1548///
1549/// extern module-declaration:
1550/// 'extern' 'module' module-id string-literal
1551void ModuleMapParser::parseExternModuleDecl() {
1552 assert(Tok.is(MMToken::ExternKeyword));
1553 consumeToken(); // 'extern' keyword
1554
1555 // Parse 'module' keyword.
1556 if (!Tok.is(MMToken::ModuleKeyword)) {
1557 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1558 consumeToken();
1559 HadError = true;
1560 return;
1561 }
1562 consumeToken(); // 'module' keyword
1563
1564 // Parse the module name.
1565 ModuleId Id;
1566 if (parseModuleId(Id)) {
1567 HadError = true;
1568 return;
1569 }
1570
1571 // Parse the referenced module map file name.
1572 if (!Tok.is(MMToken::StringLiteral)) {
1573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1574 HadError = true;
1575 return;
1576 }
1577 std::string FileName = Tok.getString();
1578 consumeToken(); // filename
1579
1580 StringRef FileNameRef = FileName;
1581 SmallString<128> ModuleMapFileName;
1582 if (llvm::sys::path::is_relative(FileNameRef)) {
1583 ModuleMapFileName += Directory->getName();
1584 llvm::sys::path::append(ModuleMapFileName, FileName);
1585 FileNameRef = ModuleMapFileName.str();
1586 }
1587 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001588 Map.parseModuleMapFile(
1589 File, /*IsSystem=*/false,
1590 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1591 ? Directory
1592 : File->getDir());
Daniel Jasper97292842013-09-11 07:20:44 +00001593}
1594
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001595/// \brief Parse a requires declaration.
1596///
1597/// requires-declaration:
1598/// 'requires' feature-list
1599///
1600/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001601/// feature ',' feature-list
1602/// feature
1603///
1604/// feature:
1605/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001606void ModuleMapParser::parseRequiresDecl() {
1607 assert(Tok.is(MMToken::RequiresKeyword));
1608
1609 // Parse 'requires' keyword.
1610 consumeToken();
1611
1612 // Parse the feature-list.
1613 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001614 bool RequiredState = true;
1615 if (Tok.is(MMToken::Exclaim)) {
1616 RequiredState = false;
1617 consumeToken();
1618 }
1619
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001620 if (!Tok.is(MMToken::Identifier)) {
1621 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1622 HadError = true;
1623 return;
1624 }
1625
1626 // Consume the feature name.
1627 std::string Feature = Tok.getString();
1628 consumeToken();
1629
1630 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001631 ActiveModule->addRequirement(Feature, RequiredState,
1632 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001633
1634 if (!Tok.is(MMToken::Comma))
1635 break;
1636
1637 // Consume the comma.
1638 consumeToken();
1639 } while (true);
1640}
1641
Douglas Gregorf2161a72011-12-06 17:16:41 +00001642/// \brief Append to \p Paths the set of paths needed to get to the
1643/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001644static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001645 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001646 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001647 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001648 for (; Mod; Mod = Mod->Parent) {
1649 if (Mod->IsFramework)
1650 Paths.push_back(Mod->Name);
1651 }
1652
1653 if (Paths.empty())
1654 return;
1655
1656 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001657 for (unsigned I = Paths.size() - 1; I != 0; --I)
1658 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001659}
1660
Douglas Gregor718292f2011-11-11 19:10:28 +00001661/// \brief Parse a header declaration.
1662///
1663/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001664/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001665/// 'private' 'textual'[opt] 'header' string-literal
1666/// 'exclude' 'header' string-literal
1667/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001668///
1669/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001670void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1671 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001672 // We've already consumed the first token.
1673 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1674 if (LeadingToken == MMToken::PrivateKeyword) {
1675 Role = ModuleMap::PrivateHeader;
1676 // 'private' may optionally be followed by 'textual'.
1677 if (Tok.is(MMToken::TextualKeyword)) {
1678 LeadingToken = Tok.Kind;
1679 consumeToken();
1680 }
1681 }
1682 if (LeadingToken == MMToken::TextualKeyword)
1683 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1684
1685 if (LeadingToken != MMToken::HeaderKeyword) {
1686 if (!Tok.is(MMToken::HeaderKeyword)) {
1687 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1688 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1689 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1690 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1691 return;
1692 }
1693 consumeToken();
1694 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001695
Douglas Gregor718292f2011-11-11 19:10:28 +00001696 // Parse the header name.
1697 if (!Tok.is(MMToken::StringLiteral)) {
1698 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1699 << "header";
1700 HadError = true;
1701 return;
1702 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001703 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001704 Header.FileName = Tok.getString();
1705 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001706
Douglas Gregor524e33e2011-12-08 19:11:24 +00001707 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001708 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001709 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001710 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001711 HadError = true;
1712 return;
1713 }
1714
Douglas Gregor5257fc62011-11-11 21:55:48 +00001715 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001716 const FileEntry *File = nullptr;
1717 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001718 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001719 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001720 RelativePathName = Header.FileName;
1721 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001722 } else {
1723 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001724 SmallString<128> FullPathName(Directory->getName());
1725 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001726
Douglas Gregorf2161a72011-12-06 17:16:41 +00001727 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001728 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001729
1730 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001731 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1732 llvm::sys::path::append(FullPathName, RelativePathName.str());
1733 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001734
1735 if (!File) {
1736 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001737 // FIXME: Should we retain the subframework paths here?
1738 RelativePathName.clear();
1739 FullPathName.resize(FullPathLength);
1740 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1741 Header.FileName);
1742 llvm::sys::path::append(FullPathName, RelativePathName.str());
1743 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001744 }
1745 } else {
1746 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001747 llvm::sys::path::append(RelativePathName, Header.FileName);
1748 llvm::sys::path::append(FullPathName, RelativePathName.str());
1749 File = SourceMgr.getFileManager().getFile(FullPathName);
1750
Douglas Gregor3ec66632012-02-02 18:42:48 +00001751 // If this is a system module with a top-level header, this header
1752 // may have a counterpart (or replacement) in the set of headers
1753 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001754 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1755 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001756 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001757 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001758 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001759 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001760
Douglas Gregor3ec66632012-02-02 18:42:48 +00001761 // If Clang supplies this header but the underlying system does not,
1762 // just silently swap in our builtin version. Otherwise, we'll end
1763 // up adding both (later).
1764 if (!File && BuiltinFile) {
1765 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001766 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001767 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001768 }
1769 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001770 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001771 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001772
Douglas Gregor5257fc62011-11-11 21:55:48 +00001773 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1774 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001775 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001776 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001777 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001778 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001779 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001780 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001781 HadError = true;
1782 } else {
1783 // Record this umbrella header.
1784 Map.setUmbrellaHeader(ActiveModule, File);
1785 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001786 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001787 Module::Header H = {RelativePathName.str(), File};
1788 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001789 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001790 // If there is a builtin counterpart to this file, add it now, before
1791 // the "real" header, so we build the built-in one first when building
1792 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001793 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001794 // FIXME: Taking the name from the FileEntry is unstable and can give
1795 // different results depending on how we've previously named that file
1796 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001797 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1798 Map.addHeader(ActiveModule, H, Role);
1799 }
Richard Smith25d50752014-10-20 00:15:49 +00001800
Richard Smith202210b2014-10-24 20:23:01 +00001801 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001802 Module::Header H = { RelativePathName.str(), File };
1803 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001804 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001805 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001806 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001807
1808 // If we find a module that has a missing header, we mark this module as
1809 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001810 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001811 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001812 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001813 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001814}
1815
Douglas Gregor524e33e2011-12-08 19:11:24 +00001816/// \brief Parse an umbrella directory declaration.
1817///
1818/// umbrella-dir-declaration:
1819/// umbrella string-literal
1820void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1821 // Parse the directory name.
1822 if (!Tok.is(MMToken::StringLiteral)) {
1823 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1824 << "umbrella";
1825 HadError = true;
1826 return;
1827 }
1828
1829 std::string DirName = Tok.getString();
1830 SourceLocation DirNameLoc = consumeToken();
1831
1832 // Check whether we already have an umbrella.
1833 if (ActiveModule->Umbrella) {
1834 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1835 << ActiveModule->getFullModuleName();
1836 HadError = true;
1837 return;
1838 }
1839
1840 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001841 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001842 if (llvm::sys::path::is_absolute(DirName))
1843 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1844 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001845 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001846 PathName = Directory->getName();
1847 llvm::sys::path::append(PathName, DirName);
1848 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1849 }
1850
1851 if (!Dir) {
1852 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1853 << DirName;
1854 HadError = true;
1855 return;
1856 }
1857
1858 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1859 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1860 << OwningModule->getFullModuleName();
1861 HadError = true;
1862 return;
1863 }
1864
1865 // Record this umbrella directory.
1866 Map.setUmbrellaDir(ActiveModule, Dir);
1867}
1868
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001869/// \brief Parse a module export declaration.
1870///
1871/// export-declaration:
1872/// 'export' wildcard-module-id
1873///
1874/// wildcard-module-id:
1875/// identifier
1876/// '*'
1877/// identifier '.' wildcard-module-id
1878void ModuleMapParser::parseExportDecl() {
1879 assert(Tok.is(MMToken::ExportKeyword));
1880 SourceLocation ExportLoc = consumeToken();
1881
1882 // Parse the module-id with an optional wildcard at the end.
1883 ModuleId ParsedModuleId;
1884 bool Wildcard = false;
1885 do {
Richard Smith306d8922014-10-22 23:50:56 +00001886 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001887 if (Tok.is(MMToken::Identifier)) {
1888 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1889 Tok.getLocation()));
1890 consumeToken();
1891
1892 if (Tok.is(MMToken::Period)) {
1893 consumeToken();
1894 continue;
1895 }
1896
1897 break;
1898 }
1899
1900 if(Tok.is(MMToken::Star)) {
1901 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001902 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001903 break;
1904 }
1905
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001906 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001907 HadError = true;
1908 return;
1909 } while (true);
1910
1911 Module::UnresolvedExportDecl Unresolved = {
1912 ExportLoc, ParsedModuleId, Wildcard
1913 };
1914 ActiveModule->UnresolvedExports.push_back(Unresolved);
1915}
1916
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001917/// \brief Parse a module uses declaration.
1918///
1919/// uses-declaration:
1920/// 'uses' wildcard-module-id
1921void ModuleMapParser::parseUseDecl() {
1922 assert(Tok.is(MMToken::UseKeyword));
1923 consumeToken();
1924 // Parse the module-id.
1925 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001926 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001927
1928 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1929}
1930
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001931/// \brief Parse a link declaration.
1932///
1933/// module-declaration:
1934/// 'link' 'framework'[opt] string-literal
1935void ModuleMapParser::parseLinkDecl() {
1936 assert(Tok.is(MMToken::LinkKeyword));
1937 SourceLocation LinkLoc = consumeToken();
1938
1939 // Parse the optional 'framework' keyword.
1940 bool IsFramework = false;
1941 if (Tok.is(MMToken::FrameworkKeyword)) {
1942 consumeToken();
1943 IsFramework = true;
1944 }
1945
1946 // Parse the library name
1947 if (!Tok.is(MMToken::StringLiteral)) {
1948 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1949 << IsFramework << SourceRange(LinkLoc);
1950 HadError = true;
1951 return;
1952 }
1953
1954 std::string LibraryName = Tok.getString();
1955 consumeToken();
1956 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1957 IsFramework));
1958}
1959
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001960/// \brief Parse a configuration macro declaration.
1961///
1962/// module-declaration:
1963/// 'config_macros' attributes[opt] config-macro-list?
1964///
1965/// config-macro-list:
1966/// identifier (',' identifier)?
1967void ModuleMapParser::parseConfigMacros() {
1968 assert(Tok.is(MMToken::ConfigMacros));
1969 SourceLocation ConfigMacrosLoc = consumeToken();
1970
1971 // Only top-level modules can have configuration macros.
1972 if (ActiveModule->Parent) {
1973 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1974 }
1975
1976 // Parse the optional attributes.
1977 Attributes Attrs;
1978 parseOptionalAttributes(Attrs);
1979 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1980 ActiveModule->ConfigMacrosExhaustive = true;
1981 }
1982
1983 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001984 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001985 if (!Tok.is(MMToken::Identifier))
1986 return;
1987
1988 // Consume the first identifier.
1989 if (!ActiveModule->Parent) {
1990 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1991 }
1992 consumeToken();
1993
1994 do {
1995 // If there's a comma, consume it.
1996 if (!Tok.is(MMToken::Comma))
1997 break;
1998 consumeToken();
1999
2000 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002001 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002002 if (!Tok.is(MMToken::Identifier)) {
2003 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2004 break;
2005 }
2006
2007 // Consume the macro name.
2008 if (!ActiveModule->Parent) {
2009 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2010 }
2011 consumeToken();
2012 } while (true);
2013}
2014
Douglas Gregorfb912652013-03-20 21:10:35 +00002015/// \brief Format a module-id into a string.
2016static std::string formatModuleId(const ModuleId &Id) {
2017 std::string result;
2018 {
2019 llvm::raw_string_ostream OS(result);
2020
2021 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2022 if (I)
2023 OS << ".";
2024 OS << Id[I].first;
2025 }
2026 }
2027
2028 return result;
2029}
2030
2031/// \brief Parse a conflict declaration.
2032///
2033/// module-declaration:
2034/// 'conflict' module-id ',' string-literal
2035void ModuleMapParser::parseConflict() {
2036 assert(Tok.is(MMToken::Conflict));
2037 SourceLocation ConflictLoc = consumeToken();
2038 Module::UnresolvedConflict Conflict;
2039
2040 // Parse the module-id.
2041 if (parseModuleId(Conflict.Id))
2042 return;
2043
2044 // Parse the ','.
2045 if (!Tok.is(MMToken::Comma)) {
2046 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2047 << SourceRange(ConflictLoc);
2048 return;
2049 }
2050 consumeToken();
2051
2052 // Parse the message.
2053 if (!Tok.is(MMToken::StringLiteral)) {
2054 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2055 << formatModuleId(Conflict.Id);
2056 return;
2057 }
2058 Conflict.Message = Tok.getString().str();
2059 consumeToken();
2060
2061 // Add this unresolved conflict.
2062 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2063}
2064
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002065/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002066///
2067/// module-declaration:
2068/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2069/// { inferred-module-member* }
2070///
2071/// inferred-module-member:
2072/// 'export' '*'
2073/// 'exclude' identifier
2074void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002075 assert(Tok.is(MMToken::Star));
2076 SourceLocation StarLoc = consumeToken();
2077 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002078
Douglas Gregor73441092011-12-05 22:27:44 +00002079 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002080 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002081 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2082 Failed = true;
2083 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002084
2085 if (ActiveModule) {
2086 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002087 if (!Failed && ActiveModule->IsAvailable &&
2088 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002089 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2090 Failed = true;
2091 }
2092
2093 // Check for redefinition of an inferred module.
2094 if (!Failed && ActiveModule->InferSubmodules) {
2095 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2096 if (ActiveModule->InferredSubmoduleLoc.isValid())
2097 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2098 diag::note_mmap_prev_definition);
2099 Failed = true;
2100 }
2101
2102 // Check for the 'framework' keyword, which is not permitted here.
2103 if (Framework) {
2104 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2105 Framework = false;
2106 }
2107 } else if (Explicit) {
2108 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2109 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002110 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002111
Douglas Gregor73441092011-12-05 22:27:44 +00002112 // If there were any problems with this inferred submodule, skip its body.
2113 if (Failed) {
2114 if (Tok.is(MMToken::LBrace)) {
2115 consumeToken();
2116 skipUntil(MMToken::RBrace);
2117 if (Tok.is(MMToken::RBrace))
2118 consumeToken();
2119 }
2120 HadError = true;
2121 return;
2122 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002123
2124 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002125 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002126 parseOptionalAttributes(Attrs);
2127
2128 if (ActiveModule) {
2129 // Note that we have an inferred submodule.
2130 ActiveModule->InferSubmodules = true;
2131 ActiveModule->InferredSubmoduleLoc = StarLoc;
2132 ActiveModule->InferExplicitSubmodules = Explicit;
2133 } else {
2134 // We'll be inferring framework modules for this directory.
2135 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002136 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002137 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002138 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002139 }
2140
Douglas Gregor73441092011-12-05 22:27:44 +00002141 // Parse the opening brace.
2142 if (!Tok.is(MMToken::LBrace)) {
2143 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2144 HadError = true;
2145 return;
2146 }
2147 SourceLocation LBraceLoc = consumeToken();
2148
2149 // Parse the body of the inferred submodule.
2150 bool Done = false;
2151 do {
2152 switch (Tok.Kind) {
2153 case MMToken::EndOfFile:
2154 case MMToken::RBrace:
2155 Done = true;
2156 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002157
2158 case MMToken::ExcludeKeyword: {
2159 if (ActiveModule) {
2160 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002161 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002162 consumeToken();
2163 break;
2164 }
2165
2166 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002167 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002168 if (!Tok.is(MMToken::Identifier)) {
2169 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2170 break;
2171 }
2172
2173 Map.InferredDirectories[Directory].ExcludedModules
2174 .push_back(Tok.getString());
2175 consumeToken();
2176 break;
2177 }
2178
2179 case MMToken::ExportKeyword:
2180 if (!ActiveModule) {
2181 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002182 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002183 consumeToken();
2184 break;
2185 }
2186
Douglas Gregor73441092011-12-05 22:27:44 +00002187 consumeToken();
2188 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002189 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002190 else
2191 Diags.Report(Tok.getLocation(),
2192 diag::err_mmap_expected_export_wildcard);
2193 consumeToken();
2194 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002195
Douglas Gregor73441092011-12-05 22:27:44 +00002196 case MMToken::ExplicitKeyword:
2197 case MMToken::ModuleKeyword:
2198 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002199 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002200 case MMToken::UmbrellaKeyword:
2201 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002202 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002203 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002204 consumeToken();
2205 break;
2206 }
2207 } while (!Done);
2208
2209 if (Tok.is(MMToken::RBrace))
2210 consumeToken();
2211 else {
2212 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2213 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2214 HadError = true;
2215 }
2216}
2217
Douglas Gregor9194a912012-11-06 19:39:40 +00002218/// \brief Parse optional attributes.
2219///
2220/// attributes:
2221/// attribute attributes
2222/// attribute
2223///
2224/// attribute:
2225/// [ identifier ]
2226///
2227/// \param Attrs Will be filled in with the parsed attributes.
2228///
2229/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002230bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002231 bool HadError = false;
2232
2233 while (Tok.is(MMToken::LSquare)) {
2234 // Consume the '['.
2235 SourceLocation LSquareLoc = consumeToken();
2236
2237 // Check whether we have an attribute name here.
2238 if (!Tok.is(MMToken::Identifier)) {
2239 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2240 skipUntil(MMToken::RSquare);
2241 if (Tok.is(MMToken::RSquare))
2242 consumeToken();
2243 HadError = true;
2244 }
2245
2246 // Decode the attribute name.
2247 AttributeKind Attribute
2248 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002249 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002250 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002251 .Case("system", AT_system)
2252 .Default(AT_unknown);
2253 switch (Attribute) {
2254 case AT_unknown:
2255 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2256 << Tok.getString();
2257 break;
2258
2259 case AT_system:
2260 Attrs.IsSystem = true;
2261 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002262
Richard Smith77944862014-03-02 05:58:18 +00002263 case AT_extern_c:
2264 Attrs.IsExternC = true;
2265 break;
2266
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002267 case AT_exhaustive:
2268 Attrs.IsExhaustive = true;
2269 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002270 }
2271 consumeToken();
2272
2273 // Consume the ']'.
2274 if (!Tok.is(MMToken::RSquare)) {
2275 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2276 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2277 skipUntil(MMToken::RSquare);
2278 HadError = true;
2279 }
2280
2281 if (Tok.is(MMToken::RSquare))
2282 consumeToken();
2283 }
2284
2285 return HadError;
2286}
2287
Douglas Gregor718292f2011-11-11 19:10:28 +00002288/// \brief Parse a module map file.
2289///
2290/// module-map-file:
2291/// module-declaration*
2292bool ModuleMapParser::parseModuleMapFile() {
2293 do {
2294 switch (Tok.Kind) {
2295 case MMToken::EndOfFile:
2296 return HadError;
2297
Douglas Gregore7ab3662011-12-07 02:23:45 +00002298 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002299 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002300 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002301 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002302 parseModuleDecl();
2303 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002304
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002305 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002306 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002307 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002308 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002309 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002310 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002311 case MMToken::HeaderKeyword:
2312 case MMToken::Identifier:
2313 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002314 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002315 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002316 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002317 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002318 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002319 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002320 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002321 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002322 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002323 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002324 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002325 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002326 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2327 HadError = true;
2328 consumeToken();
2329 break;
2330 }
2331 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002332}
2333
Richard Smith9acb99e32014-12-10 03:09:48 +00002334bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2335 const DirectoryEntry *Dir) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002336 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2337 = ParsedModuleMap.find(File);
2338 if (Known != ParsedModuleMap.end())
2339 return Known->second;
2340
Craig Topperd2d442c2014-05-17 23:10:59 +00002341 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002342 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2343 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002344 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002345 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002346 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002347
Douglas Gregor718292f2011-11-11 19:10:28 +00002348 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002349 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002350 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002351 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002352 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002353 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002354 return Result;
2355}