blob: 8c57931e47b740efb915979e4141cb7053c2048c [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
Richard Smith1d609872017-05-26 00:01:53 +000087/// \brief Append to \p Paths the set of paths needed to get to the
88/// subframework in which the given module lives.
89static void appendSubframeworkPaths(Module *Mod,
90 SmallVectorImpl<char> &Path) {
91 // Collect the framework names from the given module to the top-level module.
92 SmallVector<StringRef, 2> Paths;
93 for (; Mod; Mod = Mod->Parent) {
94 if (Mod->IsFramework)
95 Paths.push_back(Mod->Name);
96 }
97
98 if (Paths.empty())
99 return;
100
101 // Add Frameworks/Name.framework for each subframework.
102 for (unsigned I = Paths.size() - 1; I != 0; --I)
103 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
104}
105
106const FileEntry *
107ModuleMap::resolveHeader(Module *M, Module::UnresolvedHeaderDirective Header,
108 SmallVectorImpl<char> &RelativePathName) {
109 if (llvm::sys::path::is_absolute(Header.FileName)) {
110 RelativePathName.clear();
111 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
112 return SourceMgr.getFileManager().getFile(Header.FileName);
113 }
114
115 // Search for the header file within the module's home directory.
116 auto *Directory = M->Directory;
117 SmallString<128> FullPathName(Directory->getName());
118 unsigned FullPathLength = FullPathName.size();
119
120 if (M->isPartOfFramework()) {
121 appendSubframeworkPaths(M, RelativePathName);
122 unsigned RelativePathLength = RelativePathName.size();
123
124 // Check whether this file is in the public headers.
125 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
126 llvm::sys::path::append(FullPathName, RelativePathName);
127 if (auto *File = SourceMgr.getFileManager().getFile(FullPathName))
128 return File;
129
130 // Check whether this file is in the private headers.
131 // Ideally, private modules in the form 'FrameworkName.Private' should
132 // be defined as 'module FrameworkName.Private', and not as
133 // 'framework module FrameworkName.Private', since a 'Private.Framework'
134 // does not usually exist. However, since both are currently widely used
135 // for private modules, make sure we find the right path in both cases.
136 if (M->IsFramework && M->Name == "Private")
137 RelativePathName.clear();
138 else
139 RelativePathName.resize(RelativePathLength);
140 FullPathName.resize(FullPathLength);
141 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
142 Header.FileName);
143 llvm::sys::path::append(FullPathName, RelativePathName);
144 return SourceMgr.getFileManager().getFile(FullPathName);
145 }
146
147 // Lookup for normal headers.
148 llvm::sys::path::append(RelativePathName, Header.FileName);
149 llvm::sys::path::append(FullPathName, RelativePathName);
150 return SourceMgr.getFileManager().getFile(FullPathName);
151}
152
153const FileEntry *
154ModuleMap::resolveAsBuiltinHeader(Module *M,
155 Module::UnresolvedHeaderDirective Header,
156 SmallVectorImpl<char> &BuiltinPathName) {
157 if (llvm::sys::path::is_absolute(Header.FileName) || M->isPartOfFramework() ||
158 !M->IsSystem || Header.IsUmbrella || !BuiltinIncludeDir ||
159 BuiltinIncludeDir == M->Directory || !isBuiltinHeader(Header.FileName))
160 return nullptr;
161
162 // This is a system module with a top-level header. This header
163 // may have a counterpart (or replacement) in the set of headers
164 // supplied by Clang. Find that builtin header.
165 llvm::sys::path::append(BuiltinPathName, BuiltinIncludeDir->getName(),
166 Header.FileName);
167 return SourceMgr.getFileManager().getFile(
168 StringRef(BuiltinPathName.data(), BuiltinPathName.size()));
169}
170
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000171ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000172 const LangOptions &LangOpts, const TargetInfo *Target,
173 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000174 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Craig Topperd2d442c2014-05-17 23:10:59 +0000175 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
Richard Smith7e82e012016-02-19 22:25:36 +0000176 SourceModule(nullptr), NumCreatedModules(0) {
Richard Smith0414b852015-02-14 05:32:00 +0000177 MMapLangOpts.LineComment = true;
178}
Douglas Gregor718292f2011-11-11 19:10:28 +0000179
180ModuleMap::~ModuleMap() {
Davide Italiano21668752016-03-08 23:58:08 +0000181 for (auto &M : Modules)
182 delete M.getValue();
Douglas Gregor718292f2011-11-11 19:10:28 +0000183}
184
Douglas Gregor89929282012-01-30 06:01:29 +0000185void ModuleMap::setTarget(const TargetInfo &Target) {
186 assert((!this->Target || this->Target == &Target) &&
187 "Improper target override");
188 this->Target = &Target;
189}
190
Douglas Gregor056396a2012-10-12 21:15:50 +0000191/// \brief "Sanitize" a filename so that it can be used as an identifier.
192static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
193 SmallVectorImpl<char> &Buffer) {
194 if (Name.empty())
195 return Name;
196
Jordan Rosea7d03842013-02-08 22:30:41 +0000197 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000198 // If we don't already have something with the form of an identifier,
199 // create a buffer with the sanitized name.
200 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000201 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000202 Buffer.push_back('_');
203 Buffer.reserve(Buffer.size() + Name.size());
204 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000205 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000206 Buffer.push_back(Name[I]);
207 else
208 Buffer.push_back('_');
209 }
210
211 Name = StringRef(Buffer.data(), Buffer.size());
212 }
213
214 while (llvm::StringSwitch<bool>(Name)
215#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
216#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
217#include "clang/Basic/TokenKinds.def"
218 .Default(false)) {
219 if (Name.data() != Buffer.data())
220 Buffer.append(Name.begin(), Name.end());
221 Buffer.push_back('_');
222 Name = StringRef(Buffer.data(), Buffer.size());
223 }
224
225 return Name;
226}
227
Douglas Gregor34d52742013-05-02 17:58:30 +0000228/// \brief Determine whether the given file name is the name of a builtin
229/// header, supplied by Clang to replace, override, or augment existing system
230/// headers.
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000231bool ModuleMap::isBuiltinHeader(StringRef FileName) {
Douglas Gregor34d52742013-05-02 17:58:30 +0000232 return llvm::StringSwitch<bool>(FileName)
233 .Case("float.h", true)
234 .Case("iso646.h", true)
235 .Case("limits.h", true)
236 .Case("stdalign.h", true)
237 .Case("stdarg.h", true)
Ben Langmuir3c4b1292016-03-09 23:31:34 +0000238 .Case("stdatomic.h", true)
Douglas Gregor34d52742013-05-02 17:58:30 +0000239 .Case("stdbool.h", true)
240 .Case("stddef.h", true)
241 .Case("stdint.h", true)
242 .Case("tgmath.h", true)
243 .Case("unwind.h", true)
244 .Default(false);
245}
246
Daniel Jasper92669ee2013-12-20 12:09:36 +0000247ModuleMap::HeadersMap::iterator
248ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000249 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000250 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
251 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000252 ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000253 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000254 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000255 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000256 return Known;
257}
258
Ben Langmuir44691382014-04-10 00:39:10 +0000259ModuleMap::KnownHeader
260ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
261 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000262 if (UmbrellaDirs.empty())
263 return KnownHeader();
264
Ben Langmuir44691382014-04-10 00:39:10 +0000265 const DirectoryEntry *Dir = File->getDir();
266 assert(Dir && "file in no directory");
267
268 // Note: as an egregious but useful hack we use the real path here, because
269 // frameworks moving from top-level frameworks to embedded frameworks tend
270 // to be symlinked from the top-level location to the embedded location,
271 // and we need to resolve lookups as if we had found the embedded location.
272 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
273
274 // Keep walking up the directory hierarchy, looking for a directory with
275 // an umbrella header.
276 do {
277 auto KnownDir = UmbrellaDirs.find(Dir);
278 if (KnownDir != UmbrellaDirs.end())
279 return KnownHeader(KnownDir->second, NormalHeader);
280
281 IntermediateDirs.push_back(Dir);
282
283 // Retrieve our parent path.
284 DirName = llvm::sys::path::parent_path(DirName);
285 if (DirName.empty())
286 break;
287
288 // Resolve the parent path to a directory entry.
289 Dir = SourceMgr.getFileManager().getDirectory(DirName);
290 } while (Dir);
291 return KnownHeader();
292}
293
Daniel Jasper92669ee2013-12-20 12:09:36 +0000294static bool violatesPrivateInclude(Module *RequestingModule,
295 const FileEntry *IncFileEnt,
Richard Smith4eb83932016-04-27 21:57:05 +0000296 ModuleMap::KnownHeader Header) {
Richard Smith202210b2014-10-24 20:23:01 +0000297#ifndef NDEBUG
Richard Smith4eb83932016-04-27 21:57:05 +0000298 if (Header.getRole() & ModuleMap::PrivateHeader) {
Richard Smith2708e522015-03-10 00:19:04 +0000299 // Check for consistency between the module header role
300 // as obtained from the lookup and as obtained from the module.
301 // This check is not cheap, so enable it only for debugging.
302 bool IsPrivate = false;
303 SmallVectorImpl<Module::Header> *HeaderList[] = {
Richard Smith4eb83932016-04-27 21:57:05 +0000304 &Header.getModule()->Headers[Module::HK_Private],
305 &Header.getModule()->Headers[Module::HK_PrivateTextual]};
Richard Smith2708e522015-03-10 00:19:04 +0000306 for (auto *Hs : HeaderList)
307 IsPrivate |=
308 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000309 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000310 }) != Hs->end();
Richard Smith4eb83932016-04-27 21:57:05 +0000311 assert(IsPrivate && "inconsistent headers and roles");
Richard Smith2708e522015-03-10 00:19:04 +0000312 }
Richard Smith202210b2014-10-24 20:23:01 +0000313#endif
Richard Smith4eb83932016-04-27 21:57:05 +0000314 return !Header.isAccessibleFrom(RequestingModule);
Daniel Jasper92669ee2013-12-20 12:09:36 +0000315}
316
Ben Langmuir71e1a642014-05-05 21:44:13 +0000317static Module *getTopLevelOrNull(Module *M) {
318 return M ? M->getTopLevelModule() : nullptr;
319}
320
Daniel Jasper92669ee2013-12-20 12:09:36 +0000321void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
Richard Smith8d4e90b2016-03-14 17:52:37 +0000322 bool RequestingModuleIsModuleInterface,
Daniel Jasper92669ee2013-12-20 12:09:36 +0000323 SourceLocation FilenameLoc,
324 StringRef Filename,
325 const FileEntry *File) {
326 // No errors for indirect modules. This may be a bit of a problem for modules
327 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000328 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000329 return;
330
331 if (RequestingModule)
332 resolveUses(RequestingModule, /*Complain=*/false);
333
Ben Langmuir71e1a642014-05-05 21:44:13 +0000334 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000335 Module *Private = nullptr;
336 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000337
Ben Langmuir71e1a642014-05-05 21:44:13 +0000338 HeadersMap::iterator Known = findKnownHeader(File);
339 if (Known != Headers.end()) {
340 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000341 // Remember private headers for later printing of a diagnostic.
Richard Smith4eb83932016-04-27 21:57:05 +0000342 if (violatesPrivateInclude(RequestingModule, File, Header)) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000343 Private = Header.getModule();
344 continue;
345 }
346
347 // If uses need to be specified explicitly, we are only allowed to return
348 // modules that are explicitly used by the requesting module.
349 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000350 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000351 NotUsed = Header.getModule();
352 continue;
353 }
354
355 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000356 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000357 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000358
359 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000360 }
361
362 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000363 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000364 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000365 << Filename;
366 return;
367 }
368
369 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000370 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000371 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000372 << RequestingModule->getFullModuleName() << Filename;
373 return;
374 }
375
Ben Langmuir71e1a642014-05-05 21:44:13 +0000376 if (Excluded || isHeaderInUmbrellaDirs(File))
377 return;
378
379 // At this point, only non-modular includes remain.
380
381 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000382 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000383 << RequestingModule->getFullModuleName() << Filename;
Manman Rena67e4d32016-08-26 17:16:46 +0000384 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
385 LangOpts.isCompilingModule()) {
386 // Do not diagnose when we are not compiling a module.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000387 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
388 diag::warn_non_modular_include_in_framework_module :
389 diag::warn_non_modular_include_in_module;
Manman Ren70a77382016-10-21 23:27:37 +0000390 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
391 << File->getName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000392 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000393}
394
Richard Smithec87a502015-02-13 23:50:20 +0000395static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
396 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000397 // Prefer available modules.
398 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
399 return true;
400
Richard Smithec87a502015-02-13 23:50:20 +0000401 // Prefer a public header over a private header.
402 if ((New.getRole() & ModuleMap::PrivateHeader) !=
403 (Old.getRole() & ModuleMap::PrivateHeader))
404 return !(New.getRole() & ModuleMap::PrivateHeader);
405
406 // Prefer a non-textual header over a textual header.
407 if ((New.getRole() & ModuleMap::TextualHeader) !=
408 (Old.getRole() & ModuleMap::TextualHeader))
409 return !(New.getRole() & ModuleMap::TextualHeader);
410
411 // Don't have a reason to choose between these. Just keep the first one.
412 return false;
413}
414
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000415ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
416 bool AllowTextual) {
Richard Smith306d8922014-10-22 23:50:56 +0000417 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000418 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000419 return ModuleMap::KnownHeader();
420 return R;
421 };
422
Sean Silva4881e8b2015-06-10 01:37:59 +0000423 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000424 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000425 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000426 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000427 for (KnownHeader &H : Known->second) {
Richard Smith7e82e012016-02-19 22:25:36 +0000428 // Prefer a header from the source module over all others.
429 if (H.getModule()->getTopLevelModule() == SourceModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000430 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000431 if (!Result || isBetterKnownHeader(H, Result))
432 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000433 }
Richard Smith306d8922014-10-22 23:50:56 +0000434 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000435 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000436
Richard Smith386bb072015-08-18 23:42:23 +0000437 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
438}
439
440ModuleMap::KnownHeader
441ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
442 assert(!Headers.count(File) && "already have a module for this header");
443
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000444 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000445 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
446 if (H) {
447 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000448
Ben Langmuir44691382014-04-10 00:39:10 +0000449 // Search up the module stack until we find a module with an umbrella
450 // directory.
451 Module *UmbrellaModule = Result;
452 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
453 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000454
Ben Langmuir44691382014-04-10 00:39:10 +0000455 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000456 const FileEntry *UmbrellaModuleMap =
457 getModuleMapFileForUniquing(UmbrellaModule);
458
Ben Langmuir44691382014-04-10 00:39:10 +0000459 // Infer submodules for each of the directories we found between
460 // the directory of the umbrella header and the directory where
461 // the actual header is located.
462 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000463
Ben Langmuir44691382014-04-10 00:39:10 +0000464 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
465 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000466 SmallString<32> NameBuf;
467 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000468 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000469 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
470 Explicit).first;
471 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000472 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000473
474 // Associate the module and the directory.
475 UmbrellaDirs[SkippedDirs[I-1]] = Result;
476
477 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000478 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000479 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000480 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000481 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000482
Ben Langmuir44691382014-04-10 00:39:10 +0000483 // Infer a submodule with the same name as this header file.
484 SmallString<32> NameBuf;
485 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000486 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000487 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
488 Explicit).first;
489 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000490 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000491 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000492
Ben Langmuir44691382014-04-10 00:39:10 +0000493 // If inferred submodules export everything they import, add a
494 // wildcard to the set of exports.
495 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000496 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000497 } else {
498 // Record each of the directories we stepped through as being part of
499 // the module we found, since the umbrella header covers them all.
500 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
501 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000502 }
Ben Langmuir44691382014-04-10 00:39:10 +0000503
Richard Smith386bb072015-08-18 23:42:23 +0000504 KnownHeader Header(Result, NormalHeader);
505 Headers[File].push_back(Header);
506 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000507 }
Richard Smith306d8922014-10-22 23:50:56 +0000508
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000509 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000510}
511
Richard Smith386bb072015-08-18 23:42:23 +0000512ArrayRef<ModuleMap::KnownHeader>
513ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
514 auto It = Headers.find(File);
515 if (It == Headers.end())
516 return None;
517 return It->second;
518}
519
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000520bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000521 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000522}
523
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000524bool
525ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
526 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000527 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000528 if (Known != Headers.end()) {
529 for (SmallVectorImpl<KnownHeader>::const_iterator
530 I = Known->second.begin(),
531 E = Known->second.end();
532 I != E; ++I) {
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000533
534 if (I->isAvailable() &&
535 (!RequestingModule ||
536 I->getModule()->isSubModuleOf(RequestingModule))) {
537 // When no requesting module is available, the caller is looking if a
538 // header is part a module by only looking into the module map. This is
539 // done by warn_uncovered_module_header checks; don't consider textual
540 // headers part of it in this mode, otherwise we get misleading warnings
541 // that a umbrella header is not including a textual header.
542 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
543 continue;
Daniel Jasper97da9172013-10-22 08:09:47 +0000544 return false;
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000545 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000546 }
547 return true;
548 }
Richard Smith50996ce2014-04-08 13:13:04 +0000549
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000550 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000551 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000552 StringRef DirName = Dir->getName();
553
Richard Smith50996ce2014-04-08 13:13:04 +0000554 auto IsUnavailable = [&](const Module *M) {
555 return !M->isAvailable() && (!RequestingModule ||
556 M->isSubModuleOf(RequestingModule));
557 };
558
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000559 // Keep walking up the directory hierarchy, looking for a directory with
560 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000561 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000562 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000563 = UmbrellaDirs.find(Dir);
564 if (KnownDir != UmbrellaDirs.end()) {
565 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000566 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000567 return true;
568
569 // Search up the module stack until we find a module with an umbrella
570 // directory.
571 Module *UmbrellaModule = Found;
572 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
573 UmbrellaModule = UmbrellaModule->Parent;
574
575 if (UmbrellaModule->InferSubmodules) {
576 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
577 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000578 SmallString<32> NameBuf;
579 StringRef Name = sanitizeFilenameAsIdentifier(
580 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
581 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000582 Found = lookupModuleQualified(Name, Found);
583 if (!Found)
584 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000585 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000586 return true;
587 }
588
589 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000590 SmallString<32> NameBuf;
591 StringRef Name = sanitizeFilenameAsIdentifier(
592 llvm::sys::path::stem(Header->getName()),
593 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000594 Found = lookupModuleQualified(Name, Found);
595 if (!Found)
596 return false;
597 }
598
Richard Smith50996ce2014-04-08 13:13:04 +0000599 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000600 }
601
602 SkippedDirs.push_back(Dir);
603
604 // Retrieve our parent path.
605 DirName = llvm::sys::path::parent_path(DirName);
606 if (DirName.empty())
607 break;
608
609 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000610 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000611 } while (Dir);
612
613 return false;
614}
615
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000616Module *ModuleMap::findModule(StringRef Name) const {
617 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000618 if (Known != Modules.end())
619 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000620
621 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000622}
623
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000624Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
625 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000626 for(; Context; Context = Context->Parent) {
627 if (Module *Sub = lookupModuleQualified(Name, Context))
628 return Sub;
629 }
630
631 return findModule(Name);
632}
633
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000634Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000635 if (!Context)
636 return findModule(Name);
637
Douglas Gregoreb90e832012-01-04 23:32:19 +0000638 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000639}
640
David Blaikie9ffe5a32017-01-30 05:00:26 +0000641std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
642 Module *Parent,
643 bool IsFramework,
644 bool IsExplicit) {
Douglas Gregor69021972011-11-30 17:33:56 +0000645 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000646 if (Module *Sub = lookupModuleQualified(Name, Parent))
647 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000648
649 // Create a new module with this name.
David Blaikie9ffe5a32017-01-30 05:00:26 +0000650 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
651 IsExplicit, NumCreatedModules++);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000652 if (!Parent) {
Richard Smith7e82e012016-02-19 22:25:36 +0000653 if (LangOpts.CurrentModule == Name)
654 SourceModule = Result;
Douglas Gregor69021972011-11-30 17:33:56 +0000655 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000656 }
Douglas Gregor69021972011-11-30 17:33:56 +0000657 return std::make_pair(Result, true);
658}
659
Richard Smithbbcc9f02016-08-26 00:14:38 +0000660Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
661 StringRef Name) {
662 assert(LangOpts.CurrentModule == Name && "module name mismatch");
663 assert(!Modules[Name] && "redefining existing module");
664
665 auto *Result =
666 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
667 /*IsExplicit*/ false, NumCreatedModules++);
Richard Smith145e15a2017-04-24 23:12:30 +0000668 Result->Kind = Module::ModuleInterfaceUnit;
Richard Smithbbcc9f02016-08-26 00:14:38 +0000669 Modules[Name] = SourceModule = Result;
670
671 // Mark the main source file as being within the newly-created module so that
672 // declarations and macros are properly visibility-restricted to it.
673 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
674 assert(MainFile && "no input file for module interface");
675 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
676
677 return Result;
678}
679
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000680/// \brief For a framework module, infer the framework against which we
681/// should link.
682static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
683 FileManager &FileMgr) {
684 assert(Mod->IsFramework && "Can only infer linking for framework modules");
685 assert(!Mod->isSubFramework() &&
686 "Can only infer linking for top-level frameworks");
687
688 SmallString<128> LibName;
689 LibName += FrameworkDir->getName();
690 llvm::sys::path::append(LibName, Mod->Name);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000691
692 // The library name of a framework has more than one possible extension since
693 // the introduction of the text-based dynamic library format. We need to check
694 // for both before we give up.
Benjamin Kramer8013e812016-11-15 18:56:39 +0000695 for (const char *extension : {"", ".tbd"}) {
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000696 llvm::sys::path::replace_extension(LibName, extension);
697 if (FileMgr.getFile(LibName)) {
698 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
699 /*IsFramework=*/true));
700 return;
701 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000702 }
703}
704
Ben Langmuira5254002015-07-02 13:19:48 +0000705Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
706 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000707 Attributes Attrs;
708 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000709 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000710}
711
Ben Langmuira5254002015-07-02 13:19:48 +0000712Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000713 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000714 // Note: as an egregious but useful hack we use the real path here, because
715 // we might be looking at an embedded framework that symlinks out to a
716 // top-level framework, and we need to infer as if we were naming the
717 // top-level framework.
718 StringRef FrameworkDirName =
719 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
720
721 // In case this is a case-insensitive filesystem, use the canonical
722 // directory name as the ModuleName, since modules are case-sensitive.
723 // FIXME: we should be able to give a fix-it hint for the correct spelling.
724 SmallString<32> ModuleNameStorage;
725 StringRef ModuleName = sanitizeFilenameAsIdentifier(
726 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000727
Douglas Gregor56c64012011-11-17 01:41:17 +0000728 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000729 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
730 return Mod;
731
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000732 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000733
734 // If the framework has a parent path from which we're allowed to infer
735 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000736 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000737 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000738 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000739 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000740 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000741 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000742 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000743 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
744 // Check whether we have already looked into the parent directory
745 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000746 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000747 inferred = InferredDirectories.find(ParentDir);
748 if (inferred == InferredDirectories.end()) {
749 // We haven't looked here before. Load a module map, if there is
750 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000751 bool IsFrameworkDir = Parent.endswith(".framework");
752 if (const FileEntry *ModMapFile =
753 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000754 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000755 inferred = InferredDirectories.find(ParentDir);
756 }
757
758 if (inferred == InferredDirectories.end())
759 inferred = InferredDirectories.insert(
760 std::make_pair(ParentDir, InferredDirectory())).first;
761 }
762
763 if (inferred->second.InferModules) {
764 // We're allowed to infer for this directory, but make sure it's okay
765 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000766 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000767 canInfer = std::find(inferred->second.ExcludedModules.begin(),
768 inferred->second.ExcludedModules.end(),
769 Name) == inferred->second.ExcludedModules.end();
770
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000771 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
772 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
773 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000774 Attrs.NoUndeclaredIncludes |=
775 inferred->second.Attrs.NoUndeclaredIncludes;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000776 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000777 }
778 }
779 }
780
781 // If we're not allowed to infer a framework module, don't.
782 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000783 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000784 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000785 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000786
787
Douglas Gregor56c64012011-11-17 01:41:17 +0000788 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000789 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000790 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000791 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000792
793 // FIXME: If there's no umbrella header, we could probably scan the
794 // framework to load *everything*. But, it's not clear that this is a good
795 // idea.
796 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000797 return nullptr;
798
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000799 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000800 /*IsFramework=*/true, /*IsExplicit=*/false,
801 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000802 InferredModuleAllowedBy[Result] = ModuleMapFile;
803 Result->IsInferred = true;
Richard Smith7e82e012016-02-19 22:25:36 +0000804 if (!Parent) {
805 if (LangOpts.CurrentModule == ModuleName)
806 SourceModule = Result;
807 Modules[ModuleName] = Result;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000808 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000809
810 Result->IsSystem |= Attrs.IsSystem;
811 Result->IsExternC |= Attrs.IsExternC;
812 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000813 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Richard Smith2b63d152015-05-16 02:28:53 +0000814 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000815
Douglas Gregor322f6332011-12-08 18:00:48 +0000816 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000817 //
818 // The "Headers/" component of the name is implied because this is
819 // a framework module.
820 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000821
822 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000823 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
824
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000825 // module * { export * }
826 Result->InferSubmodules = true;
827 Result->InferExportWildcard = true;
828
Douglas Gregore89dbc12011-12-06 19:39:29 +0000829 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000830 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000831 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000832 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000833 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000834 llvm::sys::path::native(SubframeworksDirName);
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000835 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
836 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
837 DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000838 Dir != DirEnd && !EC; Dir.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000839 if (!StringRef(Dir->getName()).endswith(".framework"))
Douglas Gregore89dbc12011-12-06 19:39:29 +0000840 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000841
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000842 if (const DirectoryEntry *SubframeworkDir =
843 FileMgr.getDirectory(Dir->getName())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000844 // Note: as an egregious but useful hack, we use the real path here and
845 // check whether it is actually a subdirectory of the parent directory.
846 // This will not be the case if the 'subframework' is actually a symlink
847 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000848 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
849 bool FoundParent = false;
850 do {
851 // Get the parent directory name.
852 SubframeworkDirName
853 = llvm::sys::path::parent_path(SubframeworkDirName);
854 if (SubframeworkDirName.empty())
855 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000856
Douglas Gregore00c8b22013-01-26 00:55:12 +0000857 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
858 FoundParent = true;
859 break;
860 }
861 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000862
Douglas Gregore00c8b22013-01-26 00:55:12 +0000863 if (!FoundParent)
864 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000865
Douglas Gregore89dbc12011-12-06 19:39:29 +0000866 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000867 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000868 }
869 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000870
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000871 // If the module is a top-level framework, automatically link against the
872 // framework.
873 if (!Result->isSubFramework()) {
874 inferFrameworkLink(Result, FrameworkDir, FileMgr);
875 }
876
Douglas Gregor56c64012011-11-17 01:41:17 +0000877 return Result;
878}
879
Richard Smith2b63d152015-05-16 02:28:53 +0000880void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
881 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000882 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000883 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000884 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000885 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Bruno Cardoso Lopesb3a0fa42016-05-13 22:21:51 +0000886
887 // Notify callbacks that we just added a new header.
888 for (const auto &Cb : Callbacks)
889 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000890}
891
Richard Smith2b63d152015-05-16 02:28:53 +0000892void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
893 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000894 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000895 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000896 UmbrellaDirs[UmbrellaDir] = Mod;
897}
898
Richard Smith3c1a41a2014-12-02 00:08:08 +0000899static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000900 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000901 default: llvm_unreachable("unknown header role");
902 case ModuleMap::NormalHeader:
903 return Module::HK_Normal;
904 case ModuleMap::PrivateHeader:
905 return Module::HK_Private;
906 case ModuleMap::TextualHeader:
907 return Module::HK_Textual;
908 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
909 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000910 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000911}
912
Richard Smith3c1a41a2014-12-02 00:08:08 +0000913void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000914 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000915 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000916
Richard Smith386bb072015-08-18 23:42:23 +0000917 // Only add each header to the headers list once.
918 // FIXME: Should we diagnose if a header is listed twice in the
919 // same module definition?
920 auto &HeaderList = Headers[Header.Entry];
921 for (auto H : HeaderList)
922 if (H == KH)
923 return;
924
925 HeaderList.push_back(KH);
Piotr Padlewski1ec383c2016-12-23 11:40:44 +0000926 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
Richard Smith386bb072015-08-18 23:42:23 +0000927
Richard Smith7e82e012016-02-19 22:25:36 +0000928 bool isCompilingModuleHeader =
Richard Smithbbcc9f02016-08-26 00:14:38 +0000929 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000930 if (!Imported || isCompilingModuleHeader) {
931 // When we import HeaderFileInfo, the external source is expected to
932 // set the isModuleHeader flag itself.
933 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
934 isCompilingModuleHeader);
935 }
Bruno Cardoso Lopese62cfd72016-03-30 23:54:25 +0000936
937 // Notify callbacks that we just added a new header.
938 for (const auto &Cb : Callbacks)
Bruno Cardoso Lopesf0841792016-05-06 23:21:50 +0000939 Cb->moduleMapAddHeader(Header.Entry->getName());
Richard Smith3c1a41a2014-12-02 00:08:08 +0000940}
941
942void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000943 // Add this as a known header so we won't implicitly add it to any
944 // umbrella directory module.
945 // FIXME: Should we only exclude it from umbrella modules within the
946 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000947 (void) Headers[Header.Entry];
948
949 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000950}
951
Douglas Gregor514b6362011-11-29 19:06:37 +0000952const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000953ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000954 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000955 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000956
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000957 return SourceMgr.getFileEntryForID(
958 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000959}
960
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000961const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000962 if (M->IsInferred) {
963 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
964 return InferredModuleAllowedBy.find(M)->second;
965 }
966 return getContainingModuleMapFile(M);
967}
968
969void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
970 assert(M->IsInferred && "module not inferred");
971 InferredModuleAllowedBy[M] = ModMap;
972}
973
Yaron Kerencdae9412016-01-29 19:38:18 +0000974LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +0000975 llvm::errs() << "Modules:";
976 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
977 MEnd = Modules.end();
978 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000979 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000980
981 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000982 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000983 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000984 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
985 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
986 E = H->second.end();
987 I != E; ++I) {
988 if (I != H->second.begin())
989 llvm::errs() << ",";
990 llvm::errs() << I->getModule()->getFullModuleName();
991 }
992 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000993 }
994}
995
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000996bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000997 auto Unresolved = std::move(Mod->UnresolvedExports);
998 Mod->UnresolvedExports.clear();
999 for (auto &UE : Unresolved) {
1000 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001001 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001002 Mod->Exports.push_back(Export);
1003 else
Richard Smith42413142015-05-15 20:05:43 +00001004 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001005 }
Richard Smith42413142015-05-15 20:05:43 +00001006 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001007}
1008
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001009bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001010 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
1011 Mod->UnresolvedDirectUses.clear();
1012 for (auto &UDU : Unresolved) {
1013 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001014 if (DirectUse)
1015 Mod->DirectUses.push_back(DirectUse);
1016 else
Richard Smith42413142015-05-15 20:05:43 +00001017 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001018 }
Richard Smith42413142015-05-15 20:05:43 +00001019 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001020}
1021
Douglas Gregorfb912652013-03-20 21:10:35 +00001022bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001023 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +00001024 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +00001025 for (auto &UC : Unresolved) {
1026 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1027 Module::Conflict Conflict;
1028 Conflict.Other = OtherMod;
1029 Conflict.Message = UC.Message;
1030 Mod->Conflicts.push_back(Conflict);
1031 } else
1032 Mod->UnresolvedConflicts.push_back(UC);
1033 }
1034 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +00001035}
1036
Douglas Gregor718292f2011-11-11 19:10:28 +00001037//----------------------------------------------------------------------------//
1038// Module map file parser
1039//----------------------------------------------------------------------------//
1040
1041namespace clang {
1042 /// \brief A token in a module map file.
1043 struct MMToken {
1044 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001045 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001046 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +00001047 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +00001048 EndOfFile,
1049 HeaderKeyword,
1050 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +00001051 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +00001052 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001053 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001054 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +00001055 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +00001056 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001057 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001058 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001059 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001060 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001061 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001062 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001063 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001064 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +00001065 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +00001066 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001067 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +00001068 RBrace,
1069 LSquare,
1070 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +00001071 } Kind;
1072
1073 unsigned Location;
1074 unsigned StringLength;
1075 const char *StringData;
1076
1077 void clear() {
1078 Kind = EndOfFile;
1079 Location = 0;
1080 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +00001081 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +00001082 }
1083
1084 bool is(TokenKind K) const { return Kind == K; }
1085
1086 SourceLocation getLocation() const {
1087 return SourceLocation::getFromRawEncoding(Location);
1088 }
1089
1090 StringRef getString() const {
1091 return StringRef(StringData, StringLength);
1092 }
1093 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001094
Douglas Gregor718292f2011-11-11 19:10:28 +00001095 class ModuleMapParser {
1096 Lexer &L;
1097 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001098
1099 /// \brief Default target information, used only for string literal
1100 /// parsing.
1101 const TargetInfo *Target;
1102
Douglas Gregor718292f2011-11-11 19:10:28 +00001103 DiagnosticsEngine &Diags;
1104 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001105
1106 /// \brief The current module map file.
1107 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001108
Richard Smith9acb99e32014-12-10 03:09:48 +00001109 /// \brief The directory that file names in this module map file should
1110 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001111 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001112
Douglas Gregor963c5532013-06-21 16:28:10 +00001113 /// \brief Whether this module map is in a system header directory.
1114 bool IsSystem;
1115
Douglas Gregor718292f2011-11-11 19:10:28 +00001116 /// \brief Whether an error occurred.
1117 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001118
Douglas Gregor718292f2011-11-11 19:10:28 +00001119 /// \brief Stores string data for the various string literals referenced
1120 /// during parsing.
1121 llvm::BumpPtrAllocator StringData;
1122
1123 /// \brief The current token.
1124 MMToken Tok;
1125
1126 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001127 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001128
1129 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1130 /// contents as 'textual'.
1131 ///
1132 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1133 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1134 /// non-modular headers. For backwards compatibility, we continue to
1135 /// support this idiom for just these modules, and map the headers to
1136 /// 'textual' to match the original intent.
1137 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1138
Douglas Gregor718292f2011-11-11 19:10:28 +00001139 /// \brief Consume the current token and return its location.
1140 SourceLocation consumeToken();
1141
1142 /// \brief Skip tokens until we reach the a token with the given kind
1143 /// (or the end of the file).
1144 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001145
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001146 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001147 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001148 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001149 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001150 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001151 void parseHeaderDecl(clang::MMToken::TokenKind,
1152 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001153 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001154 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001155 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001156 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001157 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001158 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001159 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001160
1161 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001162 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001163
Douglas Gregor718292f2011-11-11 19:10:28 +00001164 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001165 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001166 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001167 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001168 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001169 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001170 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001171 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001172 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001173 ModuleMapFile(ModuleMapFile), Directory(Directory),
Richard Smith1d609872017-05-26 00:01:53 +00001174 IsSystem(IsSystem), HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001175 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001176 Tok.clear();
1177 consumeToken();
1178 }
1179
1180 bool parseModuleMapFile();
Richard Smith8128f332017-05-05 22:18:51 +00001181
1182 bool terminatedByDirective() { return false; }
1183 SourceLocation getLocation() { return Tok.getLocation(); }
Douglas Gregor718292f2011-11-11 19:10:28 +00001184 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001185}
Douglas Gregor718292f2011-11-11 19:10:28 +00001186
1187SourceLocation ModuleMapParser::consumeToken() {
Douglas Gregor718292f2011-11-11 19:10:28 +00001188 SourceLocation Result = Tok.getLocation();
Richard Smith8128f332017-05-05 22:18:51 +00001189
1190retry:
Douglas Gregor718292f2011-11-11 19:10:28 +00001191 Tok.clear();
Douglas Gregor718292f2011-11-11 19:10:28 +00001192 Token LToken;
1193 L.LexFromRawLexer(LToken);
1194 Tok.Location = LToken.getLocation().getRawEncoding();
1195 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001196 case tok::raw_identifier: {
1197 StringRef RI = LToken.getRawIdentifier();
1198 Tok.StringData = RI.data();
1199 Tok.StringLength = RI.size();
1200 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001201 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001202 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001203 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001204 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001205 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001206 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001207 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001208 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001209 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001210 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001211 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001212 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001213 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001214 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001215 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001216 .Default(MMToken::Identifier);
1217 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001218 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001219
1220 case tok::comma:
1221 Tok.Kind = MMToken::Comma;
1222 break;
1223
Douglas Gregor718292f2011-11-11 19:10:28 +00001224 case tok::eof:
1225 Tok.Kind = MMToken::EndOfFile;
1226 break;
1227
1228 case tok::l_brace:
1229 Tok.Kind = MMToken::LBrace;
1230 break;
1231
Douglas Gregora686e1b2012-01-27 19:52:33 +00001232 case tok::l_square:
1233 Tok.Kind = MMToken::LSquare;
1234 break;
1235
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001236 case tok::period:
1237 Tok.Kind = MMToken::Period;
1238 break;
1239
Douglas Gregor718292f2011-11-11 19:10:28 +00001240 case tok::r_brace:
1241 Tok.Kind = MMToken::RBrace;
1242 break;
1243
Douglas Gregora686e1b2012-01-27 19:52:33 +00001244 case tok::r_square:
1245 Tok.Kind = MMToken::RSquare;
1246 break;
1247
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001248 case tok::star:
1249 Tok.Kind = MMToken::Star;
1250 break;
1251
Richard Smitha3feee22013-10-28 22:18:19 +00001252 case tok::exclaim:
1253 Tok.Kind = MMToken::Exclaim;
1254 break;
1255
Douglas Gregor718292f2011-11-11 19:10:28 +00001256 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001257 if (LToken.hasUDSuffix()) {
1258 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1259 HadError = true;
1260 goto retry;
1261 }
1262
Douglas Gregor718292f2011-11-11 19:10:28 +00001263 // Parse the string literal.
1264 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001265 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001266 if (StringLiteral.hadError)
1267 goto retry;
1268
1269 // Copy the string literal into our string data allocator.
1270 unsigned Length = StringLiteral.GetStringLength();
1271 char *Saved = StringData.Allocate<char>(Length + 1);
1272 memcpy(Saved, StringLiteral.GetString().data(), Length);
1273 Saved[Length] = 0;
1274
1275 // Form the token.
1276 Tok.Kind = MMToken::StringLiteral;
1277 Tok.StringData = Saved;
1278 Tok.StringLength = Length;
1279 break;
1280 }
1281
1282 case tok::comment:
1283 goto retry;
Richard Smith8128f332017-05-05 22:18:51 +00001284
1285 case tok::hash:
1286 // A module map can be terminated prematurely by
1287 // #pragma clang module contents
1288 // When building the module, we'll treat the rest of the file as the
1289 // contents of the module.
1290 {
1291 auto NextIsIdent = [&](StringRef Str) -> bool {
1292 L.LexFromRawLexer(LToken);
1293 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1294 LToken.getRawIdentifier() == Str;
1295 };
1296 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1297 NextIsIdent("module") && NextIsIdent("contents")) {
1298 Tok.Kind = MMToken::EndOfFile;
1299 break;
1300 }
1301 }
1302 LLVM_FALLTHROUGH;
1303
Douglas Gregor718292f2011-11-11 19:10:28 +00001304 default:
Richard Smith8128f332017-05-05 22:18:51 +00001305 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
Douglas Gregor718292f2011-11-11 19:10:28 +00001306 HadError = true;
1307 goto retry;
1308 }
1309
1310 return Result;
1311}
1312
1313void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1314 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001315 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001316 do {
1317 switch (Tok.Kind) {
1318 case MMToken::EndOfFile:
1319 return;
1320
1321 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001322 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001323 return;
1324
1325 ++braceDepth;
1326 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001327
1328 case MMToken::LSquare:
1329 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1330 return;
1331
1332 ++squareDepth;
1333 break;
1334
Douglas Gregor718292f2011-11-11 19:10:28 +00001335 case MMToken::RBrace:
1336 if (braceDepth > 0)
1337 --braceDepth;
1338 else if (Tok.is(K))
1339 return;
1340 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001341
1342 case MMToken::RSquare:
1343 if (squareDepth > 0)
1344 --squareDepth;
1345 else if (Tok.is(K))
1346 return;
1347 break;
1348
Douglas Gregor718292f2011-11-11 19:10:28 +00001349 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001350 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001351 return;
1352 break;
1353 }
1354
1355 consumeToken();
1356 } while (true);
1357}
1358
Douglas Gregore7ab3662011-12-07 02:23:45 +00001359/// \brief Parse a module-id.
1360///
1361/// module-id:
1362/// identifier
1363/// identifier '.' module-id
1364///
1365/// \returns true if an error occurred, false otherwise.
1366bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1367 Id.clear();
1368 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001369 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001370 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1371 consumeToken();
1372 } else {
1373 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1374 return true;
1375 }
1376
1377 if (!Tok.is(MMToken::Period))
1378 break;
1379
1380 consumeToken();
1381 } while (true);
1382
1383 return false;
1384}
1385
Douglas Gregora686e1b2012-01-27 19:52:33 +00001386namespace {
1387 /// \brief Enumerates the known attributes.
1388 enum AttributeKind {
1389 /// \brief An unknown attribute.
1390 AT_unknown,
1391 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001392 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001393 /// \brief The 'extern_c' attribute.
1394 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001395 /// \brief The 'exhaustive' attribute.
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001396 AT_exhaustive,
1397 /// \brief The 'no_undeclared_includes' attribute.
1398 AT_no_undeclared_includes
Douglas Gregora686e1b2012-01-27 19:52:33 +00001399 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001400}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001401
Douglas Gregor718292f2011-11-11 19:10:28 +00001402/// \brief Parse a module declaration.
1403///
1404/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001405/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001406/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1407/// { module-member* }
1408///
Douglas Gregor718292f2011-11-11 19:10:28 +00001409/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001410/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001411/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001412/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001413/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001414/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001415///
1416/// submodule-declaration:
1417/// module-declaration
1418/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001419void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001420 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001421 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1422 if (Tok.is(MMToken::ExternKeyword)) {
1423 parseExternModuleDecl();
1424 return;
1425 }
1426
Douglas Gregorf2161a72011-12-06 17:16:41 +00001427 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001428 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001429 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001430 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001431
Douglas Gregorf2161a72011-12-06 17:16:41 +00001432 // Parse 'explicit' keyword, if present.
1433 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001434 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001435 Explicit = true;
1436 }
1437
1438 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001439 if (Tok.is(MMToken::FrameworkKeyword)) {
1440 consumeToken();
1441 Framework = true;
1442 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001443
1444 // Parse 'module' keyword.
1445 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001446 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001447 consumeToken();
1448 HadError = true;
1449 return;
1450 }
1451 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001452
1453 // If we have a wildcard for the module name, this is an inferred submodule.
1454 // Parse it.
1455 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001456 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001457
1458 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001459 ModuleId Id;
1460 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001461 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001462 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001463 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001464
Douglas Gregore7ab3662011-12-07 02:23:45 +00001465 if (ActiveModule) {
1466 if (Id.size() > 1) {
1467 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1468 << SourceRange(Id.front().second, Id.back().second);
1469
1470 HadError = true;
1471 return;
1472 }
1473 } else if (Id.size() == 1 && Explicit) {
1474 // Top-level modules can't be explicit.
1475 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1476 Explicit = false;
1477 ExplicitLoc = SourceLocation();
1478 HadError = true;
1479 }
1480
1481 Module *PreviousActiveModule = ActiveModule;
1482 if (Id.size() > 1) {
1483 // This module map defines a submodule. Go find the module of which it
1484 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001485 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001486 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001487 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1488 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001489 if (I == 0)
1490 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001491 ActiveModule = Next;
1492 continue;
1493 }
1494
1495 if (ActiveModule) {
1496 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001497 << Id[I].first
1498 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001499 } else {
1500 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1501 }
1502 HadError = true;
1503 return;
1504 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001505
1506 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1507 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1508 "submodule defined in same file as 'module *' that allowed its "
1509 "top-level module");
1510 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1511 }
1512 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001513
1514 StringRef ModuleName = Id.back().first;
1515 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001516
Douglas Gregora686e1b2012-01-27 19:52:33 +00001517 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001518 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00001519 if (parseOptionalAttributes(Attrs))
1520 return;
1521
Douglas Gregora686e1b2012-01-27 19:52:33 +00001522
Douglas Gregor718292f2011-11-11 19:10:28 +00001523 // Parse the opening brace.
1524 if (!Tok.is(MMToken::LBrace)) {
1525 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1526 << ModuleName;
1527 HadError = true;
1528 return;
1529 }
1530 SourceLocation LBraceLoc = consumeToken();
1531
1532 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001533 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Richard Smith4a3751f2017-05-08 20:30:47 +00001534 // We might see a (re)definition of a module that we already have a
1535 // definition for in two cases:
1536 // - If we loaded one definition from an AST file and we've just found a
1537 // corresponding definition in a module map file, or
1538 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
1539 // - If we're building a (preprocessed) module and we've just loaded the
1540 // module map file from which it was created.
1541 bool ParsedAsMainInput =
1542 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1543 Map.LangOpts.CurrentModule == ModuleName &&
1544 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1545 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1546 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001547 // Skip the module definition.
1548 skipUntil(MMToken::RBrace);
1549 if (Tok.is(MMToken::RBrace))
1550 consumeToken();
1551 else {
1552 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1553 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1554 HadError = true;
1555 }
1556 return;
1557 }
1558
Douglas Gregor718292f2011-11-11 19:10:28 +00001559 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1560 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001561 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001562
1563 // Skip the module definition.
1564 skipUntil(MMToken::RBrace);
1565 if (Tok.is(MMToken::RBrace))
1566 consumeToken();
1567
1568 HadError = true;
1569 return;
1570 }
1571
1572 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001573 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1574 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001575 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001576 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001577 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001578 if (Attrs.IsExternC)
1579 ActiveModule->IsExternC = true;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001580 if (Attrs.NoUndeclaredIncludes ||
1581 (!ActiveModule->Parent && ModuleName == "Darwin"))
1582 ActiveModule->NoUndeclaredIncludes = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001583 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001584
Graydon Hoare4d867642016-12-21 00:24:39 +00001585 if (!ActiveModule->Parent) {
1586 StringRef MapFileName(ModuleMapFile->getName());
1587 if (MapFileName.endswith("module.private.modulemap") ||
1588 MapFileName.endswith("module_private.map")) {
1589 // Adding a top-level module from a private modulemap is likely a
1590 // user error; we check to see if there's another top-level module
1591 // defined in the non-private map in the same dir, and if so emit a
1592 // warning.
1593 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1594 auto const *M = E->getValue();
1595 if (!M->Parent &&
1596 M->Directory == ActiveModule->Directory &&
1597 M->Name != ActiveModule->Name) {
1598 Diags.Report(ActiveModule->DefinitionLoc,
1599 diag::warn_mmap_mismatched_top_level_private)
1600 << ActiveModule->Name << M->Name;
1601 // The pattern we're defending against here is typically due to
1602 // a module named FooPrivate which is supposed to be a submodule
1603 // called Foo.Private. Emit a fixit in that case.
1604 auto D =
1605 Diags.Report(ActiveModule->DefinitionLoc,
1606 diag::note_mmap_rename_top_level_private_as_submodule);
1607 D << ActiveModule->Name << M->Name;
1608 StringRef Bad(ActiveModule->Name);
1609 if (Bad.consume_back("Private")) {
1610 SmallString<128> Fixed = Bad;
1611 Fixed.append(".Private");
1612 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
1613 Fixed);
1614 }
1615 break;
1616 }
1617 }
1618 }
1619 }
1620
Douglas Gregor718292f2011-11-11 19:10:28 +00001621 bool Done = false;
1622 do {
1623 switch (Tok.Kind) {
1624 case MMToken::EndOfFile:
1625 case MMToken::RBrace:
1626 Done = true;
1627 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001628
1629 case MMToken::ConfigMacros:
1630 parseConfigMacros();
1631 break;
1632
Douglas Gregorfb912652013-03-20 21:10:35 +00001633 case MMToken::Conflict:
1634 parseConflict();
1635 break;
1636
Douglas Gregor718292f2011-11-11 19:10:28 +00001637 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001638 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001639 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001640 case MMToken::ModuleKeyword:
1641 parseModuleDecl();
1642 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001643
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001644 case MMToken::ExportKeyword:
1645 parseExportDecl();
1646 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001647
1648 case MMToken::UseKeyword:
1649 parseUseDecl();
1650 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001651
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001652 case MMToken::RequiresKeyword:
1653 parseRequiresDecl();
1654 break;
1655
Richard Smith202210b2014-10-24 20:23:01 +00001656 case MMToken::TextualKeyword:
1657 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001658 break;
Richard Smith306d8922014-10-22 23:50:56 +00001659
Douglas Gregor524e33e2011-12-08 19:11:24 +00001660 case MMToken::UmbrellaKeyword: {
1661 SourceLocation UmbrellaLoc = consumeToken();
1662 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001663 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001664 else
1665 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001666 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001667 }
Richard Smith202210b2014-10-24 20:23:01 +00001668
1669 case MMToken::ExcludeKeyword:
1670 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001671 break;
Richard Smith202210b2014-10-24 20:23:01 +00001672
1673 case MMToken::PrivateKeyword:
1674 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001675 break;
Richard Smith202210b2014-10-24 20:23:01 +00001676
Douglas Gregor322f6332011-12-08 18:00:48 +00001677 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001678 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001679 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001680
1681 case MMToken::LinkKeyword:
1682 parseLinkDecl();
1683 break;
1684
Douglas Gregor718292f2011-11-11 19:10:28 +00001685 default:
1686 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1687 consumeToken();
1688 break;
1689 }
1690 } while (!Done);
1691
1692 if (Tok.is(MMToken::RBrace))
1693 consumeToken();
1694 else {
1695 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1696 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1697 HadError = true;
1698 }
1699
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001700 // If the active module is a top-level framework, and there are no link
1701 // libraries, automatically link against the framework.
1702 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1703 ActiveModule->LinkLibraries.empty()) {
1704 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1705 }
1706
Ben Langmuirec8c9752014-04-18 22:07:31 +00001707 // If the module meets all requirements but is still unavailable, mark the
1708 // whole tree as unavailable to prevent it from building.
1709 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1710 ActiveModule->Parent) {
1711 ActiveModule->getTopLevelModule()->markUnavailable();
1712 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1713 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1714 }
1715
Douglas Gregore7ab3662011-12-07 02:23:45 +00001716 // We're done parsing this module. Pop back to the previous module.
1717 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001718}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001719
Daniel Jasper97292842013-09-11 07:20:44 +00001720/// \brief Parse an extern module declaration.
1721///
1722/// extern module-declaration:
1723/// 'extern' 'module' module-id string-literal
1724void ModuleMapParser::parseExternModuleDecl() {
1725 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001726 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001727
1728 // Parse 'module' keyword.
1729 if (!Tok.is(MMToken::ModuleKeyword)) {
1730 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1731 consumeToken();
1732 HadError = true;
1733 return;
1734 }
1735 consumeToken(); // 'module' keyword
1736
1737 // Parse the module name.
1738 ModuleId Id;
1739 if (parseModuleId(Id)) {
1740 HadError = true;
1741 return;
1742 }
1743
1744 // Parse the referenced module map file name.
1745 if (!Tok.is(MMToken::StringLiteral)) {
1746 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1747 HadError = true;
1748 return;
1749 }
1750 std::string FileName = Tok.getString();
1751 consumeToken(); // filename
1752
1753 StringRef FileNameRef = FileName;
1754 SmallString<128> ModuleMapFileName;
1755 if (llvm::sys::path::is_relative(FileNameRef)) {
1756 ModuleMapFileName += Directory->getName();
1757 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001758 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001759 }
1760 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001761 Map.parseModuleMapFile(
1762 File, /*IsSystem=*/false,
1763 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1764 ? Directory
Richard Smith8128f332017-05-05 22:18:51 +00001765 : File->getDir(),
1766 FileID(), nullptr, ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001767}
1768
Ben Langmuir7ff29142015-08-13 17:13:33 +00001769/// Whether to add the requirement \p Feature to the module \p M.
1770///
1771/// This preserves backwards compatibility for two hacks in the Darwin system
1772/// module map files:
1773///
1774/// 1. The use of 'requires excluded' to make headers non-modular, which
1775/// should really be mapped to 'textual' now that we have this feature. We
1776/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1777/// true. Later, this bit will be used to map all the headers inside this
1778/// module to 'textual'.
1779///
1780/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1781///
1782/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1783/// was never correct and causes issues now that we check it, so drop it.
1784static bool shouldAddRequirement(Module *M, StringRef Feature,
1785 bool &IsRequiresExcludedHack) {
Benjamin Kramer8013e812016-11-15 18:56:39 +00001786 if (Feature == "excluded" &&
1787 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
1788 M->fullModuleNameIs({"Tcl", "Private"}))) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00001789 IsRequiresExcludedHack = true;
1790 return false;
Benjamin Kramer8013e812016-11-15 18:56:39 +00001791 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00001792 return false;
1793 }
1794
1795 return true;
1796}
1797
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001798/// \brief Parse a requires declaration.
1799///
1800/// requires-declaration:
1801/// 'requires' feature-list
1802///
1803/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001804/// feature ',' feature-list
1805/// feature
1806///
1807/// feature:
1808/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001809void ModuleMapParser::parseRequiresDecl() {
1810 assert(Tok.is(MMToken::RequiresKeyword));
1811
1812 // Parse 'requires' keyword.
1813 consumeToken();
1814
1815 // Parse the feature-list.
1816 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001817 bool RequiredState = true;
1818 if (Tok.is(MMToken::Exclaim)) {
1819 RequiredState = false;
1820 consumeToken();
1821 }
1822
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001823 if (!Tok.is(MMToken::Identifier)) {
1824 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1825 HadError = true;
1826 return;
1827 }
1828
1829 // Consume the feature name.
1830 std::string Feature = Tok.getString();
1831 consumeToken();
1832
Ben Langmuir7ff29142015-08-13 17:13:33 +00001833 bool IsRequiresExcludedHack = false;
1834 bool ShouldAddRequirement =
1835 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1836
1837 if (IsRequiresExcludedHack)
1838 UsesRequiresExcludedHack.insert(ActiveModule);
1839
1840 if (ShouldAddRequirement) {
1841 // Add this feature.
1842 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1843 *Map.Target);
1844 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001845
1846 if (!Tok.is(MMToken::Comma))
1847 break;
1848
1849 // Consume the comma.
1850 consumeToken();
1851 } while (true);
1852}
1853
Douglas Gregor718292f2011-11-11 19:10:28 +00001854/// \brief Parse a header declaration.
1855///
1856/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001857/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001858/// 'private' 'textual'[opt] 'header' string-literal
1859/// 'exclude' 'header' string-literal
1860/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001861///
1862/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001863void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1864 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001865 // We've already consumed the first token.
1866 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1867 if (LeadingToken == MMToken::PrivateKeyword) {
1868 Role = ModuleMap::PrivateHeader;
1869 // 'private' may optionally be followed by 'textual'.
1870 if (Tok.is(MMToken::TextualKeyword)) {
1871 LeadingToken = Tok.Kind;
1872 consumeToken();
1873 }
1874 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001875
Richard Smith202210b2014-10-24 20:23:01 +00001876 if (LeadingToken == MMToken::TextualKeyword)
1877 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1878
Ben Langmuir7ff29142015-08-13 17:13:33 +00001879 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1880 // Mark this header 'textual' (see doc comment for
1881 // Module::UsesRequiresExcludedHack).
1882 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1883 }
1884
Richard Smith202210b2014-10-24 20:23:01 +00001885 if (LeadingToken != MMToken::HeaderKeyword) {
1886 if (!Tok.is(MMToken::HeaderKeyword)) {
1887 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1888 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1889 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1890 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1891 return;
1892 }
1893 consumeToken();
1894 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001895
Douglas Gregor718292f2011-11-11 19:10:28 +00001896 // Parse the header name.
1897 if (!Tok.is(MMToken::StringLiteral)) {
1898 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1899 << "header";
1900 HadError = true;
1901 return;
1902 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001903 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001904 Header.FileName = Tok.getString();
1905 Header.FileNameLoc = consumeToken();
Richard Smith1d609872017-05-26 00:01:53 +00001906 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001907
Douglas Gregor524e33e2011-12-08 19:11:24 +00001908 // Check whether we already have an umbrella.
Richard Smith1d609872017-05-26 00:01:53 +00001909 if (Header.IsUmbrella && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001910 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001911 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001912 HadError = true;
1913 return;
1914 }
1915
Richard Smith1d609872017-05-26 00:01:53 +00001916 // Look for this file by name if we don't have any stat information.
1917 SmallString<128> RelativePathName, BuiltinPathName;
1918 const FileEntry *File =
1919 Map.resolveHeader(ActiveModule, Header, RelativePathName);
1920 const FileEntry *BuiltinFile =
1921 Map.resolveAsBuiltinHeader(ActiveModule, Header, BuiltinPathName);
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00001922
Richard Smith1d609872017-05-26 00:01:53 +00001923 // If Clang supplies this header but the underlying system does not,
1924 // just silently swap in our builtin version. Otherwise, we'll end
1925 // up adding both (later).
1926 if (BuiltinFile && !File) {
1927 RelativePathName = BuiltinPathName;
1928 File = BuiltinFile;
1929 BuiltinFile = nullptr;
Douglas Gregorf545f672011-11-29 21:59:16 +00001930 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001931
Douglas Gregor5257fc62011-11-11 21:55:48 +00001932 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1933 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001934 if (File) {
Richard Smith1d609872017-05-26 00:01:53 +00001935 if (Header.IsUmbrella) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001936 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001937 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001938 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001939 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001940 HadError = true;
1941 } else {
1942 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001943 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001944 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001945 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001946 Module::Header H = {RelativePathName.str(), File};
1947 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001948 } else {
Richard Smith15881ed2016-10-26 01:08:55 +00001949 // If there is a builtin counterpart to this file, add it now so it can
1950 // wrap the system header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001951 if (BuiltinFile) {
Richard Smith1d609872017-05-26 00:01:53 +00001952 Module::Header H = { BuiltinPathName.str(), BuiltinFile };
Richard Smith15881ed2016-10-26 01:08:55 +00001953 Map.addHeader(ActiveModule, H, Role);
1954
1955 // If we have both a builtin and system version of the file, the
1956 // builtin version may want to inject macros into the system header, so
1957 // force the system header to be treated as a textual header in this
1958 // case.
1959 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
Hans Wennborg0101b542014-12-02 02:13:09 +00001960 }
Richard Smith25d50752014-10-20 00:15:49 +00001961
Richard Smith202210b2014-10-24 20:23:01 +00001962 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001963 Module::Header H = { RelativePathName.str(), File };
1964 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001965 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001966 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001967 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001968
1969 // If we find a module that has a missing header, we mark this module as
1970 // unavailable and store the header directive for displaying diagnostics.
Ben Langmuirec8c9752014-04-18 22:07:31 +00001971 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001972 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001973 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001974}
1975
Ben Langmuir41f81992015-08-13 17:30:07 +00001976static int compareModuleHeaders(const Module::Header *A,
1977 const Module::Header *B) {
1978 return A->NameAsWritten.compare(B->NameAsWritten);
1979}
1980
Douglas Gregor524e33e2011-12-08 19:11:24 +00001981/// \brief Parse an umbrella directory declaration.
1982///
1983/// umbrella-dir-declaration:
1984/// umbrella string-literal
1985void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1986 // Parse the directory name.
1987 if (!Tok.is(MMToken::StringLiteral)) {
1988 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1989 << "umbrella";
1990 HadError = true;
1991 return;
1992 }
1993
1994 std::string DirName = Tok.getString();
1995 SourceLocation DirNameLoc = consumeToken();
1996
1997 // Check whether we already have an umbrella.
1998 if (ActiveModule->Umbrella) {
1999 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2000 << ActiveModule->getFullModuleName();
2001 HadError = true;
2002 return;
2003 }
2004
2005 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00002006 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002007 if (llvm::sys::path::is_absolute(DirName))
2008 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2009 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00002010 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002011 PathName = Directory->getName();
2012 llvm::sys::path::append(PathName, DirName);
2013 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2014 }
2015
2016 if (!Dir) {
Vassil Vassileva0320b92017-04-18 20:57:29 +00002017 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
Douglas Gregor524e33e2011-12-08 19:11:24 +00002018 << DirName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002019 return;
2020 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00002021
2022 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2023 // Mark this header 'textual' (see doc comment for
2024 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2025 // directory is relatively expensive, in practice this only applies to the
2026 // uncommonly used Tcl module on Darwin platforms.
2027 std::error_code EC;
2028 SmallVector<Module::Header, 6> Headers;
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002029 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2030 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002031 I != E && !EC; I.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002032 if (const FileEntry *FE =
2033 SourceMgr.getFileManager().getFile(I->getName())) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00002034
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002035 Module::Header Header = {I->getName(), FE};
Ben Langmuir7ff29142015-08-13 17:13:33 +00002036 Headers.push_back(std::move(Header));
2037 }
2038 }
2039
2040 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00002041 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2042
Ben Langmuir7ff29142015-08-13 17:13:33 +00002043 for (auto &Header : Headers)
2044 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2045 return;
2046 }
2047
Douglas Gregor524e33e2011-12-08 19:11:24 +00002048 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2049 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2050 << OwningModule->getFullModuleName();
2051 HadError = true;
2052 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002053 }
2054
Douglas Gregor524e33e2011-12-08 19:11:24 +00002055 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00002056 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00002057}
2058
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002059/// \brief Parse a module export declaration.
2060///
2061/// export-declaration:
2062/// 'export' wildcard-module-id
2063///
2064/// wildcard-module-id:
2065/// identifier
2066/// '*'
2067/// identifier '.' wildcard-module-id
2068void ModuleMapParser::parseExportDecl() {
2069 assert(Tok.is(MMToken::ExportKeyword));
2070 SourceLocation ExportLoc = consumeToken();
2071
2072 // Parse the module-id with an optional wildcard at the end.
2073 ModuleId ParsedModuleId;
2074 bool Wildcard = false;
2075 do {
Richard Smith306d8922014-10-22 23:50:56 +00002076 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002077 if (Tok.is(MMToken::Identifier)) {
2078 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
2079 Tok.getLocation()));
2080 consumeToken();
2081
2082 if (Tok.is(MMToken::Period)) {
2083 consumeToken();
2084 continue;
2085 }
2086
2087 break;
2088 }
2089
2090 if(Tok.is(MMToken::Star)) {
2091 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00002092 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002093 break;
2094 }
2095
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002096 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002097 HadError = true;
2098 return;
2099 } while (true);
2100
2101 Module::UnresolvedExportDecl Unresolved = {
2102 ExportLoc, ParsedModuleId, Wildcard
2103 };
2104 ActiveModule->UnresolvedExports.push_back(Unresolved);
2105}
2106
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002107/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002108///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002109/// use-declaration:
2110/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002111void ModuleMapParser::parseUseDecl() {
2112 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002113 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002114 // Parse the module-id.
2115 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002116 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002117
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002118 if (ActiveModule->Parent)
2119 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2120 else
2121 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002122}
2123
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002124/// \brief Parse a link declaration.
2125///
2126/// module-declaration:
2127/// 'link' 'framework'[opt] string-literal
2128void ModuleMapParser::parseLinkDecl() {
2129 assert(Tok.is(MMToken::LinkKeyword));
2130 SourceLocation LinkLoc = consumeToken();
2131
2132 // Parse the optional 'framework' keyword.
2133 bool IsFramework = false;
2134 if (Tok.is(MMToken::FrameworkKeyword)) {
2135 consumeToken();
2136 IsFramework = true;
2137 }
2138
2139 // Parse the library name
2140 if (!Tok.is(MMToken::StringLiteral)) {
2141 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2142 << IsFramework << SourceRange(LinkLoc);
2143 HadError = true;
2144 return;
2145 }
2146
2147 std::string LibraryName = Tok.getString();
2148 consumeToken();
2149 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2150 IsFramework));
2151}
2152
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002153/// \brief Parse a configuration macro declaration.
2154///
2155/// module-declaration:
2156/// 'config_macros' attributes[opt] config-macro-list?
2157///
2158/// config-macro-list:
2159/// identifier (',' identifier)?
2160void ModuleMapParser::parseConfigMacros() {
2161 assert(Tok.is(MMToken::ConfigMacros));
2162 SourceLocation ConfigMacrosLoc = consumeToken();
2163
2164 // Only top-level modules can have configuration macros.
2165 if (ActiveModule->Parent) {
2166 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2167 }
2168
2169 // Parse the optional attributes.
2170 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002171 if (parseOptionalAttributes(Attrs))
2172 return;
2173
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002174 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2175 ActiveModule->ConfigMacrosExhaustive = true;
2176 }
2177
2178 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002179 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002180 if (!Tok.is(MMToken::Identifier))
2181 return;
2182
2183 // Consume the first identifier.
2184 if (!ActiveModule->Parent) {
2185 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2186 }
2187 consumeToken();
2188
2189 do {
2190 // If there's a comma, consume it.
2191 if (!Tok.is(MMToken::Comma))
2192 break;
2193 consumeToken();
2194
2195 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002196 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002197 if (!Tok.is(MMToken::Identifier)) {
2198 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2199 break;
2200 }
2201
2202 // Consume the macro name.
2203 if (!ActiveModule->Parent) {
2204 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2205 }
2206 consumeToken();
2207 } while (true);
2208}
2209
Douglas Gregorfb912652013-03-20 21:10:35 +00002210/// \brief Format a module-id into a string.
2211static std::string formatModuleId(const ModuleId &Id) {
2212 std::string result;
2213 {
2214 llvm::raw_string_ostream OS(result);
2215
2216 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2217 if (I)
2218 OS << ".";
2219 OS << Id[I].first;
2220 }
2221 }
2222
2223 return result;
2224}
2225
2226/// \brief Parse a conflict declaration.
2227///
2228/// module-declaration:
2229/// 'conflict' module-id ',' string-literal
2230void ModuleMapParser::parseConflict() {
2231 assert(Tok.is(MMToken::Conflict));
2232 SourceLocation ConflictLoc = consumeToken();
2233 Module::UnresolvedConflict Conflict;
2234
2235 // Parse the module-id.
2236 if (parseModuleId(Conflict.Id))
2237 return;
2238
2239 // Parse the ','.
2240 if (!Tok.is(MMToken::Comma)) {
2241 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2242 << SourceRange(ConflictLoc);
2243 return;
2244 }
2245 consumeToken();
2246
2247 // Parse the message.
2248 if (!Tok.is(MMToken::StringLiteral)) {
2249 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2250 << formatModuleId(Conflict.Id);
2251 return;
2252 }
2253 Conflict.Message = Tok.getString().str();
2254 consumeToken();
2255
2256 // Add this unresolved conflict.
2257 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2258}
2259
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002260/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002261///
2262/// module-declaration:
2263/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2264/// { inferred-module-member* }
2265///
2266/// inferred-module-member:
2267/// 'export' '*'
2268/// 'exclude' identifier
2269void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002270 assert(Tok.is(MMToken::Star));
2271 SourceLocation StarLoc = consumeToken();
2272 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002273
Douglas Gregor73441092011-12-05 22:27:44 +00002274 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002275 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002276 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2277 Failed = true;
2278 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002279
2280 if (ActiveModule) {
2281 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002282 if (!Failed && ActiveModule->IsAvailable &&
2283 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002284 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2285 Failed = true;
2286 }
2287
2288 // Check for redefinition of an inferred module.
2289 if (!Failed && ActiveModule->InferSubmodules) {
2290 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2291 if (ActiveModule->InferredSubmoduleLoc.isValid())
2292 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2293 diag::note_mmap_prev_definition);
2294 Failed = true;
2295 }
2296
2297 // Check for the 'framework' keyword, which is not permitted here.
2298 if (Framework) {
2299 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2300 Framework = false;
2301 }
2302 } else if (Explicit) {
2303 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2304 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002305 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002306
Douglas Gregor73441092011-12-05 22:27:44 +00002307 // If there were any problems with this inferred submodule, skip its body.
2308 if (Failed) {
2309 if (Tok.is(MMToken::LBrace)) {
2310 consumeToken();
2311 skipUntil(MMToken::RBrace);
2312 if (Tok.is(MMToken::RBrace))
2313 consumeToken();
2314 }
2315 HadError = true;
2316 return;
2317 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002318
2319 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002320 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002321 if (parseOptionalAttributes(Attrs))
2322 return;
Douglas Gregor9194a912012-11-06 19:39:40 +00002323
2324 if (ActiveModule) {
2325 // Note that we have an inferred submodule.
2326 ActiveModule->InferSubmodules = true;
2327 ActiveModule->InferredSubmoduleLoc = StarLoc;
2328 ActiveModule->InferExplicitSubmodules = Explicit;
2329 } else {
2330 // We'll be inferring framework modules for this directory.
2331 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002332 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002333 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002334 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002335 }
2336
Douglas Gregor73441092011-12-05 22:27:44 +00002337 // Parse the opening brace.
2338 if (!Tok.is(MMToken::LBrace)) {
2339 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2340 HadError = true;
2341 return;
2342 }
2343 SourceLocation LBraceLoc = consumeToken();
2344
2345 // Parse the body of the inferred submodule.
2346 bool Done = false;
2347 do {
2348 switch (Tok.Kind) {
2349 case MMToken::EndOfFile:
2350 case MMToken::RBrace:
2351 Done = true;
2352 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002353
2354 case MMToken::ExcludeKeyword: {
2355 if (ActiveModule) {
2356 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002357 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002358 consumeToken();
2359 break;
2360 }
2361
2362 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002363 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002364 if (!Tok.is(MMToken::Identifier)) {
2365 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2366 break;
2367 }
2368
2369 Map.InferredDirectories[Directory].ExcludedModules
2370 .push_back(Tok.getString());
2371 consumeToken();
2372 break;
2373 }
2374
2375 case MMToken::ExportKeyword:
2376 if (!ActiveModule) {
2377 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002378 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002379 consumeToken();
2380 break;
2381 }
2382
Douglas Gregor73441092011-12-05 22:27:44 +00002383 consumeToken();
2384 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002385 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002386 else
2387 Diags.Report(Tok.getLocation(),
2388 diag::err_mmap_expected_export_wildcard);
2389 consumeToken();
2390 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002391
Douglas Gregor73441092011-12-05 22:27:44 +00002392 case MMToken::ExplicitKeyword:
2393 case MMToken::ModuleKeyword:
2394 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002395 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002396 case MMToken::UmbrellaKeyword:
2397 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002398 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002399 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002400 consumeToken();
2401 break;
2402 }
2403 } while (!Done);
2404
2405 if (Tok.is(MMToken::RBrace))
2406 consumeToken();
2407 else {
2408 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2409 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2410 HadError = true;
2411 }
2412}
2413
Douglas Gregor9194a912012-11-06 19:39:40 +00002414/// \brief Parse optional attributes.
2415///
2416/// attributes:
2417/// attribute attributes
2418/// attribute
2419///
2420/// attribute:
2421/// [ identifier ]
2422///
2423/// \param Attrs Will be filled in with the parsed attributes.
2424///
2425/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002426bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002427 bool HadError = false;
2428
2429 while (Tok.is(MMToken::LSquare)) {
2430 // Consume the '['.
2431 SourceLocation LSquareLoc = consumeToken();
2432
2433 // Check whether we have an attribute name here.
2434 if (!Tok.is(MMToken::Identifier)) {
2435 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2436 skipUntil(MMToken::RSquare);
2437 if (Tok.is(MMToken::RSquare))
2438 consumeToken();
2439 HadError = true;
2440 }
2441
2442 // Decode the attribute name.
2443 AttributeKind Attribute
2444 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002445 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002446 .Case("extern_c", AT_extern_c)
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002447 .Case("no_undeclared_includes", AT_no_undeclared_includes)
Douglas Gregor9194a912012-11-06 19:39:40 +00002448 .Case("system", AT_system)
2449 .Default(AT_unknown);
2450 switch (Attribute) {
2451 case AT_unknown:
2452 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2453 << Tok.getString();
2454 break;
2455
2456 case AT_system:
2457 Attrs.IsSystem = true;
2458 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002459
Richard Smith77944862014-03-02 05:58:18 +00002460 case AT_extern_c:
2461 Attrs.IsExternC = true;
2462 break;
2463
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002464 case AT_exhaustive:
2465 Attrs.IsExhaustive = true;
2466 break;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002467
2468 case AT_no_undeclared_includes:
2469 Attrs.NoUndeclaredIncludes = true;
2470 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002471 }
2472 consumeToken();
2473
2474 // Consume the ']'.
2475 if (!Tok.is(MMToken::RSquare)) {
2476 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2477 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2478 skipUntil(MMToken::RSquare);
2479 HadError = true;
2480 }
2481
2482 if (Tok.is(MMToken::RSquare))
2483 consumeToken();
2484 }
2485
2486 return HadError;
2487}
2488
Douglas Gregor718292f2011-11-11 19:10:28 +00002489/// \brief Parse a module map file.
2490///
2491/// module-map-file:
2492/// module-declaration*
2493bool ModuleMapParser::parseModuleMapFile() {
2494 do {
2495 switch (Tok.Kind) {
2496 case MMToken::EndOfFile:
2497 return HadError;
2498
Douglas Gregore7ab3662011-12-07 02:23:45 +00002499 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002500 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002501 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002502 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002503 parseModuleDecl();
2504 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002505
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002506 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002507 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002508 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002509 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002510 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002511 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002512 case MMToken::HeaderKeyword:
2513 case MMToken::Identifier:
2514 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002515 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002516 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002517 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002518 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002519 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002520 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002521 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002522 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002523 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002524 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002525 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002526 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002527 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2528 HadError = true;
2529 consumeToken();
2530 break;
2531 }
2532 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002533}
2534
Richard Smith9acb99e32014-12-10 03:09:48 +00002535bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smith8128f332017-05-05 22:18:51 +00002536 const DirectoryEntry *Dir, FileID ID,
2537 unsigned *Offset,
Richard Smithae6df272015-07-14 02:06:01 +00002538 SourceLocation ExternModuleLoc) {
Richard Smith8128f332017-05-05 22:18:51 +00002539 assert(Target && "Missing target information");
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002540 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2541 = ParsedModuleMap.find(File);
2542 if (Known != ParsedModuleMap.end())
2543 return Known->second;
2544
Richard Smith8128f332017-05-05 22:18:51 +00002545 // If the module map file wasn't already entered, do so now.
2546 if (ID.isInvalid()) {
2547 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2548 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2549 }
2550
Craig Topperd2d442c2014-05-17 23:10:59 +00002551 assert(Target && "Missing target information");
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002552 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002553 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002554 return ParsedModuleMap[File] = true;
Richard Smith8128f332017-05-05 22:18:51 +00002555 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2556 "invalid buffer offset");
Ben Langmuir984e1df2014-03-19 20:23:34 +00002557
Douglas Gregor718292f2011-11-11 19:10:28 +00002558 // Parse this module map file.
Richard Smith8128f332017-05-05 22:18:51 +00002559 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2560 Buffer->getBufferStart(),
2561 Buffer->getBufferStart() + (Offset ? *Offset : 0),
2562 Buffer->getBufferEnd());
Richard Smith2a6edb32015-08-09 04:46:57 +00002563 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002564 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Richard Smith1d609872017-05-26 00:01:53 +00002565 IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002566 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002567 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002568
Richard Smith8128f332017-05-05 22:18:51 +00002569 if (Offset) {
2570 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
2571 assert(Loc.first == ID && "stopped in a different file?");
2572 *Offset = Loc.second;
2573 }
2574
Richard Smith2a6edb32015-08-09 04:46:57 +00002575 // Notify callbacks that we parsed it.
2576 for (const auto &Cb : Callbacks)
2577 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002578 return Result;
2579}