blob: 1f7003a2a4a70389d17b961c98f55a62a4edea12 [file] [log] [blame]
Douglas Gregor718292f2011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Richard Smith9acb99e32014-12-10 03:09:48 +000022#include "clang/Lex/HeaderSearchOptions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000023#include "clang/Lex/LexDiagnostic.h"
24#include "clang/Lex/Lexer.h"
25#include "clang/Lex/LiteralSupport.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000028#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000029#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000030#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000031#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000032#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000033#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000034#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000035#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000036#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000037using namespace clang;
38
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000039Module::ExportDecl
40ModuleMap::resolveExport(Module *Mod,
41 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000042 bool Complain) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +000043 // We may have just a wildcard.
44 if (Unresolved.Id.empty()) {
45 assert(Unresolved.Wildcard && "Invalid unresolved export");
Craig Topperd2d442c2014-05-17 23:10:59 +000046 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +000047 }
48
Douglas Gregorfb912652013-03-20 21:10:35 +000049 // Resolve the module-id.
50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
51 if (!Context)
52 return Module::ExportDecl();
53
54 return Module::ExportDecl(Context, Unresolved.Wildcard);
55}
56
57Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
58 bool Complain) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000059 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000060 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000061 if (!Context) {
62 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000063 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000064 << Id[0].first << Mod->getFullModuleName();
65
Craig Topperd2d442c2014-05-17 23:10:59 +000066 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000067 }
68
69 // Dig into the module path.
Douglas Gregorfb912652013-03-20 21:10:35 +000070 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
71 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000072 if (!Sub) {
73 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000074 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000075 << Id[I].first << Context->getFullModuleName()
76 << SourceRange(Id[0].second, Id[I-1].second);
77
Craig Topperd2d442c2014-05-17 23:10:59 +000078 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000079 }
Douglas Gregorfb912652013-03-20 21:10:35 +000080
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000081 Context = Sub;
82 }
Douglas Gregorfb912652013-03-20 21:10:35 +000083
84 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000085}
86
Daniel Jasper0761a8a2013-12-17 10:31:37 +000087ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000088 const LangOptions &LangOpts, const TargetInfo *Target,
89 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000090 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Craig Topperd2d442c2014-05-17 23:10:59 +000091 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
Richard Smith7e82e012016-02-19 22:25:36 +000092 SourceModule(nullptr), NumCreatedModules(0) {
Richard Smith0414b852015-02-14 05:32:00 +000093 MMapLangOpts.LineComment = true;
94}
Douglas Gregor718292f2011-11-11 19:10:28 +000095
96ModuleMap::~ModuleMap() {
Davide Italiano21668752016-03-08 23:58:08 +000097 for (auto &M : Modules)
98 delete M.getValue();
Douglas Gregor718292f2011-11-11 19:10:28 +000099}
100
Douglas Gregor89929282012-01-30 06:01:29 +0000101void ModuleMap::setTarget(const TargetInfo &Target) {
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
105}
106
Douglas Gregor056396a2012-10-12 21:15:50 +0000107/// \brief "Sanitize" a filename so that it can be used as an identifier.
108static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
109 SmallVectorImpl<char> &Buffer) {
110 if (Name.empty())
111 return Name;
112
Jordan Rosea7d03842013-02-08 22:30:41 +0000113 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000114 // If we don't already have something with the form of an identifier,
115 // create a buffer with the sanitized name.
116 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000117 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000118 Buffer.push_back('_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000121 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000122 Buffer.push_back(Name[I]);
123 else
124 Buffer.push_back('_');
125 }
126
127 Name = StringRef(Buffer.data(), Buffer.size());
128 }
129
130 while (llvm::StringSwitch<bool>(Name)
131#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
132#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
133#include "clang/Basic/TokenKinds.def"
134 .Default(false)) {
135 if (Name.data() != Buffer.data())
136 Buffer.append(Name.begin(), Name.end());
137 Buffer.push_back('_');
138 Name = StringRef(Buffer.data(), Buffer.size());
139 }
140
141 return Name;
142}
143
Douglas Gregor34d52742013-05-02 17:58:30 +0000144/// \brief Determine whether the given file name is the name of a builtin
145/// header, supplied by Clang to replace, override, or augment existing system
146/// headers.
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000147bool ModuleMap::isBuiltinHeader(StringRef FileName) {
Douglas Gregor34d52742013-05-02 17:58:30 +0000148 return llvm::StringSwitch<bool>(FileName)
149 .Case("float.h", true)
150 .Case("iso646.h", true)
151 .Case("limits.h", true)
152 .Case("stdalign.h", true)
153 .Case("stdarg.h", true)
Ben Langmuir3c4b1292016-03-09 23:31:34 +0000154 .Case("stdatomic.h", true)
Douglas Gregor34d52742013-05-02 17:58:30 +0000155 .Case("stdbool.h", true)
156 .Case("stddef.h", true)
157 .Case("stdint.h", true)
158 .Case("tgmath.h", true)
159 .Case("unwind.h", true)
160 .Default(false);
161}
162
Daniel Jasper92669ee2013-12-20 12:09:36 +0000163ModuleMap::HeadersMap::iterator
164ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000165 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000166 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
167 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000168 ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000169 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000170 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000171 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000172 return Known;
173}
174
Ben Langmuir44691382014-04-10 00:39:10 +0000175ModuleMap::KnownHeader
176ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
177 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000178 if (UmbrellaDirs.empty())
179 return KnownHeader();
180
Ben Langmuir44691382014-04-10 00:39:10 +0000181 const DirectoryEntry *Dir = File->getDir();
182 assert(Dir && "file in no directory");
183
184 // Note: as an egregious but useful hack we use the real path here, because
185 // frameworks moving from top-level frameworks to embedded frameworks tend
186 // to be symlinked from the top-level location to the embedded location,
187 // and we need to resolve lookups as if we had found the embedded location.
188 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
189
190 // Keep walking up the directory hierarchy, looking for a directory with
191 // an umbrella header.
192 do {
193 auto KnownDir = UmbrellaDirs.find(Dir);
194 if (KnownDir != UmbrellaDirs.end())
195 return KnownHeader(KnownDir->second, NormalHeader);
196
197 IntermediateDirs.push_back(Dir);
198
199 // Retrieve our parent path.
200 DirName = llvm::sys::path::parent_path(DirName);
201 if (DirName.empty())
202 break;
203
204 // Resolve the parent path to a directory entry.
205 Dir = SourceMgr.getFileManager().getDirectory(DirName);
206 } while (Dir);
207 return KnownHeader();
208}
209
Daniel Jasper92669ee2013-12-20 12:09:36 +0000210static bool violatesPrivateInclude(Module *RequestingModule,
211 const FileEntry *IncFileEnt,
Richard Smith4eb83932016-04-27 21:57:05 +0000212 ModuleMap::KnownHeader Header) {
Richard Smith202210b2014-10-24 20:23:01 +0000213#ifndef NDEBUG
Richard Smith4eb83932016-04-27 21:57:05 +0000214 if (Header.getRole() & ModuleMap::PrivateHeader) {
Richard Smith2708e522015-03-10 00:19:04 +0000215 // Check for consistency between the module header role
216 // as obtained from the lookup and as obtained from the module.
217 // This check is not cheap, so enable it only for debugging.
218 bool IsPrivate = false;
219 SmallVectorImpl<Module::Header> *HeaderList[] = {
Richard Smith4eb83932016-04-27 21:57:05 +0000220 &Header.getModule()->Headers[Module::HK_Private],
221 &Header.getModule()->Headers[Module::HK_PrivateTextual]};
Richard Smith2708e522015-03-10 00:19:04 +0000222 for (auto *Hs : HeaderList)
223 IsPrivate |=
224 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000225 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000226 }) != Hs->end();
Richard Smith4eb83932016-04-27 21:57:05 +0000227 assert(IsPrivate && "inconsistent headers and roles");
Richard Smith2708e522015-03-10 00:19:04 +0000228 }
Richard Smith202210b2014-10-24 20:23:01 +0000229#endif
Richard Smith4eb83932016-04-27 21:57:05 +0000230 return !Header.isAccessibleFrom(RequestingModule);
Daniel Jasper92669ee2013-12-20 12:09:36 +0000231}
232
Ben Langmuir71e1a642014-05-05 21:44:13 +0000233static Module *getTopLevelOrNull(Module *M) {
234 return M ? M->getTopLevelModule() : nullptr;
235}
236
Daniel Jasper92669ee2013-12-20 12:09:36 +0000237void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
Richard Smith8d4e90b2016-03-14 17:52:37 +0000238 bool RequestingModuleIsModuleInterface,
Daniel Jasper92669ee2013-12-20 12:09:36 +0000239 SourceLocation FilenameLoc,
240 StringRef Filename,
241 const FileEntry *File) {
242 // No errors for indirect modules. This may be a bit of a problem for modules
243 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000244 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000245 return;
246
247 if (RequestingModule)
248 resolveUses(RequestingModule, /*Complain=*/false);
249
Ben Langmuir71e1a642014-05-05 21:44:13 +0000250 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000251 Module *Private = nullptr;
252 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000253
Ben Langmuir71e1a642014-05-05 21:44:13 +0000254 HeadersMap::iterator Known = findKnownHeader(File);
255 if (Known != Headers.end()) {
256 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000257 // Remember private headers for later printing of a diagnostic.
Richard Smith4eb83932016-04-27 21:57:05 +0000258 if (violatesPrivateInclude(RequestingModule, File, Header)) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000259 Private = Header.getModule();
260 continue;
261 }
262
263 // If uses need to be specified explicitly, we are only allowed to return
264 // modules that are explicitly used by the requesting module.
265 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000266 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000267 NotUsed = Header.getModule();
268 continue;
269 }
270
271 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000272 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000273 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000274
275 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000276 }
277
278 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000279 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000280 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000281 << Filename;
282 return;
283 }
284
285 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000286 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000287 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000288 << RequestingModule->getFullModuleName() << Filename;
289 return;
290 }
291
Ben Langmuir71e1a642014-05-05 21:44:13 +0000292 if (Excluded || isHeaderInUmbrellaDirs(File))
293 return;
294
295 // At this point, only non-modular includes remain.
296
297 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000298 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000299 << RequestingModule->getFullModuleName() << Filename;
Manman Rena67e4d32016-08-26 17:16:46 +0000300 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
301 LangOpts.isCompilingModule()) {
302 // Do not diagnose when we are not compiling a module.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000303 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
304 diag::warn_non_modular_include_in_framework_module :
305 diag::warn_non_modular_include_in_module;
Manman Ren70a77382016-10-21 23:27:37 +0000306 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
307 << File->getName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000308 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000309}
310
Richard Smithec87a502015-02-13 23:50:20 +0000311static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
312 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000313 // Prefer available modules.
314 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
315 return true;
316
Richard Smithec87a502015-02-13 23:50:20 +0000317 // Prefer a public header over a private header.
318 if ((New.getRole() & ModuleMap::PrivateHeader) !=
319 (Old.getRole() & ModuleMap::PrivateHeader))
320 return !(New.getRole() & ModuleMap::PrivateHeader);
321
322 // Prefer a non-textual header over a textual header.
323 if ((New.getRole() & ModuleMap::TextualHeader) !=
324 (Old.getRole() & ModuleMap::TextualHeader))
325 return !(New.getRole() & ModuleMap::TextualHeader);
326
327 // Don't have a reason to choose between these. Just keep the first one.
328 return false;
329}
330
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000331ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
332 bool AllowTextual) {
Richard Smith306d8922014-10-22 23:50:56 +0000333 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000334 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000335 return ModuleMap::KnownHeader();
336 return R;
337 };
338
Sean Silva4881e8b2015-06-10 01:37:59 +0000339 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000340 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000341 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000342 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000343 for (KnownHeader &H : Known->second) {
Richard Smith7e82e012016-02-19 22:25:36 +0000344 // Prefer a header from the source module over all others.
345 if (H.getModule()->getTopLevelModule() == SourceModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000346 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000347 if (!Result || isBetterKnownHeader(H, Result))
348 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000349 }
Richard Smith306d8922014-10-22 23:50:56 +0000350 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000351 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000352
Richard Smith386bb072015-08-18 23:42:23 +0000353 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
354}
355
356ModuleMap::KnownHeader
357ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
358 assert(!Headers.count(File) && "already have a module for this header");
359
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000360 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000361 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
362 if (H) {
363 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000364
Ben Langmuir44691382014-04-10 00:39:10 +0000365 // Search up the module stack until we find a module with an umbrella
366 // directory.
367 Module *UmbrellaModule = Result;
368 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
369 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000370
Ben Langmuir44691382014-04-10 00:39:10 +0000371 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000372 const FileEntry *UmbrellaModuleMap =
373 getModuleMapFileForUniquing(UmbrellaModule);
374
Ben Langmuir44691382014-04-10 00:39:10 +0000375 // Infer submodules for each of the directories we found between
376 // the directory of the umbrella header and the directory where
377 // the actual header is located.
378 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000379
Ben Langmuir44691382014-04-10 00:39:10 +0000380 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
381 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000382 SmallString<32> NameBuf;
383 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000384 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000385 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
386 Explicit).first;
387 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000388 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000389
390 // Associate the module and the directory.
391 UmbrellaDirs[SkippedDirs[I-1]] = Result;
392
393 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000394 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000395 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000396 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000397 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000398
Ben Langmuir44691382014-04-10 00:39:10 +0000399 // Infer a submodule with the same name as this header file.
400 SmallString<32> NameBuf;
401 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000402 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000403 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
404 Explicit).first;
405 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000406 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000407 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000408
Ben Langmuir44691382014-04-10 00:39:10 +0000409 // If inferred submodules export everything they import, add a
410 // wildcard to the set of exports.
411 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000412 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000413 } else {
414 // Record each of the directories we stepped through as being part of
415 // the module we found, since the umbrella header covers them all.
416 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
417 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000418 }
Ben Langmuir44691382014-04-10 00:39:10 +0000419
Richard Smith386bb072015-08-18 23:42:23 +0000420 KnownHeader Header(Result, NormalHeader);
421 Headers[File].push_back(Header);
422 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000423 }
Richard Smith306d8922014-10-22 23:50:56 +0000424
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000425 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000426}
427
Richard Smith386bb072015-08-18 23:42:23 +0000428ArrayRef<ModuleMap::KnownHeader>
429ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
430 auto It = Headers.find(File);
431 if (It == Headers.end())
432 return None;
433 return It->second;
434}
435
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000436bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000437 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000438}
439
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000440bool
441ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
442 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000443 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000444 if (Known != Headers.end()) {
445 for (SmallVectorImpl<KnownHeader>::const_iterator
446 I = Known->second.begin(),
447 E = Known->second.end();
448 I != E; ++I) {
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000449
450 if (I->isAvailable() &&
451 (!RequestingModule ||
452 I->getModule()->isSubModuleOf(RequestingModule))) {
453 // When no requesting module is available, the caller is looking if a
454 // header is part a module by only looking into the module map. This is
455 // done by warn_uncovered_module_header checks; don't consider textual
456 // headers part of it in this mode, otherwise we get misleading warnings
457 // that a umbrella header is not including a textual header.
458 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
459 continue;
Daniel Jasper97da9172013-10-22 08:09:47 +0000460 return false;
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000461 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000462 }
463 return true;
464 }
Richard Smith50996ce2014-04-08 13:13:04 +0000465
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000466 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000467 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000468 StringRef DirName = Dir->getName();
469
Richard Smith50996ce2014-04-08 13:13:04 +0000470 auto IsUnavailable = [&](const Module *M) {
471 return !M->isAvailable() && (!RequestingModule ||
472 M->isSubModuleOf(RequestingModule));
473 };
474
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000475 // Keep walking up the directory hierarchy, looking for a directory with
476 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000477 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000478 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000479 = UmbrellaDirs.find(Dir);
480 if (KnownDir != UmbrellaDirs.end()) {
481 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000482 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000483 return true;
484
485 // Search up the module stack until we find a module with an umbrella
486 // directory.
487 Module *UmbrellaModule = Found;
488 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
489 UmbrellaModule = UmbrellaModule->Parent;
490
491 if (UmbrellaModule->InferSubmodules) {
492 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
493 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000494 SmallString<32> NameBuf;
495 StringRef Name = sanitizeFilenameAsIdentifier(
496 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
497 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000498 Found = lookupModuleQualified(Name, Found);
499 if (!Found)
500 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000501 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000502 return true;
503 }
504
505 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000506 SmallString<32> NameBuf;
507 StringRef Name = sanitizeFilenameAsIdentifier(
508 llvm::sys::path::stem(Header->getName()),
509 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000510 Found = lookupModuleQualified(Name, Found);
511 if (!Found)
512 return false;
513 }
514
Richard Smith50996ce2014-04-08 13:13:04 +0000515 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000516 }
517
518 SkippedDirs.push_back(Dir);
519
520 // Retrieve our parent path.
521 DirName = llvm::sys::path::parent_path(DirName);
522 if (DirName.empty())
523 break;
524
525 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000526 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000527 } while (Dir);
528
529 return false;
530}
531
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000532Module *ModuleMap::findModule(StringRef Name) const {
533 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000534 if (Known != Modules.end())
535 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000536
537 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000538}
539
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000540Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
541 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000542 for(; Context; Context = Context->Parent) {
543 if (Module *Sub = lookupModuleQualified(Name, Context))
544 return Sub;
545 }
546
547 return findModule(Name);
548}
549
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000550Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000551 if (!Context)
552 return findModule(Name);
553
Douglas Gregoreb90e832012-01-04 23:32:19 +0000554 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000555}
556
David Blaikie9ffe5a32017-01-30 05:00:26 +0000557std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
558 Module *Parent,
559 bool IsFramework,
560 bool IsExplicit) {
Douglas Gregor69021972011-11-30 17:33:56 +0000561 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000562 if (Module *Sub = lookupModuleQualified(Name, Parent))
563 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000564
565 // Create a new module with this name.
David Blaikie9ffe5a32017-01-30 05:00:26 +0000566 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
567 IsExplicit, NumCreatedModules++);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000568 if (!Parent) {
Richard Smith7e82e012016-02-19 22:25:36 +0000569 if (LangOpts.CurrentModule == Name)
570 SourceModule = Result;
Douglas Gregor69021972011-11-30 17:33:56 +0000571 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000572 }
Douglas Gregor69021972011-11-30 17:33:56 +0000573 return std::make_pair(Result, true);
574}
575
Richard Smithbbcc9f02016-08-26 00:14:38 +0000576Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
577 StringRef Name) {
578 assert(LangOpts.CurrentModule == Name && "module name mismatch");
579 assert(!Modules[Name] && "redefining existing module");
580
581 auto *Result =
582 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
583 /*IsExplicit*/ false, NumCreatedModules++);
Richard Smith145e15a2017-04-24 23:12:30 +0000584 Result->Kind = Module::ModuleInterfaceUnit;
Richard Smithbbcc9f02016-08-26 00:14:38 +0000585 Modules[Name] = SourceModule = Result;
586
587 // Mark the main source file as being within the newly-created module so that
588 // declarations and macros are properly visibility-restricted to it.
589 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
590 assert(MainFile && "no input file for module interface");
591 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
592
593 return Result;
594}
595
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000596/// \brief For a framework module, infer the framework against which we
597/// should link.
598static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
599 FileManager &FileMgr) {
600 assert(Mod->IsFramework && "Can only infer linking for framework modules");
601 assert(!Mod->isSubFramework() &&
602 "Can only infer linking for top-level frameworks");
603
604 SmallString<128> LibName;
605 LibName += FrameworkDir->getName();
606 llvm::sys::path::append(LibName, Mod->Name);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000607
608 // The library name of a framework has more than one possible extension since
609 // the introduction of the text-based dynamic library format. We need to check
610 // for both before we give up.
Benjamin Kramer8013e812016-11-15 18:56:39 +0000611 for (const char *extension : {"", ".tbd"}) {
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000612 llvm::sys::path::replace_extension(LibName, extension);
613 if (FileMgr.getFile(LibName)) {
614 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
615 /*IsFramework=*/true));
616 return;
617 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000618 }
619}
620
Ben Langmuira5254002015-07-02 13:19:48 +0000621Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
622 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000623 Attributes Attrs;
624 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000625 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000626}
627
Ben Langmuira5254002015-07-02 13:19:48 +0000628Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000629 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000630 // Note: as an egregious but useful hack we use the real path here, because
631 // we might be looking at an embedded framework that symlinks out to a
632 // top-level framework, and we need to infer as if we were naming the
633 // top-level framework.
634 StringRef FrameworkDirName =
635 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
636
637 // In case this is a case-insensitive filesystem, use the canonical
638 // directory name as the ModuleName, since modules are case-sensitive.
639 // FIXME: we should be able to give a fix-it hint for the correct spelling.
640 SmallString<32> ModuleNameStorage;
641 StringRef ModuleName = sanitizeFilenameAsIdentifier(
642 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000643
Douglas Gregor56c64012011-11-17 01:41:17 +0000644 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000645 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
646 return Mod;
647
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000648 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000649
650 // If the framework has a parent path from which we're allowed to infer
651 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000652 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000653 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000654 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000655 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000656 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000657 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000658 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000659 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
660 // Check whether we have already looked into the parent directory
661 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000662 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000663 inferred = InferredDirectories.find(ParentDir);
664 if (inferred == InferredDirectories.end()) {
665 // We haven't looked here before. Load a module map, if there is
666 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000667 bool IsFrameworkDir = Parent.endswith(".framework");
668 if (const FileEntry *ModMapFile =
669 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000670 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000671 inferred = InferredDirectories.find(ParentDir);
672 }
673
674 if (inferred == InferredDirectories.end())
675 inferred = InferredDirectories.insert(
676 std::make_pair(ParentDir, InferredDirectory())).first;
677 }
678
679 if (inferred->second.InferModules) {
680 // We're allowed to infer for this directory, but make sure it's okay
681 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000682 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000683 canInfer = std::find(inferred->second.ExcludedModules.begin(),
684 inferred->second.ExcludedModules.end(),
685 Name) == inferred->second.ExcludedModules.end();
686
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000687 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
688 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
689 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000690 Attrs.NoUndeclaredIncludes |=
691 inferred->second.Attrs.NoUndeclaredIncludes;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000692 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000693 }
694 }
695 }
696
697 // If we're not allowed to infer a framework module, don't.
698 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000699 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000700 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000701 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000702
703
Douglas Gregor56c64012011-11-17 01:41:17 +0000704 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000705 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000706 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000707 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000708
709 // FIXME: If there's no umbrella header, we could probably scan the
710 // framework to load *everything*. But, it's not clear that this is a good
711 // idea.
712 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000713 return nullptr;
714
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000715 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000716 /*IsFramework=*/true, /*IsExplicit=*/false,
717 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000718 InferredModuleAllowedBy[Result] = ModuleMapFile;
719 Result->IsInferred = true;
Richard Smith7e82e012016-02-19 22:25:36 +0000720 if (!Parent) {
721 if (LangOpts.CurrentModule == ModuleName)
722 SourceModule = Result;
723 Modules[ModuleName] = Result;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000724 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000725
726 Result->IsSystem |= Attrs.IsSystem;
727 Result->IsExternC |= Attrs.IsExternC;
728 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000729 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Richard Smith2b63d152015-05-16 02:28:53 +0000730 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000731
Douglas Gregor322f6332011-12-08 18:00:48 +0000732 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000733 //
734 // The "Headers/" component of the name is implied because this is
735 // a framework module.
736 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000737
738 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000739 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
740
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000741 // module * { export * }
742 Result->InferSubmodules = true;
743 Result->InferExportWildcard = true;
744
Douglas Gregore89dbc12011-12-06 19:39:29 +0000745 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000746 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000747 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000748 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000749 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000750 llvm::sys::path::native(SubframeworksDirName);
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000751 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
752 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
753 DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000754 Dir != DirEnd && !EC; Dir.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000755 if (!StringRef(Dir->getName()).endswith(".framework"))
Douglas Gregore89dbc12011-12-06 19:39:29 +0000756 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000757
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000758 if (const DirectoryEntry *SubframeworkDir =
759 FileMgr.getDirectory(Dir->getName())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000760 // Note: as an egregious but useful hack, we use the real path here and
761 // check whether it is actually a subdirectory of the parent directory.
762 // This will not be the case if the 'subframework' is actually a symlink
763 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000764 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
765 bool FoundParent = false;
766 do {
767 // Get the parent directory name.
768 SubframeworkDirName
769 = llvm::sys::path::parent_path(SubframeworkDirName);
770 if (SubframeworkDirName.empty())
771 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000772
Douglas Gregore00c8b22013-01-26 00:55:12 +0000773 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
774 FoundParent = true;
775 break;
776 }
777 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000778
Douglas Gregore00c8b22013-01-26 00:55:12 +0000779 if (!FoundParent)
780 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000781
Douglas Gregore89dbc12011-12-06 19:39:29 +0000782 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000783 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000784 }
785 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000786
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000787 // If the module is a top-level framework, automatically link against the
788 // framework.
789 if (!Result->isSubFramework()) {
790 inferFrameworkLink(Result, FrameworkDir, FileMgr);
791 }
792
Douglas Gregor56c64012011-11-17 01:41:17 +0000793 return Result;
794}
795
Richard Smith2b63d152015-05-16 02:28:53 +0000796void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
797 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000798 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000799 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000800 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000801 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Bruno Cardoso Lopesb3a0fa42016-05-13 22:21:51 +0000802
803 // Notify callbacks that we just added a new header.
804 for (const auto &Cb : Callbacks)
805 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000806}
807
Richard Smith2b63d152015-05-16 02:28:53 +0000808void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
809 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000810 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000811 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000812 UmbrellaDirs[UmbrellaDir] = Mod;
813}
814
Richard Smith3c1a41a2014-12-02 00:08:08 +0000815static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000816 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000817 default: llvm_unreachable("unknown header role");
818 case ModuleMap::NormalHeader:
819 return Module::HK_Normal;
820 case ModuleMap::PrivateHeader:
821 return Module::HK_Private;
822 case ModuleMap::TextualHeader:
823 return Module::HK_Textual;
824 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
825 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000826 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000827}
828
Richard Smith3c1a41a2014-12-02 00:08:08 +0000829void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000830 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000831 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000832
Richard Smith386bb072015-08-18 23:42:23 +0000833 // Only add each header to the headers list once.
834 // FIXME: Should we diagnose if a header is listed twice in the
835 // same module definition?
836 auto &HeaderList = Headers[Header.Entry];
837 for (auto H : HeaderList)
838 if (H == KH)
839 return;
840
841 HeaderList.push_back(KH);
Piotr Padlewski1ec383c2016-12-23 11:40:44 +0000842 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
Richard Smith386bb072015-08-18 23:42:23 +0000843
Richard Smith7e82e012016-02-19 22:25:36 +0000844 bool isCompilingModuleHeader =
Richard Smithbbcc9f02016-08-26 00:14:38 +0000845 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000846 if (!Imported || isCompilingModuleHeader) {
847 // When we import HeaderFileInfo, the external source is expected to
848 // set the isModuleHeader flag itself.
849 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
850 isCompilingModuleHeader);
851 }
Bruno Cardoso Lopese62cfd72016-03-30 23:54:25 +0000852
853 // Notify callbacks that we just added a new header.
854 for (const auto &Cb : Callbacks)
Bruno Cardoso Lopesf0841792016-05-06 23:21:50 +0000855 Cb->moduleMapAddHeader(Header.Entry->getName());
Richard Smith3c1a41a2014-12-02 00:08:08 +0000856}
857
858void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000859 // Add this as a known header so we won't implicitly add it to any
860 // umbrella directory module.
861 // FIXME: Should we only exclude it from umbrella modules within the
862 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000863 (void) Headers[Header.Entry];
864
865 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000866}
867
Douglas Gregor514b6362011-11-29 19:06:37 +0000868const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000869ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000870 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000871 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000872
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000873 return SourceMgr.getFileEntryForID(
874 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000875}
876
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000877const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000878 if (M->IsInferred) {
879 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
880 return InferredModuleAllowedBy.find(M)->second;
881 }
882 return getContainingModuleMapFile(M);
883}
884
885void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
886 assert(M->IsInferred && "module not inferred");
887 InferredModuleAllowedBy[M] = ModMap;
888}
889
Yaron Kerencdae9412016-01-29 19:38:18 +0000890LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +0000891 llvm::errs() << "Modules:";
892 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
893 MEnd = Modules.end();
894 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000895 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000896
897 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000898 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000899 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000900 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
901 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
902 E = H->second.end();
903 I != E; ++I) {
904 if (I != H->second.begin())
905 llvm::errs() << ",";
906 llvm::errs() << I->getModule()->getFullModuleName();
907 }
908 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000909 }
910}
911
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000912bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000913 auto Unresolved = std::move(Mod->UnresolvedExports);
914 Mod->UnresolvedExports.clear();
915 for (auto &UE : Unresolved) {
916 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000917 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000918 Mod->Exports.push_back(Export);
919 else
Richard Smith42413142015-05-15 20:05:43 +0000920 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000921 }
Richard Smith42413142015-05-15 20:05:43 +0000922 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000923}
924
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000925bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000926 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
927 Mod->UnresolvedDirectUses.clear();
928 for (auto &UDU : Unresolved) {
929 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000930 if (DirectUse)
931 Mod->DirectUses.push_back(DirectUse);
932 else
Richard Smith42413142015-05-15 20:05:43 +0000933 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000934 }
Richard Smith42413142015-05-15 20:05:43 +0000935 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000936}
937
Douglas Gregorfb912652013-03-20 21:10:35 +0000938bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000939 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000940 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000941 for (auto &UC : Unresolved) {
942 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
943 Module::Conflict Conflict;
944 Conflict.Other = OtherMod;
945 Conflict.Message = UC.Message;
946 Mod->Conflicts.push_back(Conflict);
947 } else
948 Mod->UnresolvedConflicts.push_back(UC);
949 }
950 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000951}
952
Douglas Gregor718292f2011-11-11 19:10:28 +0000953//----------------------------------------------------------------------------//
954// Module map file parser
955//----------------------------------------------------------------------------//
956
957namespace clang {
958 /// \brief A token in a module map file.
959 struct MMToken {
960 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000961 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000962 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000963 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 EndOfFile,
965 HeaderKeyword,
966 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000967 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000968 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000969 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000970 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000971 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000972 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000973 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000974 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000975 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000976 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000977 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000978 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000979 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000980 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000981 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000982 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000983 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000984 RBrace,
985 LSquare,
986 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000987 } Kind;
988
989 unsigned Location;
990 unsigned StringLength;
991 const char *StringData;
992
993 void clear() {
994 Kind = EndOfFile;
995 Location = 0;
996 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000997 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000998 }
999
1000 bool is(TokenKind K) const { return Kind == K; }
1001
1002 SourceLocation getLocation() const {
1003 return SourceLocation::getFromRawEncoding(Location);
1004 }
1005
1006 StringRef getString() const {
1007 return StringRef(StringData, StringLength);
1008 }
1009 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001010
Douglas Gregor718292f2011-11-11 19:10:28 +00001011 class ModuleMapParser {
1012 Lexer &L;
1013 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001014
1015 /// \brief Default target information, used only for string literal
1016 /// parsing.
1017 const TargetInfo *Target;
1018
Douglas Gregor718292f2011-11-11 19:10:28 +00001019 DiagnosticsEngine &Diags;
1020 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001021
1022 /// \brief The current module map file.
1023 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001024
Richard Smith9acb99e32014-12-10 03:09:48 +00001025 /// \brief The directory that file names in this module map file should
1026 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001027 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001028
1029 /// \brief The directory containing Clang-supplied headers.
1030 const DirectoryEntry *BuiltinIncludeDir;
1031
Douglas Gregor963c5532013-06-21 16:28:10 +00001032 /// \brief Whether this module map is in a system header directory.
1033 bool IsSystem;
1034
Douglas Gregor718292f2011-11-11 19:10:28 +00001035 /// \brief Whether an error occurred.
1036 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001037
Douglas Gregor718292f2011-11-11 19:10:28 +00001038 /// \brief Stores string data for the various string literals referenced
1039 /// during parsing.
1040 llvm::BumpPtrAllocator StringData;
1041
1042 /// \brief The current token.
1043 MMToken Tok;
1044
1045 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001046 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001047
1048 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1049 /// contents as 'textual'.
1050 ///
1051 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1052 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1053 /// non-modular headers. For backwards compatibility, we continue to
1054 /// support this idiom for just these modules, and map the headers to
1055 /// 'textual' to match the original intent.
1056 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1057
Douglas Gregor718292f2011-11-11 19:10:28 +00001058 /// \brief Consume the current token and return its location.
1059 SourceLocation consumeToken();
1060
1061 /// \brief Skip tokens until we reach the a token with the given kind
1062 /// (or the end of the file).
1063 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001064
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001065 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001066 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001067 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001068 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001069 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001070 void parseHeaderDecl(clang::MMToken::TokenKind,
1071 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001072 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001073 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001074 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001075 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001076 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001077 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001078 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001079
1080 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001081 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001082
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001084 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001085 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001086 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001087 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001088 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001089 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001090 const DirectoryEntry *BuiltinIncludeDir,
1091 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001092 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001093 ModuleMapFile(ModuleMapFile), Directory(Directory),
1094 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001095 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001096 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001097 Tok.clear();
1098 consumeToken();
1099 }
1100
1101 bool parseModuleMapFile();
Richard Smith8128f332017-05-05 22:18:51 +00001102
1103 bool terminatedByDirective() { return false; }
1104 SourceLocation getLocation() { return Tok.getLocation(); }
Douglas Gregor718292f2011-11-11 19:10:28 +00001105 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001106}
Douglas Gregor718292f2011-11-11 19:10:28 +00001107
1108SourceLocation ModuleMapParser::consumeToken() {
Douglas Gregor718292f2011-11-11 19:10:28 +00001109 SourceLocation Result = Tok.getLocation();
Richard Smith8128f332017-05-05 22:18:51 +00001110
1111retry:
Douglas Gregor718292f2011-11-11 19:10:28 +00001112 Tok.clear();
Douglas Gregor718292f2011-11-11 19:10:28 +00001113 Token LToken;
1114 L.LexFromRawLexer(LToken);
1115 Tok.Location = LToken.getLocation().getRawEncoding();
1116 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001117 case tok::raw_identifier: {
1118 StringRef RI = LToken.getRawIdentifier();
1119 Tok.StringData = RI.data();
1120 Tok.StringLength = RI.size();
1121 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001122 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001123 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001124 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001125 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001126 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001127 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001128 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001129 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001130 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001131 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001132 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001133 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001134 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001135 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001136 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001137 .Default(MMToken::Identifier);
1138 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001139 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001140
1141 case tok::comma:
1142 Tok.Kind = MMToken::Comma;
1143 break;
1144
Douglas Gregor718292f2011-11-11 19:10:28 +00001145 case tok::eof:
1146 Tok.Kind = MMToken::EndOfFile;
1147 break;
1148
1149 case tok::l_brace:
1150 Tok.Kind = MMToken::LBrace;
1151 break;
1152
Douglas Gregora686e1b2012-01-27 19:52:33 +00001153 case tok::l_square:
1154 Tok.Kind = MMToken::LSquare;
1155 break;
1156
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001157 case tok::period:
1158 Tok.Kind = MMToken::Period;
1159 break;
1160
Douglas Gregor718292f2011-11-11 19:10:28 +00001161 case tok::r_brace:
1162 Tok.Kind = MMToken::RBrace;
1163 break;
1164
Douglas Gregora686e1b2012-01-27 19:52:33 +00001165 case tok::r_square:
1166 Tok.Kind = MMToken::RSquare;
1167 break;
1168
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001169 case tok::star:
1170 Tok.Kind = MMToken::Star;
1171 break;
1172
Richard Smitha3feee22013-10-28 22:18:19 +00001173 case tok::exclaim:
1174 Tok.Kind = MMToken::Exclaim;
1175 break;
1176
Douglas Gregor718292f2011-11-11 19:10:28 +00001177 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001178 if (LToken.hasUDSuffix()) {
1179 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1180 HadError = true;
1181 goto retry;
1182 }
1183
Douglas Gregor718292f2011-11-11 19:10:28 +00001184 // Parse the string literal.
1185 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001186 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001187 if (StringLiteral.hadError)
1188 goto retry;
1189
1190 // Copy the string literal into our string data allocator.
1191 unsigned Length = StringLiteral.GetStringLength();
1192 char *Saved = StringData.Allocate<char>(Length + 1);
1193 memcpy(Saved, StringLiteral.GetString().data(), Length);
1194 Saved[Length] = 0;
1195
1196 // Form the token.
1197 Tok.Kind = MMToken::StringLiteral;
1198 Tok.StringData = Saved;
1199 Tok.StringLength = Length;
1200 break;
1201 }
1202
1203 case tok::comment:
1204 goto retry;
Richard Smith8128f332017-05-05 22:18:51 +00001205
1206 case tok::hash:
1207 // A module map can be terminated prematurely by
1208 // #pragma clang module contents
1209 // When building the module, we'll treat the rest of the file as the
1210 // contents of the module.
1211 {
1212 auto NextIsIdent = [&](StringRef Str) -> bool {
1213 L.LexFromRawLexer(LToken);
1214 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1215 LToken.getRawIdentifier() == Str;
1216 };
1217 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1218 NextIsIdent("module") && NextIsIdent("contents")) {
1219 Tok.Kind = MMToken::EndOfFile;
1220 break;
1221 }
1222 }
1223 LLVM_FALLTHROUGH;
1224
Douglas Gregor718292f2011-11-11 19:10:28 +00001225 default:
Richard Smith8128f332017-05-05 22:18:51 +00001226 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
Douglas Gregor718292f2011-11-11 19:10:28 +00001227 HadError = true;
1228 goto retry;
1229 }
1230
1231 return Result;
1232}
1233
1234void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1235 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001236 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 do {
1238 switch (Tok.Kind) {
1239 case MMToken::EndOfFile:
1240 return;
1241
1242 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001243 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001244 return;
1245
1246 ++braceDepth;
1247 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001248
1249 case MMToken::LSquare:
1250 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1251 return;
1252
1253 ++squareDepth;
1254 break;
1255
Douglas Gregor718292f2011-11-11 19:10:28 +00001256 case MMToken::RBrace:
1257 if (braceDepth > 0)
1258 --braceDepth;
1259 else if (Tok.is(K))
1260 return;
1261 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001262
1263 case MMToken::RSquare:
1264 if (squareDepth > 0)
1265 --squareDepth;
1266 else if (Tok.is(K))
1267 return;
1268 break;
1269
Douglas Gregor718292f2011-11-11 19:10:28 +00001270 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001271 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001272 return;
1273 break;
1274 }
1275
1276 consumeToken();
1277 } while (true);
1278}
1279
Douglas Gregore7ab3662011-12-07 02:23:45 +00001280/// \brief Parse a module-id.
1281///
1282/// module-id:
1283/// identifier
1284/// identifier '.' module-id
1285///
1286/// \returns true if an error occurred, false otherwise.
1287bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1288 Id.clear();
1289 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001290 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001291 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1292 consumeToken();
1293 } else {
1294 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1295 return true;
1296 }
1297
1298 if (!Tok.is(MMToken::Period))
1299 break;
1300
1301 consumeToken();
1302 } while (true);
1303
1304 return false;
1305}
1306
Douglas Gregora686e1b2012-01-27 19:52:33 +00001307namespace {
1308 /// \brief Enumerates the known attributes.
1309 enum AttributeKind {
1310 /// \brief An unknown attribute.
1311 AT_unknown,
1312 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001313 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001314 /// \brief The 'extern_c' attribute.
1315 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001316 /// \brief The 'exhaustive' attribute.
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001317 AT_exhaustive,
1318 /// \brief The 'no_undeclared_includes' attribute.
1319 AT_no_undeclared_includes
Douglas Gregora686e1b2012-01-27 19:52:33 +00001320 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001321}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001322
Douglas Gregor718292f2011-11-11 19:10:28 +00001323/// \brief Parse a module declaration.
1324///
1325/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001326/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001327/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1328/// { module-member* }
1329///
Douglas Gregor718292f2011-11-11 19:10:28 +00001330/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001331/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001332/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001333/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001334/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001335/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001336///
1337/// submodule-declaration:
1338/// module-declaration
1339/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001340void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001341 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001342 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1343 if (Tok.is(MMToken::ExternKeyword)) {
1344 parseExternModuleDecl();
1345 return;
1346 }
1347
Douglas Gregorf2161a72011-12-06 17:16:41 +00001348 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001349 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001350 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001351 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001352
Douglas Gregorf2161a72011-12-06 17:16:41 +00001353 // Parse 'explicit' keyword, if present.
1354 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001355 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001356 Explicit = true;
1357 }
1358
1359 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001360 if (Tok.is(MMToken::FrameworkKeyword)) {
1361 consumeToken();
1362 Framework = true;
1363 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001364
1365 // Parse 'module' keyword.
1366 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001367 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001368 consumeToken();
1369 HadError = true;
1370 return;
1371 }
1372 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001373
1374 // If we have a wildcard for the module name, this is an inferred submodule.
1375 // Parse it.
1376 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001377 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001378
1379 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001380 ModuleId Id;
1381 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001382 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001383 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001384 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001385
Douglas Gregore7ab3662011-12-07 02:23:45 +00001386 if (ActiveModule) {
1387 if (Id.size() > 1) {
1388 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1389 << SourceRange(Id.front().second, Id.back().second);
1390
1391 HadError = true;
1392 return;
1393 }
1394 } else if (Id.size() == 1 && Explicit) {
1395 // Top-level modules can't be explicit.
1396 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1397 Explicit = false;
1398 ExplicitLoc = SourceLocation();
1399 HadError = true;
1400 }
1401
1402 Module *PreviousActiveModule = ActiveModule;
1403 if (Id.size() > 1) {
1404 // This module map defines a submodule. Go find the module of which it
1405 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001406 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001407 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001408 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1409 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001410 if (I == 0)
1411 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001412 ActiveModule = Next;
1413 continue;
1414 }
1415
1416 if (ActiveModule) {
1417 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001418 << Id[I].first
1419 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001420 } else {
1421 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1422 }
1423 HadError = true;
1424 return;
1425 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001426
1427 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1428 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1429 "submodule defined in same file as 'module *' that allowed its "
1430 "top-level module");
1431 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1432 }
1433 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001434
1435 StringRef ModuleName = Id.back().first;
1436 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001437
Douglas Gregora686e1b2012-01-27 19:52:33 +00001438 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001439 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00001440 if (parseOptionalAttributes(Attrs))
1441 return;
1442
Douglas Gregora686e1b2012-01-27 19:52:33 +00001443
Douglas Gregor718292f2011-11-11 19:10:28 +00001444 // Parse the opening brace.
1445 if (!Tok.is(MMToken::LBrace)) {
1446 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1447 << ModuleName;
1448 HadError = true;
1449 return;
1450 }
1451 SourceLocation LBraceLoc = consumeToken();
1452
1453 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001454 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Richard Smith4a3751f2017-05-08 20:30:47 +00001455 // We might see a (re)definition of a module that we already have a
1456 // definition for in two cases:
1457 // - If we loaded one definition from an AST file and we've just found a
1458 // corresponding definition in a module map file, or
1459 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
1460 // - If we're building a (preprocessed) module and we've just loaded the
1461 // module map file from which it was created.
1462 bool ParsedAsMainInput =
1463 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1464 Map.LangOpts.CurrentModule == ModuleName &&
1465 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1466 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1467 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001468 // Skip the module definition.
1469 skipUntil(MMToken::RBrace);
1470 if (Tok.is(MMToken::RBrace))
1471 consumeToken();
1472 else {
1473 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1474 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1475 HadError = true;
1476 }
1477 return;
1478 }
1479
Douglas Gregor718292f2011-11-11 19:10:28 +00001480 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1481 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001482 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001483
1484 // Skip the module definition.
1485 skipUntil(MMToken::RBrace);
1486 if (Tok.is(MMToken::RBrace))
1487 consumeToken();
1488
1489 HadError = true;
1490 return;
1491 }
1492
1493 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001494 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1495 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001496 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001497 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001498 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001499 if (Attrs.IsExternC)
1500 ActiveModule->IsExternC = true;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001501 if (Attrs.NoUndeclaredIncludes ||
1502 (!ActiveModule->Parent && ModuleName == "Darwin"))
1503 ActiveModule->NoUndeclaredIncludes = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001504 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001505
Graydon Hoare4d867642016-12-21 00:24:39 +00001506 if (!ActiveModule->Parent) {
1507 StringRef MapFileName(ModuleMapFile->getName());
1508 if (MapFileName.endswith("module.private.modulemap") ||
1509 MapFileName.endswith("module_private.map")) {
1510 // Adding a top-level module from a private modulemap is likely a
1511 // user error; we check to see if there's another top-level module
1512 // defined in the non-private map in the same dir, and if so emit a
1513 // warning.
1514 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1515 auto const *M = E->getValue();
1516 if (!M->Parent &&
1517 M->Directory == ActiveModule->Directory &&
1518 M->Name != ActiveModule->Name) {
1519 Diags.Report(ActiveModule->DefinitionLoc,
1520 diag::warn_mmap_mismatched_top_level_private)
1521 << ActiveModule->Name << M->Name;
1522 // The pattern we're defending against here is typically due to
1523 // a module named FooPrivate which is supposed to be a submodule
1524 // called Foo.Private. Emit a fixit in that case.
1525 auto D =
1526 Diags.Report(ActiveModule->DefinitionLoc,
1527 diag::note_mmap_rename_top_level_private_as_submodule);
1528 D << ActiveModule->Name << M->Name;
1529 StringRef Bad(ActiveModule->Name);
1530 if (Bad.consume_back("Private")) {
1531 SmallString<128> Fixed = Bad;
1532 Fixed.append(".Private");
1533 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
1534 Fixed);
1535 }
1536 break;
1537 }
1538 }
1539 }
1540 }
1541
Douglas Gregor718292f2011-11-11 19:10:28 +00001542 bool Done = false;
1543 do {
1544 switch (Tok.Kind) {
1545 case MMToken::EndOfFile:
1546 case MMToken::RBrace:
1547 Done = true;
1548 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001549
1550 case MMToken::ConfigMacros:
1551 parseConfigMacros();
1552 break;
1553
Douglas Gregorfb912652013-03-20 21:10:35 +00001554 case MMToken::Conflict:
1555 parseConflict();
1556 break;
1557
Douglas Gregor718292f2011-11-11 19:10:28 +00001558 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001559 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001560 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001561 case MMToken::ModuleKeyword:
1562 parseModuleDecl();
1563 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001564
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001565 case MMToken::ExportKeyword:
1566 parseExportDecl();
1567 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001568
1569 case MMToken::UseKeyword:
1570 parseUseDecl();
1571 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001572
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001573 case MMToken::RequiresKeyword:
1574 parseRequiresDecl();
1575 break;
1576
Richard Smith202210b2014-10-24 20:23:01 +00001577 case MMToken::TextualKeyword:
1578 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001579 break;
Richard Smith306d8922014-10-22 23:50:56 +00001580
Douglas Gregor524e33e2011-12-08 19:11:24 +00001581 case MMToken::UmbrellaKeyword: {
1582 SourceLocation UmbrellaLoc = consumeToken();
1583 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001584 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001585 else
1586 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001587 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001588 }
Richard Smith202210b2014-10-24 20:23:01 +00001589
1590 case MMToken::ExcludeKeyword:
1591 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001592 break;
Richard Smith202210b2014-10-24 20:23:01 +00001593
1594 case MMToken::PrivateKeyword:
1595 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001596 break;
Richard Smith202210b2014-10-24 20:23:01 +00001597
Douglas Gregor322f6332011-12-08 18:00:48 +00001598 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001599 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001600 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001601
1602 case MMToken::LinkKeyword:
1603 parseLinkDecl();
1604 break;
1605
Douglas Gregor718292f2011-11-11 19:10:28 +00001606 default:
1607 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1608 consumeToken();
1609 break;
1610 }
1611 } while (!Done);
1612
1613 if (Tok.is(MMToken::RBrace))
1614 consumeToken();
1615 else {
1616 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1617 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1618 HadError = true;
1619 }
1620
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001621 // If the active module is a top-level framework, and there are no link
1622 // libraries, automatically link against the framework.
1623 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1624 ActiveModule->LinkLibraries.empty()) {
1625 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1626 }
1627
Ben Langmuirec8c9752014-04-18 22:07:31 +00001628 // If the module meets all requirements but is still unavailable, mark the
1629 // whole tree as unavailable to prevent it from building.
1630 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1631 ActiveModule->Parent) {
1632 ActiveModule->getTopLevelModule()->markUnavailable();
1633 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1634 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1635 }
1636
Douglas Gregore7ab3662011-12-07 02:23:45 +00001637 // We're done parsing this module. Pop back to the previous module.
1638 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001639}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001640
Daniel Jasper97292842013-09-11 07:20:44 +00001641/// \brief Parse an extern module declaration.
1642///
1643/// extern module-declaration:
1644/// 'extern' 'module' module-id string-literal
1645void ModuleMapParser::parseExternModuleDecl() {
1646 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001647 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001648
1649 // Parse 'module' keyword.
1650 if (!Tok.is(MMToken::ModuleKeyword)) {
1651 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1652 consumeToken();
1653 HadError = true;
1654 return;
1655 }
1656 consumeToken(); // 'module' keyword
1657
1658 // Parse the module name.
1659 ModuleId Id;
1660 if (parseModuleId(Id)) {
1661 HadError = true;
1662 return;
1663 }
1664
1665 // Parse the referenced module map file name.
1666 if (!Tok.is(MMToken::StringLiteral)) {
1667 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1668 HadError = true;
1669 return;
1670 }
1671 std::string FileName = Tok.getString();
1672 consumeToken(); // filename
1673
1674 StringRef FileNameRef = FileName;
1675 SmallString<128> ModuleMapFileName;
1676 if (llvm::sys::path::is_relative(FileNameRef)) {
1677 ModuleMapFileName += Directory->getName();
1678 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001679 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001680 }
1681 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001682 Map.parseModuleMapFile(
1683 File, /*IsSystem=*/false,
1684 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1685 ? Directory
Richard Smith8128f332017-05-05 22:18:51 +00001686 : File->getDir(),
1687 FileID(), nullptr, ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001688}
1689
Ben Langmuir7ff29142015-08-13 17:13:33 +00001690/// Whether to add the requirement \p Feature to the module \p M.
1691///
1692/// This preserves backwards compatibility for two hacks in the Darwin system
1693/// module map files:
1694///
1695/// 1. The use of 'requires excluded' to make headers non-modular, which
1696/// should really be mapped to 'textual' now that we have this feature. We
1697/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1698/// true. Later, this bit will be used to map all the headers inside this
1699/// module to 'textual'.
1700///
1701/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1702///
1703/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1704/// was never correct and causes issues now that we check it, so drop it.
1705static bool shouldAddRequirement(Module *M, StringRef Feature,
1706 bool &IsRequiresExcludedHack) {
Benjamin Kramer8013e812016-11-15 18:56:39 +00001707 if (Feature == "excluded" &&
1708 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
1709 M->fullModuleNameIs({"Tcl", "Private"}))) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00001710 IsRequiresExcludedHack = true;
1711 return false;
Benjamin Kramer8013e812016-11-15 18:56:39 +00001712 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00001713 return false;
1714 }
1715
1716 return true;
1717}
1718
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001719/// \brief Parse a requires declaration.
1720///
1721/// requires-declaration:
1722/// 'requires' feature-list
1723///
1724/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001725/// feature ',' feature-list
1726/// feature
1727///
1728/// feature:
1729/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001730void ModuleMapParser::parseRequiresDecl() {
1731 assert(Tok.is(MMToken::RequiresKeyword));
1732
1733 // Parse 'requires' keyword.
1734 consumeToken();
1735
1736 // Parse the feature-list.
1737 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001738 bool RequiredState = true;
1739 if (Tok.is(MMToken::Exclaim)) {
1740 RequiredState = false;
1741 consumeToken();
1742 }
1743
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001744 if (!Tok.is(MMToken::Identifier)) {
1745 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1746 HadError = true;
1747 return;
1748 }
1749
1750 // Consume the feature name.
1751 std::string Feature = Tok.getString();
1752 consumeToken();
1753
Ben Langmuir7ff29142015-08-13 17:13:33 +00001754 bool IsRequiresExcludedHack = false;
1755 bool ShouldAddRequirement =
1756 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1757
1758 if (IsRequiresExcludedHack)
1759 UsesRequiresExcludedHack.insert(ActiveModule);
1760
1761 if (ShouldAddRequirement) {
1762 // Add this feature.
1763 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1764 *Map.Target);
1765 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001766
1767 if (!Tok.is(MMToken::Comma))
1768 break;
1769
1770 // Consume the comma.
1771 consumeToken();
1772 } while (true);
1773}
1774
Douglas Gregorf2161a72011-12-06 17:16:41 +00001775/// \brief Append to \p Paths the set of paths needed to get to the
1776/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001777static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001778 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001779 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001780 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001781 for (; Mod; Mod = Mod->Parent) {
1782 if (Mod->IsFramework)
1783 Paths.push_back(Mod->Name);
1784 }
1785
1786 if (Paths.empty())
1787 return;
1788
1789 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001790 for (unsigned I = Paths.size() - 1; I != 0; --I)
1791 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001792}
1793
Douglas Gregor718292f2011-11-11 19:10:28 +00001794/// \brief Parse a header declaration.
1795///
1796/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001797/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001798/// 'private' 'textual'[opt] 'header' string-literal
1799/// 'exclude' 'header' string-literal
1800/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001801///
1802/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001803void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1804 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001805 // We've already consumed the first token.
1806 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1807 if (LeadingToken == MMToken::PrivateKeyword) {
1808 Role = ModuleMap::PrivateHeader;
1809 // 'private' may optionally be followed by 'textual'.
1810 if (Tok.is(MMToken::TextualKeyword)) {
1811 LeadingToken = Tok.Kind;
1812 consumeToken();
1813 }
1814 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001815
Richard Smith202210b2014-10-24 20:23:01 +00001816 if (LeadingToken == MMToken::TextualKeyword)
1817 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1818
Ben Langmuir7ff29142015-08-13 17:13:33 +00001819 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1820 // Mark this header 'textual' (see doc comment for
1821 // Module::UsesRequiresExcludedHack).
1822 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1823 }
1824
Richard Smith202210b2014-10-24 20:23:01 +00001825 if (LeadingToken != MMToken::HeaderKeyword) {
1826 if (!Tok.is(MMToken::HeaderKeyword)) {
1827 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1828 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1829 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1830 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1831 return;
1832 }
1833 consumeToken();
1834 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001835
Douglas Gregor718292f2011-11-11 19:10:28 +00001836 // Parse the header name.
1837 if (!Tok.is(MMToken::StringLiteral)) {
1838 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1839 << "header";
1840 HadError = true;
1841 return;
1842 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001843 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001844 Header.FileName = Tok.getString();
1845 Header.FileNameLoc = consumeToken();
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001846
Douglas Gregor524e33e2011-12-08 19:11:24 +00001847 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001848 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001849 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001850 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001851 HadError = true;
1852 return;
1853 }
1854
Douglas Gregor5257fc62011-11-11 21:55:48 +00001855 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001856 const FileEntry *File = nullptr;
1857 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001858 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001859 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001860 RelativePathName = Header.FileName;
1861 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001862 } else {
1863 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001864 SmallString<128> FullPathName(Directory->getName());
1865 unsigned FullPathLength = FullPathName.size();
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001866
Douglas Gregorf2161a72011-12-06 17:16:41 +00001867 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001868 appendSubframeworkPaths(ActiveModule, RelativePathName);
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001869 unsigned RelativePathLength = RelativePathName.size();
1870
Douglas Gregore7ab3662011-12-07 02:23:45 +00001871 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001872 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001873 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001874 File = SourceMgr.getFileManager().getFile(FullPathName);
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001875
1876 // Check whether this file is in the private headers.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001877 if (!File) {
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001878 // Ideally, private modules in the form 'FrameworkName.Private' should
1879 // be defined as 'module FrameworkName.Private', and not as
1880 // 'framework module FrameworkName.Private', since a 'Private.Framework'
1881 // does not usually exist. However, since both are currently widely used
1882 // for private modules, make sure we find the right path in both cases.
Bruno Cardoso Lopesd6e32892017-05-09 00:41:38 +00001883 if (ActiveModule->IsFramework && ActiveModule->Name == "Private")
1884 RelativePathName.clear();
1885 else
1886 RelativePathName.resize(RelativePathLength);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001887 FullPathName.resize(FullPathLength);
1888 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1889 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001890 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001891 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001892 }
1893 } else {
1894 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001895 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001896 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001897 File = SourceMgr.getFileManager().getFile(FullPathName);
1898
Douglas Gregor3ec66632012-02-02 18:42:48 +00001899 // If this is a system module with a top-level header, this header
1900 // may have a counterpart (or replacement) in the set of headers
1901 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001902 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1903 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +00001904 ModuleMap::isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001905 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001906 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001907 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001908
Douglas Gregor3ec66632012-02-02 18:42:48 +00001909 // If Clang supplies this header but the underlying system does not,
1910 // just silently swap in our builtin version. Otherwise, we'll end
1911 // up adding both (later).
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001912 if (BuiltinFile && !File) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001913 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001914 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001915 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001916 }
1917 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001918 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001919 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001920
Douglas Gregor5257fc62011-11-11 21:55:48 +00001921 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1922 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001923 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001924 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001925 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001926 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001927 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001928 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001929 HadError = true;
1930 } else {
1931 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001932 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001933 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001934 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001935 Module::Header H = {RelativePathName.str(), File};
1936 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001937 } else {
Richard Smith15881ed2016-10-26 01:08:55 +00001938 // If there is a builtin counterpart to this file, add it now so it can
1939 // wrap the system header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001940 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001941 // FIXME: Taking the name from the FileEntry is unstable and can give
1942 // different results depending on how we've previously named that file
1943 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001944 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
Richard Smith15881ed2016-10-26 01:08:55 +00001945 Map.addHeader(ActiveModule, H, Role);
1946
1947 // If we have both a builtin and system version of the file, the
1948 // builtin version may want to inject macros into the system header, so
1949 // force the system header to be treated as a textual header in this
1950 // case.
1951 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
Hans Wennborg0101b542014-12-02 02:13:09 +00001952 }
Richard Smith25d50752014-10-20 00:15:49 +00001953
Richard Smith202210b2014-10-24 20:23:01 +00001954 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001955 Module::Header H = { RelativePathName.str(), File };
1956 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001957 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001958 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001959 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001960
1961 // If we find a module that has a missing header, we mark this module as
1962 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001963 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001964 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001965 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001966 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001967}
1968
Ben Langmuir41f81992015-08-13 17:30:07 +00001969static int compareModuleHeaders(const Module::Header *A,
1970 const Module::Header *B) {
1971 return A->NameAsWritten.compare(B->NameAsWritten);
1972}
1973
Douglas Gregor524e33e2011-12-08 19:11:24 +00001974/// \brief Parse an umbrella directory declaration.
1975///
1976/// umbrella-dir-declaration:
1977/// umbrella string-literal
1978void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1979 // Parse the directory name.
1980 if (!Tok.is(MMToken::StringLiteral)) {
1981 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1982 << "umbrella";
1983 HadError = true;
1984 return;
1985 }
1986
1987 std::string DirName = Tok.getString();
1988 SourceLocation DirNameLoc = consumeToken();
1989
1990 // Check whether we already have an umbrella.
1991 if (ActiveModule->Umbrella) {
1992 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1993 << ActiveModule->getFullModuleName();
1994 HadError = true;
1995 return;
1996 }
1997
1998 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001999 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002000 if (llvm::sys::path::is_absolute(DirName))
2001 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2002 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00002003 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002004 PathName = Directory->getName();
2005 llvm::sys::path::append(PathName, DirName);
2006 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2007 }
2008
2009 if (!Dir) {
Vassil Vassileva0320b92017-04-18 20:57:29 +00002010 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
Douglas Gregor524e33e2011-12-08 19:11:24 +00002011 << DirName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002012 return;
2013 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00002014
2015 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2016 // Mark this header 'textual' (see doc comment for
2017 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2018 // directory is relatively expensive, in practice this only applies to the
2019 // uncommonly used Tcl module on Darwin platforms.
2020 std::error_code EC;
2021 SmallVector<Module::Header, 6> Headers;
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002022 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2023 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002024 I != E && !EC; I.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002025 if (const FileEntry *FE =
2026 SourceMgr.getFileManager().getFile(I->getName())) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00002027
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002028 Module::Header Header = {I->getName(), FE};
Ben Langmuir7ff29142015-08-13 17:13:33 +00002029 Headers.push_back(std::move(Header));
2030 }
2031 }
2032
2033 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00002034 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2035
Ben Langmuir7ff29142015-08-13 17:13:33 +00002036 for (auto &Header : Headers)
2037 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2038 return;
2039 }
2040
Douglas Gregor524e33e2011-12-08 19:11:24 +00002041 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2042 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2043 << OwningModule->getFullModuleName();
2044 HadError = true;
2045 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002046 }
2047
Douglas Gregor524e33e2011-12-08 19:11:24 +00002048 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00002049 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00002050}
2051
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002052/// \brief Parse a module export declaration.
2053///
2054/// export-declaration:
2055/// 'export' wildcard-module-id
2056///
2057/// wildcard-module-id:
2058/// identifier
2059/// '*'
2060/// identifier '.' wildcard-module-id
2061void ModuleMapParser::parseExportDecl() {
2062 assert(Tok.is(MMToken::ExportKeyword));
2063 SourceLocation ExportLoc = consumeToken();
2064
2065 // Parse the module-id with an optional wildcard at the end.
2066 ModuleId ParsedModuleId;
2067 bool Wildcard = false;
2068 do {
Richard Smith306d8922014-10-22 23:50:56 +00002069 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002070 if (Tok.is(MMToken::Identifier)) {
2071 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
2072 Tok.getLocation()));
2073 consumeToken();
2074
2075 if (Tok.is(MMToken::Period)) {
2076 consumeToken();
2077 continue;
2078 }
2079
2080 break;
2081 }
2082
2083 if(Tok.is(MMToken::Star)) {
2084 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00002085 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002086 break;
2087 }
2088
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002089 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002090 HadError = true;
2091 return;
2092 } while (true);
2093
2094 Module::UnresolvedExportDecl Unresolved = {
2095 ExportLoc, ParsedModuleId, Wildcard
2096 };
2097 ActiveModule->UnresolvedExports.push_back(Unresolved);
2098}
2099
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002100/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002101///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002102/// use-declaration:
2103/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002104void ModuleMapParser::parseUseDecl() {
2105 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002106 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002107 // Parse the module-id.
2108 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002109 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002110
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002111 if (ActiveModule->Parent)
2112 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2113 else
2114 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002115}
2116
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002117/// \brief Parse a link declaration.
2118///
2119/// module-declaration:
2120/// 'link' 'framework'[opt] string-literal
2121void ModuleMapParser::parseLinkDecl() {
2122 assert(Tok.is(MMToken::LinkKeyword));
2123 SourceLocation LinkLoc = consumeToken();
2124
2125 // Parse the optional 'framework' keyword.
2126 bool IsFramework = false;
2127 if (Tok.is(MMToken::FrameworkKeyword)) {
2128 consumeToken();
2129 IsFramework = true;
2130 }
2131
2132 // Parse the library name
2133 if (!Tok.is(MMToken::StringLiteral)) {
2134 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2135 << IsFramework << SourceRange(LinkLoc);
2136 HadError = true;
2137 return;
2138 }
2139
2140 std::string LibraryName = Tok.getString();
2141 consumeToken();
2142 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2143 IsFramework));
2144}
2145
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002146/// \brief Parse a configuration macro declaration.
2147///
2148/// module-declaration:
2149/// 'config_macros' attributes[opt] config-macro-list?
2150///
2151/// config-macro-list:
2152/// identifier (',' identifier)?
2153void ModuleMapParser::parseConfigMacros() {
2154 assert(Tok.is(MMToken::ConfigMacros));
2155 SourceLocation ConfigMacrosLoc = consumeToken();
2156
2157 // Only top-level modules can have configuration macros.
2158 if (ActiveModule->Parent) {
2159 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2160 }
2161
2162 // Parse the optional attributes.
2163 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002164 if (parseOptionalAttributes(Attrs))
2165 return;
2166
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002167 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2168 ActiveModule->ConfigMacrosExhaustive = true;
2169 }
2170
2171 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002172 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002173 if (!Tok.is(MMToken::Identifier))
2174 return;
2175
2176 // Consume the first identifier.
2177 if (!ActiveModule->Parent) {
2178 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2179 }
2180 consumeToken();
2181
2182 do {
2183 // If there's a comma, consume it.
2184 if (!Tok.is(MMToken::Comma))
2185 break;
2186 consumeToken();
2187
2188 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002189 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002190 if (!Tok.is(MMToken::Identifier)) {
2191 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2192 break;
2193 }
2194
2195 // Consume the macro name.
2196 if (!ActiveModule->Parent) {
2197 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2198 }
2199 consumeToken();
2200 } while (true);
2201}
2202
Douglas Gregorfb912652013-03-20 21:10:35 +00002203/// \brief Format a module-id into a string.
2204static std::string formatModuleId(const ModuleId &Id) {
2205 std::string result;
2206 {
2207 llvm::raw_string_ostream OS(result);
2208
2209 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2210 if (I)
2211 OS << ".";
2212 OS << Id[I].first;
2213 }
2214 }
2215
2216 return result;
2217}
2218
2219/// \brief Parse a conflict declaration.
2220///
2221/// module-declaration:
2222/// 'conflict' module-id ',' string-literal
2223void ModuleMapParser::parseConflict() {
2224 assert(Tok.is(MMToken::Conflict));
2225 SourceLocation ConflictLoc = consumeToken();
2226 Module::UnresolvedConflict Conflict;
2227
2228 // Parse the module-id.
2229 if (parseModuleId(Conflict.Id))
2230 return;
2231
2232 // Parse the ','.
2233 if (!Tok.is(MMToken::Comma)) {
2234 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2235 << SourceRange(ConflictLoc);
2236 return;
2237 }
2238 consumeToken();
2239
2240 // Parse the message.
2241 if (!Tok.is(MMToken::StringLiteral)) {
2242 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2243 << formatModuleId(Conflict.Id);
2244 return;
2245 }
2246 Conflict.Message = Tok.getString().str();
2247 consumeToken();
2248
2249 // Add this unresolved conflict.
2250 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2251}
2252
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002253/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002254///
2255/// module-declaration:
2256/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2257/// { inferred-module-member* }
2258///
2259/// inferred-module-member:
2260/// 'export' '*'
2261/// 'exclude' identifier
2262void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002263 assert(Tok.is(MMToken::Star));
2264 SourceLocation StarLoc = consumeToken();
2265 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002266
Douglas Gregor73441092011-12-05 22:27:44 +00002267 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002268 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002269 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2270 Failed = true;
2271 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002272
2273 if (ActiveModule) {
2274 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002275 if (!Failed && ActiveModule->IsAvailable &&
2276 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002277 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2278 Failed = true;
2279 }
2280
2281 // Check for redefinition of an inferred module.
2282 if (!Failed && ActiveModule->InferSubmodules) {
2283 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2284 if (ActiveModule->InferredSubmoduleLoc.isValid())
2285 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2286 diag::note_mmap_prev_definition);
2287 Failed = true;
2288 }
2289
2290 // Check for the 'framework' keyword, which is not permitted here.
2291 if (Framework) {
2292 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2293 Framework = false;
2294 }
2295 } else if (Explicit) {
2296 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2297 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002298 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002299
Douglas Gregor73441092011-12-05 22:27:44 +00002300 // If there were any problems with this inferred submodule, skip its body.
2301 if (Failed) {
2302 if (Tok.is(MMToken::LBrace)) {
2303 consumeToken();
2304 skipUntil(MMToken::RBrace);
2305 if (Tok.is(MMToken::RBrace))
2306 consumeToken();
2307 }
2308 HadError = true;
2309 return;
2310 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002311
2312 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002313 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002314 if (parseOptionalAttributes(Attrs))
2315 return;
Douglas Gregor9194a912012-11-06 19:39:40 +00002316
2317 if (ActiveModule) {
2318 // Note that we have an inferred submodule.
2319 ActiveModule->InferSubmodules = true;
2320 ActiveModule->InferredSubmoduleLoc = StarLoc;
2321 ActiveModule->InferExplicitSubmodules = Explicit;
2322 } else {
2323 // We'll be inferring framework modules for this directory.
2324 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002325 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002326 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002327 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002328 }
2329
Douglas Gregor73441092011-12-05 22:27:44 +00002330 // Parse the opening brace.
2331 if (!Tok.is(MMToken::LBrace)) {
2332 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2333 HadError = true;
2334 return;
2335 }
2336 SourceLocation LBraceLoc = consumeToken();
2337
2338 // Parse the body of the inferred submodule.
2339 bool Done = false;
2340 do {
2341 switch (Tok.Kind) {
2342 case MMToken::EndOfFile:
2343 case MMToken::RBrace:
2344 Done = true;
2345 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002346
2347 case MMToken::ExcludeKeyword: {
2348 if (ActiveModule) {
2349 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002350 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002351 consumeToken();
2352 break;
2353 }
2354
2355 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002356 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002357 if (!Tok.is(MMToken::Identifier)) {
2358 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2359 break;
2360 }
2361
2362 Map.InferredDirectories[Directory].ExcludedModules
2363 .push_back(Tok.getString());
2364 consumeToken();
2365 break;
2366 }
2367
2368 case MMToken::ExportKeyword:
2369 if (!ActiveModule) {
2370 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002371 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002372 consumeToken();
2373 break;
2374 }
2375
Douglas Gregor73441092011-12-05 22:27:44 +00002376 consumeToken();
2377 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002378 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002379 else
2380 Diags.Report(Tok.getLocation(),
2381 diag::err_mmap_expected_export_wildcard);
2382 consumeToken();
2383 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002384
Douglas Gregor73441092011-12-05 22:27:44 +00002385 case MMToken::ExplicitKeyword:
2386 case MMToken::ModuleKeyword:
2387 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002388 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002389 case MMToken::UmbrellaKeyword:
2390 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002391 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002392 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002393 consumeToken();
2394 break;
2395 }
2396 } while (!Done);
2397
2398 if (Tok.is(MMToken::RBrace))
2399 consumeToken();
2400 else {
2401 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2402 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2403 HadError = true;
2404 }
2405}
2406
Douglas Gregor9194a912012-11-06 19:39:40 +00002407/// \brief Parse optional attributes.
2408///
2409/// attributes:
2410/// attribute attributes
2411/// attribute
2412///
2413/// attribute:
2414/// [ identifier ]
2415///
2416/// \param Attrs Will be filled in with the parsed attributes.
2417///
2418/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002419bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002420 bool HadError = false;
2421
2422 while (Tok.is(MMToken::LSquare)) {
2423 // Consume the '['.
2424 SourceLocation LSquareLoc = consumeToken();
2425
2426 // Check whether we have an attribute name here.
2427 if (!Tok.is(MMToken::Identifier)) {
2428 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2429 skipUntil(MMToken::RSquare);
2430 if (Tok.is(MMToken::RSquare))
2431 consumeToken();
2432 HadError = true;
2433 }
2434
2435 // Decode the attribute name.
2436 AttributeKind Attribute
2437 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002438 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002439 .Case("extern_c", AT_extern_c)
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002440 .Case("no_undeclared_includes", AT_no_undeclared_includes)
Douglas Gregor9194a912012-11-06 19:39:40 +00002441 .Case("system", AT_system)
2442 .Default(AT_unknown);
2443 switch (Attribute) {
2444 case AT_unknown:
2445 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2446 << Tok.getString();
2447 break;
2448
2449 case AT_system:
2450 Attrs.IsSystem = true;
2451 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002452
Richard Smith77944862014-03-02 05:58:18 +00002453 case AT_extern_c:
2454 Attrs.IsExternC = true;
2455 break;
2456
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002457 case AT_exhaustive:
2458 Attrs.IsExhaustive = true;
2459 break;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002460
2461 case AT_no_undeclared_includes:
2462 Attrs.NoUndeclaredIncludes = true;
2463 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002464 }
2465 consumeToken();
2466
2467 // Consume the ']'.
2468 if (!Tok.is(MMToken::RSquare)) {
2469 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2470 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2471 skipUntil(MMToken::RSquare);
2472 HadError = true;
2473 }
2474
2475 if (Tok.is(MMToken::RSquare))
2476 consumeToken();
2477 }
2478
2479 return HadError;
2480}
2481
Douglas Gregor718292f2011-11-11 19:10:28 +00002482/// \brief Parse a module map file.
2483///
2484/// module-map-file:
2485/// module-declaration*
2486bool ModuleMapParser::parseModuleMapFile() {
2487 do {
2488 switch (Tok.Kind) {
2489 case MMToken::EndOfFile:
2490 return HadError;
2491
Douglas Gregore7ab3662011-12-07 02:23:45 +00002492 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002493 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002494 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002495 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002496 parseModuleDecl();
2497 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002498
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002499 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002500 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002501 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002502 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002503 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002504 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002505 case MMToken::HeaderKeyword:
2506 case MMToken::Identifier:
2507 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002508 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002509 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002510 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002511 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002512 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002513 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002514 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002515 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002516 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002517 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002518 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002519 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002520 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2521 HadError = true;
2522 consumeToken();
2523 break;
2524 }
2525 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002526}
2527
Richard Smith9acb99e32014-12-10 03:09:48 +00002528bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smith8128f332017-05-05 22:18:51 +00002529 const DirectoryEntry *Dir, FileID ID,
2530 unsigned *Offset,
Richard Smithae6df272015-07-14 02:06:01 +00002531 SourceLocation ExternModuleLoc) {
Richard Smith8128f332017-05-05 22:18:51 +00002532 assert(Target && "Missing target information");
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002533 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2534 = ParsedModuleMap.find(File);
2535 if (Known != ParsedModuleMap.end())
2536 return Known->second;
2537
Richard Smith8128f332017-05-05 22:18:51 +00002538 // If the module map file wasn't already entered, do so now.
2539 if (ID.isInvalid()) {
2540 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2541 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2542 }
2543
Craig Topperd2d442c2014-05-17 23:10:59 +00002544 assert(Target && "Missing target information");
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002545 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002546 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002547 return ParsedModuleMap[File] = true;
Richard Smith8128f332017-05-05 22:18:51 +00002548 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2549 "invalid buffer offset");
Ben Langmuir984e1df2014-03-19 20:23:34 +00002550
Douglas Gregor718292f2011-11-11 19:10:28 +00002551 // Parse this module map file.
Richard Smith8128f332017-05-05 22:18:51 +00002552 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2553 Buffer->getBufferStart(),
2554 Buffer->getBufferStart() + (Offset ? *Offset : 0),
2555 Buffer->getBufferEnd());
Richard Smith2a6edb32015-08-09 04:46:57 +00002556 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002557 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002558 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002559 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002560 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002561
Richard Smith8128f332017-05-05 22:18:51 +00002562 if (Offset) {
2563 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
2564 assert(Loc.first == ID && "stopped in a different file?");
2565 *Offset = Loc.second;
2566 }
2567
Richard Smith2a6edb32015-08-09 04:46:57 +00002568 // Notify callbacks that we parsed it.
2569 for (const auto &Cb : Callbacks)
2570 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002571 return Result;
2572}