blob: e29cc692eae25259dab576b2d123068611d014de [file] [log] [blame]
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
Douglas Gregor718292f2011-11-11 19:10:28 +00002//
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//===----------------------------------------------------------------------===//
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +000014
Douglas Gregor718292f2011-11-11 19:10:28 +000015#include "clang/Lex/ModuleMap.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000016#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000017#include "clang/Basic/Diagnostic.h"
18#include "clang/Basic/FileManager.h"
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +000019#include "clang/Basic/LLVM.h"
20#include "clang/Basic/LangOptions.h"
21#include "clang/Basic/Module.h"
22#include "clang/Basic/SourceLocation.h"
23#include "clang/Basic/SourceManager.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000024#include "clang/Basic/TargetInfo.h"
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +000025#include "clang/Basic/VirtualFileSystem.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000026#include "clang/Lex/HeaderSearch.h"
Richard Smith9acb99e32014-12-10 03:09:48 +000027#include "clang/Lex/HeaderSearchOptions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000028#include "clang/Lex/LexDiagnostic.h"
29#include "clang/Lex/Lexer.h"
30#include "clang/Lex/LiteralSupport.h"
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +000031#include "clang/Lex/Token.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/None.h"
34#include "llvm/ADT/STLExtras.h"
35#include "llvm/ADT/SmallPtrSet.h"
36#include "llvm/ADT/SmallString.h"
37#include "llvm/ADT/SmallVector.h"
38#include "llvm/ADT/StringMap.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000039#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/StringSwitch.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000041#include "llvm/Support/Allocator.h"
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +000042#include "llvm/Support/Compiler.h"
43#include "llvm/Support/ErrorHandling.h"
44#include "llvm/Support/MemoryBuffer.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000045#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000046#include "llvm/Support/raw_ostream.h"
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +000047#include <algorithm>
48#include <cassert>
49#include <cstdint>
50#include <cstring>
51#include <string>
52#include <system_error>
53#include <utility>
54
Douglas Gregor718292f2011-11-11 19:10:28 +000055using namespace clang;
56
Bruno Cardoso Lopesa3b5f712018-04-16 19:42:32 +000057void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
58 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
59 if (PendingLinkAs != PendingLinkAsModule.end()) {
60 for (auto &Name : PendingLinkAs->second) {
61 auto *M = findModule(Name.getKey());
62 if (M)
63 M->UseExportAsModuleLinkName = true;
64 }
65 }
66}
67
68void ModuleMap::addLinkAsDependency(Module *Mod) {
69 if (findModule(Mod->ExportAsModule))
70 Mod->UseExportAsModuleLinkName = true;
71 else
72 PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
73}
74
Richard Smith040e1262017-06-02 01:55:39 +000075Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
76 switch ((int)Role) {
77 default: llvm_unreachable("unknown header role");
78 case NormalHeader:
79 return Module::HK_Normal;
80 case PrivateHeader:
81 return Module::HK_Private;
82 case TextualHeader:
83 return Module::HK_Textual;
84 case PrivateHeader | TextualHeader:
85 return Module::HK_PrivateTextual;
86 }
87}
88
89ModuleMap::ModuleHeaderRole
90ModuleMap::headerKindToRole(Module::HeaderKind Kind) {
91 switch ((int)Kind) {
92 case Module::HK_Normal:
93 return NormalHeader;
94 case Module::HK_Private:
95 return PrivateHeader;
96 case Module::HK_Textual:
97 return TextualHeader;
98 case Module::HK_PrivateTextual:
99 return ModuleHeaderRole(PrivateHeader | TextualHeader);
100 case Module::HK_Excluded:
101 llvm_unreachable("unexpected header kind");
102 }
103 llvm_unreachable("unknown header kind");
104}
105
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000106Module::ExportDecl
107ModuleMap::resolveExport(Module *Mod,
108 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000109 bool Complain) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000110 // We may have just a wildcard.
111 if (Unresolved.Id.empty()) {
112 assert(Unresolved.Wildcard && "Invalid unresolved export");
Craig Topperd2d442c2014-05-17 23:10:59 +0000113 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000114 }
115
Douglas Gregorfb912652013-03-20 21:10:35 +0000116 // Resolve the module-id.
117 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
118 if (!Context)
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +0000119 return {};
Douglas Gregorfb912652013-03-20 21:10:35 +0000120
121 return Module::ExportDecl(Context, Unresolved.Wildcard);
122}
123
124Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
125 bool Complain) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000126 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +0000127 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000128 if (!Context) {
129 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000130 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +0000131 << Id[0].first << Mod->getFullModuleName();
132
Craig Topperd2d442c2014-05-17 23:10:59 +0000133 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000134 }
135
136 // Dig into the module path.
Douglas Gregorfb912652013-03-20 21:10:35 +0000137 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
138 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000139 if (!Sub) {
140 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000141 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +0000142 << Id[I].first << Context->getFullModuleName()
143 << SourceRange(Id[0].second, Id[I-1].second);
144
Craig Topperd2d442c2014-05-17 23:10:59 +0000145 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000146 }
Douglas Gregorfb912652013-03-20 21:10:35 +0000147
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000148 Context = Sub;
149 }
Douglas Gregorfb912652013-03-20 21:10:35 +0000150
151 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000152}
153
Richard Smith1d609872017-05-26 00:01:53 +0000154/// \brief Append to \p Paths the set of paths needed to get to the
155/// subframework in which the given module lives.
156static void appendSubframeworkPaths(Module *Mod,
157 SmallVectorImpl<char> &Path) {
158 // Collect the framework names from the given module to the top-level module.
159 SmallVector<StringRef, 2> Paths;
160 for (; Mod; Mod = Mod->Parent) {
161 if (Mod->IsFramework)
162 Paths.push_back(Mod->Name);
163 }
164
165 if (Paths.empty())
166 return;
167
168 // Add Frameworks/Name.framework for each subframework.
169 for (unsigned I = Paths.size() - 1; I != 0; --I)
170 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
171}
172
173const FileEntry *
Richard Smith040e1262017-06-02 01:55:39 +0000174ModuleMap::findHeader(Module *M,
175 const Module::UnresolvedHeaderDirective &Header,
176 SmallVectorImpl<char> &RelativePathName) {
177 auto GetFile = [&](StringRef Filename) -> const FileEntry * {
178 auto *File = SourceMgr.getFileManager().getFile(Filename);
179 if (!File ||
180 (Header.Size && File->getSize() != *Header.Size) ||
181 (Header.ModTime && File->getModificationTime() != *Header.ModTime))
182 return nullptr;
183 return File;
184 };
185
Richard Smith1d609872017-05-26 00:01:53 +0000186 if (llvm::sys::path::is_absolute(Header.FileName)) {
187 RelativePathName.clear();
188 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
Richard Smith040e1262017-06-02 01:55:39 +0000189 return GetFile(Header.FileName);
Richard Smith1d609872017-05-26 00:01:53 +0000190 }
191
192 // Search for the header file within the module's home directory.
193 auto *Directory = M->Directory;
194 SmallString<128> FullPathName(Directory->getName());
195 unsigned FullPathLength = FullPathName.size();
196
197 if (M->isPartOfFramework()) {
198 appendSubframeworkPaths(M, RelativePathName);
199 unsigned RelativePathLength = RelativePathName.size();
200
201 // Check whether this file is in the public headers.
202 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
203 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith040e1262017-06-02 01:55:39 +0000204 if (auto *File = GetFile(FullPathName))
Richard Smith1d609872017-05-26 00:01:53 +0000205 return File;
206
207 // Check whether this file is in the private headers.
208 // Ideally, private modules in the form 'FrameworkName.Private' should
209 // be defined as 'module FrameworkName.Private', and not as
210 // 'framework module FrameworkName.Private', since a 'Private.Framework'
211 // does not usually exist. However, since both are currently widely used
212 // for private modules, make sure we find the right path in both cases.
213 if (M->IsFramework && M->Name == "Private")
214 RelativePathName.clear();
215 else
216 RelativePathName.resize(RelativePathLength);
217 FullPathName.resize(FullPathLength);
218 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
219 Header.FileName);
220 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith040e1262017-06-02 01:55:39 +0000221 return GetFile(FullPathName);
Richard Smith1d609872017-05-26 00:01:53 +0000222 }
223
224 // Lookup for normal headers.
225 llvm::sys::path::append(RelativePathName, Header.FileName);
226 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith040e1262017-06-02 01:55:39 +0000227 return GetFile(FullPathName);
Richard Smith1d609872017-05-26 00:01:53 +0000228}
229
Richard Smith040e1262017-06-02 01:55:39 +0000230void ModuleMap::resolveHeader(Module *Mod,
231 const Module::UnresolvedHeaderDirective &Header) {
232 SmallString<128> RelativePathName;
233 if (const FileEntry *File = findHeader(Mod, Header, RelativePathName)) {
234 if (Header.IsUmbrella) {
235 const DirectoryEntry *UmbrellaDir = File->getDir();
236 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
237 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
238 << UmbrellaMod->getFullModuleName();
239 else
240 // Record this umbrella header.
241 setUmbrellaHeader(Mod, File, RelativePathName.str());
242 } else {
243 Module::Header H = {RelativePathName.str(), File};
244 if (Header.Kind == Module::HK_Excluded)
245 excludeHeader(Mod, H);
246 else
247 addHeader(Mod, H, headerKindToRole(Header.Kind));
248 }
249 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
250 // There's a builtin header but no corresponding on-disk header. Assume
251 // this was supposed to modularize the builtin header alone.
252 } else if (Header.Kind == Module::HK_Excluded) {
253 // Ignore missing excluded header files. They're optional anyway.
254 } else {
255 // If we find a module that has a missing header, we mark this module as
256 // unavailable and store the header directive for displaying diagnostics.
257 Mod->MissingHeaders.push_back(Header);
258 // A missing header with stat information doesn't make the module
259 // unavailable; this keeps our behavior consistent as headers are lazily
260 // resolved. (Such a module still can't be built though, except from
261 // preprocessed source.)
262 if (!Header.Size && !Header.ModTime)
263 Mod->markUnavailable();
264 }
265}
266
267bool ModuleMap::resolveAsBuiltinHeader(
268 Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
269 if (Header.Kind == Module::HK_Excluded ||
270 llvm::sys::path::is_absolute(Header.FileName) ||
271 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
272 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
273 !isBuiltinHeader(Header.FileName))
274 return false;
Richard Smith1d609872017-05-26 00:01:53 +0000275
276 // This is a system module with a top-level header. This header
277 // may have a counterpart (or replacement) in the set of headers
278 // supplied by Clang. Find that builtin header.
Richard Smith040e1262017-06-02 01:55:39 +0000279 SmallString<128> Path;
280 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
281 auto *File = SourceMgr.getFileManager().getFile(Path);
282 if (!File)
283 return false;
284
285 auto Role = headerKindToRole(Header.Kind);
286 Module::Header H = {Path.str(), File};
287 addHeader(Mod, H, Role);
288 return true;
Richard Smith1d609872017-05-26 00:01:53 +0000289}
290
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000291ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000292 const LangOptions &LangOpts, const TargetInfo *Target,
293 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000294 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Richard Smith056bf772017-09-05 21:46:22 +0000295 HeaderInfo(HeaderInfo) {
Richard Smith0414b852015-02-14 05:32:00 +0000296 MMapLangOpts.LineComment = true;
297}
Douglas Gregor718292f2011-11-11 19:10:28 +0000298
299ModuleMap::~ModuleMap() {
Davide Italiano21668752016-03-08 23:58:08 +0000300 for (auto &M : Modules)
301 delete M.getValue();
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +0000302 for (auto *M : ShadowModules)
303 delete M;
Douglas Gregor718292f2011-11-11 19:10:28 +0000304}
305
Douglas Gregor89929282012-01-30 06:01:29 +0000306void ModuleMap::setTarget(const TargetInfo &Target) {
307 assert((!this->Target || this->Target == &Target) &&
308 "Improper target override");
309 this->Target = &Target;
310}
311
Douglas Gregor056396a2012-10-12 21:15:50 +0000312/// \brief "Sanitize" a filename so that it can be used as an identifier.
313static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
314 SmallVectorImpl<char> &Buffer) {
315 if (Name.empty())
316 return Name;
317
Jordan Rosea7d03842013-02-08 22:30:41 +0000318 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000319 // If we don't already have something with the form of an identifier,
320 // create a buffer with the sanitized name.
321 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000322 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000323 Buffer.push_back('_');
324 Buffer.reserve(Buffer.size() + Name.size());
325 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000326 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000327 Buffer.push_back(Name[I]);
328 else
329 Buffer.push_back('_');
330 }
331
332 Name = StringRef(Buffer.data(), Buffer.size());
333 }
334
335 while (llvm::StringSwitch<bool>(Name)
336#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
337#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
338#include "clang/Basic/TokenKinds.def"
339 .Default(false)) {
340 if (Name.data() != Buffer.data())
341 Buffer.append(Name.begin(), Name.end());
342 Buffer.push_back('_');
343 Name = StringRef(Buffer.data(), Buffer.size());
344 }
345
346 return Name;
347}
348
Douglas Gregor34d52742013-05-02 17:58:30 +0000349/// \brief Determine whether the given file name is the name of a builtin
350/// header, supplied by Clang to replace, override, or augment existing system
351/// headers.
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000352bool ModuleMap::isBuiltinHeader(StringRef FileName) {
Douglas Gregor34d52742013-05-02 17:58:30 +0000353 return llvm::StringSwitch<bool>(FileName)
354 .Case("float.h", true)
355 .Case("iso646.h", true)
356 .Case("limits.h", true)
357 .Case("stdalign.h", true)
358 .Case("stdarg.h", true)
Ben Langmuir3c4b1292016-03-09 23:31:34 +0000359 .Case("stdatomic.h", true)
Douglas Gregor34d52742013-05-02 17:58:30 +0000360 .Case("stdbool.h", true)
361 .Case("stddef.h", true)
362 .Case("stdint.h", true)
363 .Case("tgmath.h", true)
364 .Case("unwind.h", true)
365 .Default(false);
366}
367
Daniel Jasper92669ee2013-12-20 12:09:36 +0000368ModuleMap::HeadersMap::iterator
369ModuleMap::findKnownHeader(const FileEntry *File) {
Richard Smith040e1262017-06-02 01:55:39 +0000370 resolveHeaderDirectives(File);
Douglas Gregor59527662012-10-15 06:28:11 +0000371 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000372 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
373 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000374 ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000375 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000376 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000377 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000378 return Known;
379}
380
Ben Langmuir44691382014-04-10 00:39:10 +0000381ModuleMap::KnownHeader
382ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
383 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000384 if (UmbrellaDirs.empty())
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +0000385 return {};
Richard Smith47972af2015-06-16 00:08:24 +0000386
Ben Langmuir44691382014-04-10 00:39:10 +0000387 const DirectoryEntry *Dir = File->getDir();
388 assert(Dir && "file in no directory");
389
390 // Note: as an egregious but useful hack we use the real path here, because
391 // frameworks moving from top-level frameworks to embedded frameworks tend
392 // to be symlinked from the top-level location to the embedded location,
393 // and we need to resolve lookups as if we had found the embedded location.
394 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
395
396 // Keep walking up the directory hierarchy, looking for a directory with
397 // an umbrella header.
398 do {
399 auto KnownDir = UmbrellaDirs.find(Dir);
400 if (KnownDir != UmbrellaDirs.end())
401 return KnownHeader(KnownDir->second, NormalHeader);
402
403 IntermediateDirs.push_back(Dir);
404
405 // Retrieve our parent path.
406 DirName = llvm::sys::path::parent_path(DirName);
407 if (DirName.empty())
408 break;
409
410 // Resolve the parent path to a directory entry.
411 Dir = SourceMgr.getFileManager().getDirectory(DirName);
412 } while (Dir);
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +0000413 return {};
Ben Langmuir44691382014-04-10 00:39:10 +0000414}
415
Daniel Jasper92669ee2013-12-20 12:09:36 +0000416static bool violatesPrivateInclude(Module *RequestingModule,
417 const FileEntry *IncFileEnt,
Richard Smith4eb83932016-04-27 21:57:05 +0000418 ModuleMap::KnownHeader Header) {
Richard Smith202210b2014-10-24 20:23:01 +0000419#ifndef NDEBUG
Richard Smith4eb83932016-04-27 21:57:05 +0000420 if (Header.getRole() & ModuleMap::PrivateHeader) {
Richard Smith2708e522015-03-10 00:19:04 +0000421 // Check for consistency between the module header role
422 // as obtained from the lookup and as obtained from the module.
423 // This check is not cheap, so enable it only for debugging.
424 bool IsPrivate = false;
425 SmallVectorImpl<Module::Header> *HeaderList[] = {
Richard Smith4eb83932016-04-27 21:57:05 +0000426 &Header.getModule()->Headers[Module::HK_Private],
427 &Header.getModule()->Headers[Module::HK_PrivateTextual]};
Richard Smith2708e522015-03-10 00:19:04 +0000428 for (auto *Hs : HeaderList)
429 IsPrivate |=
430 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000431 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000432 }) != Hs->end();
Richard Smith4eb83932016-04-27 21:57:05 +0000433 assert(IsPrivate && "inconsistent headers and roles");
Richard Smith2708e522015-03-10 00:19:04 +0000434 }
Richard Smith202210b2014-10-24 20:23:01 +0000435#endif
Richard Smith4eb83932016-04-27 21:57:05 +0000436 return !Header.isAccessibleFrom(RequestingModule);
Daniel Jasper92669ee2013-12-20 12:09:36 +0000437}
438
Ben Langmuir71e1a642014-05-05 21:44:13 +0000439static Module *getTopLevelOrNull(Module *M) {
440 return M ? M->getTopLevelModule() : nullptr;
441}
442
Daniel Jasper92669ee2013-12-20 12:09:36 +0000443void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
Richard Smith8d4e90b2016-03-14 17:52:37 +0000444 bool RequestingModuleIsModuleInterface,
Daniel Jasper92669ee2013-12-20 12:09:36 +0000445 SourceLocation FilenameLoc,
446 StringRef Filename,
447 const FileEntry *File) {
448 // No errors for indirect modules. This may be a bit of a problem for modules
449 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000450 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000451 return;
452
Richard Smith040e1262017-06-02 01:55:39 +0000453 if (RequestingModule) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000454 resolveUses(RequestingModule, /*Complain=*/false);
Richard Smith040e1262017-06-02 01:55:39 +0000455 resolveHeaderDirectives(RequestingModule);
456 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000457
Ben Langmuir71e1a642014-05-05 21:44:13 +0000458 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000459 Module *Private = nullptr;
460 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000461
Ben Langmuir71e1a642014-05-05 21:44:13 +0000462 HeadersMap::iterator Known = findKnownHeader(File);
463 if (Known != Headers.end()) {
464 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000465 // Remember private headers for later printing of a diagnostic.
Richard Smith4eb83932016-04-27 21:57:05 +0000466 if (violatesPrivateInclude(RequestingModule, File, Header)) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000467 Private = Header.getModule();
468 continue;
469 }
470
471 // If uses need to be specified explicitly, we are only allowed to return
472 // modules that are explicitly used by the requesting module.
473 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000474 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000475 NotUsed = Header.getModule();
476 continue;
477 }
478
479 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000480 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000481 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000482
483 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000484 }
485
486 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000487 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000488 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000489 << Filename;
490 return;
491 }
492
493 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000494 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000495 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper4ea330c2018-02-24 06:54:09 +0000496 << RequestingModule->getTopLevelModule()->Name << Filename;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000497 return;
498 }
499
Ben Langmuir71e1a642014-05-05 21:44:13 +0000500 if (Excluded || isHeaderInUmbrellaDirs(File))
501 return;
502
503 // At this point, only non-modular includes remain.
504
505 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000506 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper4ea330c2018-02-24 06:54:09 +0000507 << RequestingModule->getTopLevelModule()->Name << Filename;
Manman Rena67e4d32016-08-26 17:16:46 +0000508 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
509 LangOpts.isCompilingModule()) {
510 // Do not diagnose when we are not compiling a module.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000511 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
512 diag::warn_non_modular_include_in_framework_module :
513 diag::warn_non_modular_include_in_module;
Manman Ren70a77382016-10-21 23:27:37 +0000514 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
515 << File->getName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000516 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000517}
518
Richard Smithec87a502015-02-13 23:50:20 +0000519static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
520 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000521 // Prefer available modules.
522 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
523 return true;
524
Richard Smithec87a502015-02-13 23:50:20 +0000525 // Prefer a public header over a private header.
526 if ((New.getRole() & ModuleMap::PrivateHeader) !=
527 (Old.getRole() & ModuleMap::PrivateHeader))
528 return !(New.getRole() & ModuleMap::PrivateHeader);
529
530 // Prefer a non-textual header over a textual header.
531 if ((New.getRole() & ModuleMap::TextualHeader) !=
532 (Old.getRole() & ModuleMap::TextualHeader))
533 return !(New.getRole() & ModuleMap::TextualHeader);
534
535 // Don't have a reason to choose between these. Just keep the first one.
536 return false;
537}
538
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000539ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
540 bool AllowTextual) {
Richard Smith306d8922014-10-22 23:50:56 +0000541 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000542 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +0000543 return {};
Richard Smith306d8922014-10-22 23:50:56 +0000544 return R;
545 };
546
Sean Silva4881e8b2015-06-10 01:37:59 +0000547 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000548 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000549 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000550 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000551 for (KnownHeader &H : Known->second) {
Richard Smith7e82e012016-02-19 22:25:36 +0000552 // Prefer a header from the source module over all others.
553 if (H.getModule()->getTopLevelModule() == SourceModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000554 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000555 if (!Result || isBetterKnownHeader(H, Result))
556 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000557 }
Richard Smith306d8922014-10-22 23:50:56 +0000558 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000559 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000560
Richard Smith386bb072015-08-18 23:42:23 +0000561 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
562}
563
564ModuleMap::KnownHeader
565ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
566 assert(!Headers.count(File) && "already have a module for this header");
567
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000568 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000569 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
570 if (H) {
571 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000572
Ben Langmuir44691382014-04-10 00:39:10 +0000573 // Search up the module stack until we find a module with an umbrella
574 // directory.
575 Module *UmbrellaModule = Result;
576 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
577 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000578
Ben Langmuir44691382014-04-10 00:39:10 +0000579 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000580 const FileEntry *UmbrellaModuleMap =
581 getModuleMapFileForUniquing(UmbrellaModule);
582
Ben Langmuir44691382014-04-10 00:39:10 +0000583 // Infer submodules for each of the directories we found between
584 // the directory of the umbrella header and the directory where
585 // the actual header is located.
586 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000587
Ben Langmuir44691382014-04-10 00:39:10 +0000588 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
589 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000590 SmallString<32> NameBuf;
591 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000592 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000593 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
594 Explicit).first;
595 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000596 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000597
598 // Associate the module and the directory.
599 UmbrellaDirs[SkippedDirs[I-1]] = Result;
600
601 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000602 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000603 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000604 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000605 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000606
Ben Langmuir44691382014-04-10 00:39:10 +0000607 // Infer a submodule with the same name as this header file.
608 SmallString<32> NameBuf;
609 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000610 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000611 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
612 Explicit).first;
613 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000614 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000615 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000616
Ben Langmuir44691382014-04-10 00:39:10 +0000617 // If inferred submodules export everything they import, add a
618 // wildcard to the set of exports.
619 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000620 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000621 } else {
622 // Record each of the directories we stepped through as being part of
623 // the module we found, since the umbrella header covers them all.
624 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
625 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000626 }
Ben Langmuir44691382014-04-10 00:39:10 +0000627
Richard Smith386bb072015-08-18 23:42:23 +0000628 KnownHeader Header(Result, NormalHeader);
629 Headers[File].push_back(Header);
630 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000631 }
Richard Smith306d8922014-10-22 23:50:56 +0000632
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +0000633 return {};
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000634}
635
Richard Smith386bb072015-08-18 23:42:23 +0000636ArrayRef<ModuleMap::KnownHeader>
637ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
Richard Smith040e1262017-06-02 01:55:39 +0000638 resolveHeaderDirectives(File);
Richard Smith386bb072015-08-18 23:42:23 +0000639 auto It = Headers.find(File);
640 if (It == Headers.end())
641 return None;
642 return It->second;
643}
644
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000645bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000646 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000647}
648
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000649bool
650ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
651 const Module *RequestingModule) const {
Richard Smith040e1262017-06-02 01:55:39 +0000652 resolveHeaderDirectives(Header);
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000653 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000654 if (Known != Headers.end()) {
655 for (SmallVectorImpl<KnownHeader>::const_iterator
656 I = Known->second.begin(),
657 E = Known->second.end();
658 I != E; ++I) {
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000659
660 if (I->isAvailable() &&
661 (!RequestingModule ||
662 I->getModule()->isSubModuleOf(RequestingModule))) {
663 // When no requesting module is available, the caller is looking if a
664 // header is part a module by only looking into the module map. This is
665 // done by warn_uncovered_module_header checks; don't consider textual
666 // headers part of it in this mode, otherwise we get misleading warnings
667 // that a umbrella header is not including a textual header.
668 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
669 continue;
Daniel Jasper97da9172013-10-22 08:09:47 +0000670 return false;
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000671 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000672 }
673 return true;
674 }
Richard Smith50996ce2014-04-08 13:13:04 +0000675
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000676 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000677 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000678 StringRef DirName = Dir->getName();
679
Richard Smith50996ce2014-04-08 13:13:04 +0000680 auto IsUnavailable = [&](const Module *M) {
681 return !M->isAvailable() && (!RequestingModule ||
682 M->isSubModuleOf(RequestingModule));
683 };
684
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000685 // Keep walking up the directory hierarchy, looking for a directory with
686 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000687 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000688 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000689 = UmbrellaDirs.find(Dir);
690 if (KnownDir != UmbrellaDirs.end()) {
691 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000692 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000693 return true;
694
695 // Search up the module stack until we find a module with an umbrella
696 // directory.
697 Module *UmbrellaModule = Found;
698 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
699 UmbrellaModule = UmbrellaModule->Parent;
700
701 if (UmbrellaModule->InferSubmodules) {
702 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
703 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000704 SmallString<32> NameBuf;
705 StringRef Name = sanitizeFilenameAsIdentifier(
706 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
707 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000708 Found = lookupModuleQualified(Name, Found);
709 if (!Found)
710 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000711 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000712 return true;
713 }
714
715 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000716 SmallString<32> NameBuf;
717 StringRef Name = sanitizeFilenameAsIdentifier(
718 llvm::sys::path::stem(Header->getName()),
719 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000720 Found = lookupModuleQualified(Name, Found);
721 if (!Found)
722 return false;
723 }
724
Richard Smith50996ce2014-04-08 13:13:04 +0000725 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000726 }
727
728 SkippedDirs.push_back(Dir);
729
730 // Retrieve our parent path.
731 DirName = llvm::sys::path::parent_path(DirName);
732 if (DirName.empty())
733 break;
734
735 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000736 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000737 } while (Dir);
738
739 return false;
740}
741
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000742Module *ModuleMap::findModule(StringRef Name) const {
743 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000744 if (Known != Modules.end())
745 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000746
747 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000748}
749
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000750Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
751 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000752 for(; Context; Context = Context->Parent) {
753 if (Module *Sub = lookupModuleQualified(Name, Context))
754 return Sub;
755 }
756
757 return findModule(Name);
758}
759
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000760Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000761 if (!Context)
762 return findModule(Name);
763
Douglas Gregoreb90e832012-01-04 23:32:19 +0000764 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000765}
766
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +0000767std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
768 Module *Parent,
769 bool IsFramework,
770 bool IsExplicit) {
Douglas Gregor69021972011-11-30 17:33:56 +0000771 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000772 if (Module *Sub = lookupModuleQualified(Name, Parent))
773 return std::make_pair(Sub, false);
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +0000774
Douglas Gregor69021972011-11-30 17:33:56 +0000775 // Create a new module with this name.
David Blaikie9ffe5a32017-01-30 05:00:26 +0000776 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
777 IsExplicit, NumCreatedModules++);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000778 if (!Parent) {
Richard Smith7e82e012016-02-19 22:25:36 +0000779 if (LangOpts.CurrentModule == Name)
780 SourceModule = Result;
Douglas Gregor69021972011-11-30 17:33:56 +0000781 Modules[Name] = Result;
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +0000782 ModuleScopeIDs[Result] = CurrentModuleScopeID;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000783 }
Douglas Gregor69021972011-11-30 17:33:56 +0000784 return std::make_pair(Result, true);
785}
786
Richard Smithdd8b5332017-09-04 05:37:53 +0000787Module *ModuleMap::createGlobalModuleForInterfaceUnit(SourceLocation Loc) {
Richard Smith056bf772017-09-05 21:46:22 +0000788 assert(!PendingGlobalModule && "created multiple global modules");
789 PendingGlobalModule.reset(
790 new Module("<global>", Loc, nullptr, /*IsFramework*/ false,
791 /*IsExplicit*/ true, NumCreatedModules++));
792 PendingGlobalModule->Kind = Module::GlobalModuleFragment;
793 return PendingGlobalModule.get();
Richard Smithdd8b5332017-09-04 05:37:53 +0000794}
795
Richard Smithbbcc9f02016-08-26 00:14:38 +0000796Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
Richard Smithdd8b5332017-09-04 05:37:53 +0000797 StringRef Name,
798 Module *GlobalModule) {
Richard Smithbbcc9f02016-08-26 00:14:38 +0000799 assert(LangOpts.CurrentModule == Name && "module name mismatch");
800 assert(!Modules[Name] && "redefining existing module");
801
802 auto *Result =
803 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
804 /*IsExplicit*/ false, NumCreatedModules++);
Richard Smith145e15a2017-04-24 23:12:30 +0000805 Result->Kind = Module::ModuleInterfaceUnit;
Richard Smithbbcc9f02016-08-26 00:14:38 +0000806 Modules[Name] = SourceModule = Result;
807
Richard Smithdd8b5332017-09-04 05:37:53 +0000808 // Reparent the current global module fragment as a submodule of this module.
Richard Smith056bf772017-09-05 21:46:22 +0000809 assert(GlobalModule == PendingGlobalModule.get() &&
810 "unexpected global module");
Richard Smithdd8b5332017-09-04 05:37:53 +0000811 GlobalModule->setParent(Result);
Richard Smith056bf772017-09-05 21:46:22 +0000812 PendingGlobalModule.release(); // now owned by parent
Richard Smithdd8b5332017-09-04 05:37:53 +0000813
Richard Smithbbcc9f02016-08-26 00:14:38 +0000814 // Mark the main source file as being within the newly-created module so that
815 // declarations and macros are properly visibility-restricted to it.
816 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
817 assert(MainFile && "no input file for module interface");
818 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
819
820 return Result;
821}
822
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000823/// \brief For a framework module, infer the framework against which we
824/// should link.
825static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
826 FileManager &FileMgr) {
827 assert(Mod->IsFramework && "Can only infer linking for framework modules");
828 assert(!Mod->isSubFramework() &&
829 "Can only infer linking for top-level frameworks");
830
831 SmallString<128> LibName;
832 LibName += FrameworkDir->getName();
833 llvm::sys::path::append(LibName, Mod->Name);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000834
835 // The library name of a framework has more than one possible extension since
836 // the introduction of the text-based dynamic library format. We need to check
837 // for both before we give up.
Benjamin Kramer8013e812016-11-15 18:56:39 +0000838 for (const char *extension : {"", ".tbd"}) {
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000839 llvm::sys::path::replace_extension(LibName, extension);
840 if (FileMgr.getFile(LibName)) {
841 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
842 /*IsFramework=*/true));
843 return;
844 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000845 }
846}
847
Ben Langmuira5254002015-07-02 13:19:48 +0000848Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
849 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000850 Attributes Attrs;
851 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000852 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000853}
854
Ben Langmuira5254002015-07-02 13:19:48 +0000855Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000856 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000857 // Note: as an egregious but useful hack we use the real path here, because
858 // we might be looking at an embedded framework that symlinks out to a
859 // top-level framework, and we need to infer as if we were naming the
860 // top-level framework.
861 StringRef FrameworkDirName =
862 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
863
864 // In case this is a case-insensitive filesystem, use the canonical
865 // directory name as the ModuleName, since modules are case-sensitive.
866 // FIXME: we should be able to give a fix-it hint for the correct spelling.
867 SmallString<32> ModuleNameStorage;
868 StringRef ModuleName = sanitizeFilenameAsIdentifier(
869 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000870
Douglas Gregor56c64012011-11-17 01:41:17 +0000871 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000872 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
873 return Mod;
874
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000875 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000876
877 // If the framework has a parent path from which we're allowed to infer
878 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000879 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000880 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000881 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000882 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000883 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000884 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000885 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000886 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
887 // Check whether we have already looked into the parent directory
888 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000889 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000890 inferred = InferredDirectories.find(ParentDir);
891 if (inferred == InferredDirectories.end()) {
892 // We haven't looked here before. Load a module map, if there is
893 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000894 bool IsFrameworkDir = Parent.endswith(".framework");
895 if (const FileEntry *ModMapFile =
896 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000897 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000898 inferred = InferredDirectories.find(ParentDir);
899 }
900
901 if (inferred == InferredDirectories.end())
902 inferred = InferredDirectories.insert(
903 std::make_pair(ParentDir, InferredDirectory())).first;
904 }
905
906 if (inferred->second.InferModules) {
907 // We're allowed to infer for this directory, but make sure it's okay
908 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000909 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000910 canInfer = std::find(inferred->second.ExcludedModules.begin(),
911 inferred->second.ExcludedModules.end(),
912 Name) == inferred->second.ExcludedModules.end();
913
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000914 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
915 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
916 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000917 Attrs.NoUndeclaredIncludes |=
918 inferred->second.Attrs.NoUndeclaredIncludes;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000919 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000920 }
921 }
922 }
923
924 // If we're not allowed to infer a framework module, don't.
925 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000926 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000927 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000928 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000929
930
Douglas Gregor56c64012011-11-17 01:41:17 +0000931 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000932 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000933 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000934 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000935
936 // FIXME: If there's no umbrella header, we could probably scan the
937 // framework to load *everything*. But, it's not clear that this is a good
938 // idea.
939 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000940 return nullptr;
941
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000942 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000943 /*IsFramework=*/true, /*IsExplicit=*/false,
944 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000945 InferredModuleAllowedBy[Result] = ModuleMapFile;
946 Result->IsInferred = true;
Richard Smith7e82e012016-02-19 22:25:36 +0000947 if (!Parent) {
948 if (LangOpts.CurrentModule == ModuleName)
949 SourceModule = Result;
950 Modules[ModuleName] = Result;
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +0000951 ModuleScopeIDs[Result] = CurrentModuleScopeID;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000952 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000953
954 Result->IsSystem |= Attrs.IsSystem;
955 Result->IsExternC |= Attrs.IsExternC;
956 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000957 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Richard Smith2b63d152015-05-16 02:28:53 +0000958 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000959
Douglas Gregor322f6332011-12-08 18:00:48 +0000960 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000961 //
962 // The "Headers/" component of the name is implied because this is
963 // a framework module.
964 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000965
966 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000967 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
968
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000969 // module * { export * }
970 Result->InferSubmodules = true;
971 Result->InferExportWildcard = true;
972
Douglas Gregore89dbc12011-12-06 19:39:29 +0000973 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000974 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000975 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000976 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000977 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000978 llvm::sys::path::native(SubframeworksDirName);
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000979 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
980 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
981 DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000982 Dir != DirEnd && !EC; Dir.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000983 if (!StringRef(Dir->getName()).endswith(".framework"))
Douglas Gregore89dbc12011-12-06 19:39:29 +0000984 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000985
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000986 if (const DirectoryEntry *SubframeworkDir =
987 FileMgr.getDirectory(Dir->getName())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000988 // Note: as an egregious but useful hack, we use the real path here and
989 // check whether it is actually a subdirectory of the parent directory.
990 // This will not be the case if the 'subframework' is actually a symlink
991 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000992 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
993 bool FoundParent = false;
994 do {
995 // Get the parent directory name.
996 SubframeworkDirName
997 = llvm::sys::path::parent_path(SubframeworkDirName);
998 if (SubframeworkDirName.empty())
999 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +00001000
Douglas Gregore00c8b22013-01-26 00:55:12 +00001001 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
1002 FoundParent = true;
1003 break;
1004 }
1005 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +00001006
Douglas Gregore00c8b22013-01-26 00:55:12 +00001007 if (!FoundParent)
1008 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +00001009
Douglas Gregore89dbc12011-12-06 19:39:29 +00001010 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +00001011 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +00001012 }
1013 }
Douglas Gregor09a22f02012-01-13 16:54:27 +00001014
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001015 // If the module is a top-level framework, automatically link against the
1016 // framework.
1017 if (!Result->isSubFramework()) {
1018 inferFrameworkLink(Result, FrameworkDir, FileMgr);
1019 }
1020
Douglas Gregor56c64012011-11-17 01:41:17 +00001021 return Result;
1022}
1023
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001024Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
1025 Module *ShadowingModule) {
1026
1027 // Create a new module with this name.
1028 Module *Result =
1029 new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
1030 /*IsExplicit=*/false, NumCreatedModules++);
1031 Result->ShadowingModule = ShadowingModule;
1032 Result->IsAvailable = false;
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00001033 ModuleScopeIDs[Result] = CurrentModuleScopeID;
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001034 ShadowModules.push_back(Result);
1035
1036 return Result;
1037}
1038
Richard Smith2b63d152015-05-16 02:28:53 +00001039void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
1040 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001041 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +00001042 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +00001043 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +00001044 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Bruno Cardoso Lopesb3a0fa42016-05-13 22:21:51 +00001045
1046 // Notify callbacks that we just added a new header.
1047 for (const auto &Cb : Callbacks)
1048 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
Douglas Gregora89c5ac2011-12-06 01:10:29 +00001049}
1050
Richard Smith2b63d152015-05-16 02:28:53 +00001051void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
1052 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +00001053 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +00001054 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +00001055 UmbrellaDirs[UmbrellaDir] = Mod;
1056}
1057
Richard Smith040e1262017-06-02 01:55:39 +00001058void ModuleMap::addUnresolvedHeader(Module *Mod,
1059 Module::UnresolvedHeaderDirective Header) {
1060 // If there is a builtin counterpart to this file, add it now so it can
1061 // wrap the system header.
1062 if (resolveAsBuiltinHeader(Mod, Header)) {
1063 // If we have both a builtin and system version of the file, the
1064 // builtin version may want to inject macros into the system header, so
1065 // force the system header to be treated as a textual header in this
1066 // case.
1067 Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
1068 headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
1069 Header.HasBuiltinHeader = true;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +00001070 }
Richard Smith040e1262017-06-02 01:55:39 +00001071
1072 // If possible, don't stat the header until we need to. This requires the
1073 // user to have provided us with some stat information about the file.
1074 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1075 // headers.
1076 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1077 Header.Kind != Module::HK_Excluded) {
1078 // We expect more variation in mtime than size, so if we're given both,
1079 // use the mtime as the key.
1080 if (Header.ModTime)
1081 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1082 else
1083 LazyHeadersBySize[*Header.Size].push_back(Mod);
1084 Mod->UnresolvedHeaders.push_back(Header);
1085 return;
1086 }
1087
1088 // We don't have stat information or can't defer looking this file up.
1089 // Perform the lookup now.
1090 resolveHeader(Mod, Header);
1091}
1092
1093void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
1094 auto BySize = LazyHeadersBySize.find(File->getSize());
1095 if (BySize != LazyHeadersBySize.end()) {
1096 for (auto *M : BySize->second)
1097 resolveHeaderDirectives(M);
1098 LazyHeadersBySize.erase(BySize);
1099 }
1100
1101 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1102 if (ByModTime != LazyHeadersByModTime.end()) {
1103 for (auto *M : ByModTime->second)
1104 resolveHeaderDirectives(M);
1105 LazyHeadersByModTime.erase(ByModTime);
1106 }
1107}
1108
1109void ModuleMap::resolveHeaderDirectives(Module *Mod) const {
1110 for (auto &Header : Mod->UnresolvedHeaders)
1111 // This operation is logically const; we're just changing how we represent
1112 // the header information for this file.
1113 const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header);
1114 Mod->UnresolvedHeaders.clear();
Douglas Gregora89c5ac2011-12-06 01:10:29 +00001115}
1116
Richard Smith3c1a41a2014-12-02 00:08:08 +00001117void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +00001118 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +00001119 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +00001120
Richard Smith386bb072015-08-18 23:42:23 +00001121 // Only add each header to the headers list once.
1122 // FIXME: Should we diagnose if a header is listed twice in the
1123 // same module definition?
1124 auto &HeaderList = Headers[Header.Entry];
1125 for (auto H : HeaderList)
1126 if (H == KH)
1127 return;
1128
1129 HeaderList.push_back(KH);
Piotr Padlewski1ec383c2016-12-23 11:40:44 +00001130 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
Richard Smith386bb072015-08-18 23:42:23 +00001131
Richard Smith7e82e012016-02-19 22:25:36 +00001132 bool isCompilingModuleHeader =
Richard Smithbbcc9f02016-08-26 00:14:38 +00001133 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
Richard Smithd8879c82015-08-24 21:59:32 +00001134 if (!Imported || isCompilingModuleHeader) {
1135 // When we import HeaderFileInfo, the external source is expected to
1136 // set the isModuleHeader flag itself.
1137 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
1138 isCompilingModuleHeader);
1139 }
Bruno Cardoso Lopese62cfd72016-03-30 23:54:25 +00001140
1141 // Notify callbacks that we just added a new header.
1142 for (const auto &Cb : Callbacks)
Bruno Cardoso Lopesf0841792016-05-06 23:21:50 +00001143 Cb->moduleMapAddHeader(Header.Entry->getName());
Richard Smith3c1a41a2014-12-02 00:08:08 +00001144}
1145
1146void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +00001147 // Add this as a known header so we won't implicitly add it to any
1148 // umbrella directory module.
1149 // FIXME: Should we only exclude it from umbrella modules within the
1150 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +00001151 (void) Headers[Header.Entry];
1152
1153 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +00001154}
1155
Douglas Gregor514b6362011-11-29 19:06:37 +00001156const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001157ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00001158 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +00001159 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +00001160
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00001161 return SourceMgr.getFileEntryForID(
1162 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +00001163}
1164
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001165const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001166 if (M->IsInferred) {
1167 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1168 return InferredModuleAllowedBy.find(M)->second;
1169 }
1170 return getContainingModuleMapFile(M);
1171}
1172
1173void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
1174 assert(M->IsInferred && "module not inferred");
1175 InferredModuleAllowedBy[M] = ModMap;
1176}
1177
Yaron Kerencdae9412016-01-29 19:38:18 +00001178LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +00001179 llvm::errs() << "Modules:";
1180 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1181 MEnd = Modules.end();
1182 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +00001183 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +00001184
1185 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +00001186 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +00001187 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001188 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
1189 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1190 E = H->second.end();
1191 I != E; ++I) {
1192 if (I != H->second.begin())
1193 llvm::errs() << ",";
1194 llvm::errs() << I->getModule()->getFullModuleName();
1195 }
1196 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +00001197 }
1198}
1199
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001200bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001201 auto Unresolved = std::move(Mod->UnresolvedExports);
1202 Mod->UnresolvedExports.clear();
1203 for (auto &UE : Unresolved) {
1204 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001205 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001206 Mod->Exports.push_back(Export);
1207 else
Richard Smith42413142015-05-15 20:05:43 +00001208 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001209 }
Richard Smith42413142015-05-15 20:05:43 +00001210 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001211}
1212
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001213bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001214 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
1215 Mod->UnresolvedDirectUses.clear();
1216 for (auto &UDU : Unresolved) {
1217 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001218 if (DirectUse)
1219 Mod->DirectUses.push_back(DirectUse);
1220 else
Richard Smith42413142015-05-15 20:05:43 +00001221 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001222 }
Richard Smith42413142015-05-15 20:05:43 +00001223 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001224}
1225
Douglas Gregorfb912652013-03-20 21:10:35 +00001226bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001227 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +00001228 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +00001229 for (auto &UC : Unresolved) {
1230 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1231 Module::Conflict Conflict;
1232 Conflict.Other = OtherMod;
1233 Conflict.Message = UC.Message;
1234 Mod->Conflicts.push_back(Conflict);
1235 } else
1236 Mod->UnresolvedConflicts.push_back(UC);
1237 }
1238 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +00001239}
1240
Douglas Gregor718292f2011-11-11 19:10:28 +00001241//----------------------------------------------------------------------------//
1242// Module map file parser
1243//----------------------------------------------------------------------------//
1244
1245namespace clang {
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001246
Douglas Gregor718292f2011-11-11 19:10:28 +00001247 /// \brief A token in a module map file.
1248 struct MMToken {
1249 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001250 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001251 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +00001252 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +00001253 EndOfFile,
1254 HeaderKeyword,
1255 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +00001256 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +00001257 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001258 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001259 ExportKeyword,
Douglas Gregorf0b11de2017-09-14 23:38:44 +00001260 ExportAsKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +00001261 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +00001262 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001263 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001264 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001265 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001266 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001267 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001268 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001269 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001270 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +00001271 StringLiteral,
Richard Smith040e1262017-06-02 01:55:39 +00001272 IntegerLiteral,
Richard Smith306d8922014-10-22 23:50:56 +00001273 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001274 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +00001275 RBrace,
1276 LSquare,
1277 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +00001278 } Kind;
1279
1280 unsigned Location;
1281 unsigned StringLength;
Richard Smith040e1262017-06-02 01:55:39 +00001282 union {
1283 // If Kind != IntegerLiteral.
1284 const char *StringData;
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001285
Richard Smith040e1262017-06-02 01:55:39 +00001286 // If Kind == IntegerLiteral.
1287 uint64_t IntegerValue;
1288 };
Douglas Gregor718292f2011-11-11 19:10:28 +00001289
1290 void clear() {
1291 Kind = EndOfFile;
1292 Location = 0;
1293 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +00001294 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +00001295 }
1296
1297 bool is(TokenKind K) const { return Kind == K; }
1298
1299 SourceLocation getLocation() const {
1300 return SourceLocation::getFromRawEncoding(Location);
1301 }
Richard Smith040e1262017-06-02 01:55:39 +00001302
1303 uint64_t getInteger() const {
1304 return Kind == IntegerLiteral ? IntegerValue : 0;
1305 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001306
1307 StringRef getString() const {
Richard Smith040e1262017-06-02 01:55:39 +00001308 return Kind == IntegerLiteral ? StringRef()
1309 : StringRef(StringData, StringLength);
Douglas Gregor718292f2011-11-11 19:10:28 +00001310 }
1311 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001312
Douglas Gregor718292f2011-11-11 19:10:28 +00001313 class ModuleMapParser {
1314 Lexer &L;
1315 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001316
1317 /// \brief Default target information, used only for string literal
1318 /// parsing.
1319 const TargetInfo *Target;
1320
Douglas Gregor718292f2011-11-11 19:10:28 +00001321 DiagnosticsEngine &Diags;
1322 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001323
1324 /// \brief The current module map file.
1325 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001326
Richard Smith9acb99e32014-12-10 03:09:48 +00001327 /// \brief The directory that file names in this module map file should
1328 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001329 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001330
Douglas Gregor963c5532013-06-21 16:28:10 +00001331 /// \brief Whether this module map is in a system header directory.
1332 bool IsSystem;
1333
Douglas Gregor718292f2011-11-11 19:10:28 +00001334 /// \brief Whether an error occurred.
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001335 bool HadError = false;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001336
Douglas Gregor718292f2011-11-11 19:10:28 +00001337 /// \brief Stores string data for the various string literals referenced
1338 /// during parsing.
1339 llvm::BumpPtrAllocator StringData;
1340
1341 /// \brief The current token.
1342 MMToken Tok;
1343
1344 /// \brief The active module.
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001345 Module *ActiveModule = nullptr;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001346
1347 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1348 /// contents as 'textual'.
1349 ///
1350 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1351 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1352 /// non-modular headers. For backwards compatibility, we continue to
1353 /// support this idiom for just these modules, and map the headers to
1354 /// 'textual' to match the original intent.
1355 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1356
Douglas Gregor718292f2011-11-11 19:10:28 +00001357 /// \brief Consume the current token and return its location.
1358 SourceLocation consumeToken();
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001359
Douglas Gregor718292f2011-11-11 19:10:28 +00001360 /// \brief Skip tokens until we reach the a token with the given kind
1361 /// (or the end of the file).
1362 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001363
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001364 using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
1365
Douglas Gregore7ab3662011-12-07 02:23:45 +00001366 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001367 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001368 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001369 void parseRequiresDecl();
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001370 void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001371 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001372 void parseExportDecl();
Douglas Gregorf0b11de2017-09-14 23:38:44 +00001373 void parseExportAsDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001374 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001375 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001376 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001377 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001378 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001379
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001380 using Attributes = ModuleMap::Attributes;
1381
Bill Wendling44426052012-12-20 19:22:21 +00001382 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001383
Douglas Gregor718292f2011-11-11 19:10:28 +00001384 public:
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001385 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1386 const TargetInfo *Target, DiagnosticsEngine &Diags,
1387 ModuleMap &Map, const FileEntry *ModuleMapFile,
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00001388 const DirectoryEntry *Directory, bool IsSystem)
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001389 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1390 ModuleMapFile(ModuleMapFile), Directory(Directory),
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00001391 IsSystem(IsSystem) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001392 Tok.clear();
1393 consumeToken();
1394 }
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001395
Douglas Gregor718292f2011-11-11 19:10:28 +00001396 bool parseModuleMapFile();
Richard Smith8128f332017-05-05 22:18:51 +00001397
1398 bool terminatedByDirective() { return false; }
1399 SourceLocation getLocation() { return Tok.getLocation(); }
Douglas Gregor718292f2011-11-11 19:10:28 +00001400 };
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001401
1402} // namespace clang
Douglas Gregor718292f2011-11-11 19:10:28 +00001403
1404SourceLocation ModuleMapParser::consumeToken() {
Douglas Gregor718292f2011-11-11 19:10:28 +00001405 SourceLocation Result = Tok.getLocation();
Richard Smith8128f332017-05-05 22:18:51 +00001406
1407retry:
Douglas Gregor718292f2011-11-11 19:10:28 +00001408 Tok.clear();
Douglas Gregor718292f2011-11-11 19:10:28 +00001409 Token LToken;
1410 L.LexFromRawLexer(LToken);
1411 Tok.Location = LToken.getLocation().getRawEncoding();
1412 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001413 case tok::raw_identifier: {
1414 StringRef RI = LToken.getRawIdentifier();
1415 Tok.StringData = RI.data();
1416 Tok.StringLength = RI.size();
1417 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001418 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001419 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001420 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001421 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001422 .Case("export", MMToken::ExportKeyword)
Douglas Gregorf0b11de2017-09-14 23:38:44 +00001423 .Case("export_as", MMToken::ExportAsKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001424 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001425 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001426 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001427 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001428 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001429 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001430 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001431 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001432 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001433 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001434 .Default(MMToken::Identifier);
1435 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001436 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001437
1438 case tok::comma:
1439 Tok.Kind = MMToken::Comma;
1440 break;
1441
Douglas Gregor718292f2011-11-11 19:10:28 +00001442 case tok::eof:
1443 Tok.Kind = MMToken::EndOfFile;
1444 break;
1445
1446 case tok::l_brace:
1447 Tok.Kind = MMToken::LBrace;
1448 break;
1449
Douglas Gregora686e1b2012-01-27 19:52:33 +00001450 case tok::l_square:
1451 Tok.Kind = MMToken::LSquare;
1452 break;
1453
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001454 case tok::period:
1455 Tok.Kind = MMToken::Period;
1456 break;
1457
Douglas Gregor718292f2011-11-11 19:10:28 +00001458 case tok::r_brace:
1459 Tok.Kind = MMToken::RBrace;
1460 break;
1461
Douglas Gregora686e1b2012-01-27 19:52:33 +00001462 case tok::r_square:
1463 Tok.Kind = MMToken::RSquare;
1464 break;
1465
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001466 case tok::star:
1467 Tok.Kind = MMToken::Star;
1468 break;
1469
Richard Smitha3feee22013-10-28 22:18:19 +00001470 case tok::exclaim:
1471 Tok.Kind = MMToken::Exclaim;
1472 break;
1473
Douglas Gregor718292f2011-11-11 19:10:28 +00001474 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001475 if (LToken.hasUDSuffix()) {
1476 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1477 HadError = true;
1478 goto retry;
1479 }
1480
Douglas Gregor718292f2011-11-11 19:10:28 +00001481 // Parse the string literal.
1482 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001483 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001484 if (StringLiteral.hadError)
1485 goto retry;
1486
1487 // Copy the string literal into our string data allocator.
1488 unsigned Length = StringLiteral.GetStringLength();
1489 char *Saved = StringData.Allocate<char>(Length + 1);
1490 memcpy(Saved, StringLiteral.GetString().data(), Length);
1491 Saved[Length] = 0;
1492
1493 // Form the token.
1494 Tok.Kind = MMToken::StringLiteral;
1495 Tok.StringData = Saved;
1496 Tok.StringLength = Length;
1497 break;
1498 }
Richard Smith040e1262017-06-02 01:55:39 +00001499
1500 case tok::numeric_constant: {
1501 // We don't support any suffixes or other complications.
1502 SmallString<32> SpellingBuffer;
1503 SpellingBuffer.resize(LToken.getLength() + 1);
1504 const char *Start = SpellingBuffer.data();
1505 unsigned Length =
1506 Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts());
1507 uint64_t Value;
1508 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1509 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1510 HadError = true;
1511 goto retry;
1512 }
1513
1514 Tok.Kind = MMToken::IntegerLiteral;
1515 Tok.IntegerValue = Value;
1516 break;
1517 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001518
1519 case tok::comment:
1520 goto retry;
Richard Smith8128f332017-05-05 22:18:51 +00001521
1522 case tok::hash:
1523 // A module map can be terminated prematurely by
1524 // #pragma clang module contents
1525 // When building the module, we'll treat the rest of the file as the
1526 // contents of the module.
1527 {
1528 auto NextIsIdent = [&](StringRef Str) -> bool {
1529 L.LexFromRawLexer(LToken);
1530 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1531 LToken.getRawIdentifier() == Str;
1532 };
1533 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1534 NextIsIdent("module") && NextIsIdent("contents")) {
1535 Tok.Kind = MMToken::EndOfFile;
1536 break;
1537 }
1538 }
1539 LLVM_FALLTHROUGH;
1540
Douglas Gregor718292f2011-11-11 19:10:28 +00001541 default:
Richard Smith8128f332017-05-05 22:18:51 +00001542 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
Douglas Gregor718292f2011-11-11 19:10:28 +00001543 HadError = true;
1544 goto retry;
1545 }
1546
1547 return Result;
1548}
1549
1550void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1551 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001552 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001553 do {
1554 switch (Tok.Kind) {
1555 case MMToken::EndOfFile:
1556 return;
1557
1558 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001559 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001560 return;
1561
1562 ++braceDepth;
1563 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001564
1565 case MMToken::LSquare:
1566 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1567 return;
1568
1569 ++squareDepth;
1570 break;
1571
Douglas Gregor718292f2011-11-11 19:10:28 +00001572 case MMToken::RBrace:
1573 if (braceDepth > 0)
1574 --braceDepth;
1575 else if (Tok.is(K))
1576 return;
1577 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001578
1579 case MMToken::RSquare:
1580 if (squareDepth > 0)
1581 --squareDepth;
1582 else if (Tok.is(K))
1583 return;
1584 break;
1585
Douglas Gregor718292f2011-11-11 19:10:28 +00001586 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001587 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001588 return;
1589 break;
1590 }
1591
1592 consumeToken();
1593 } while (true);
1594}
1595
Douglas Gregore7ab3662011-12-07 02:23:45 +00001596/// \brief Parse a module-id.
1597///
1598/// module-id:
1599/// identifier
1600/// identifier '.' module-id
1601///
1602/// \returns true if an error occurred, false otherwise.
1603bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1604 Id.clear();
1605 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001606 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001607 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1608 consumeToken();
1609 } else {
1610 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1611 return true;
1612 }
1613
1614 if (!Tok.is(MMToken::Period))
1615 break;
1616
1617 consumeToken();
1618 } while (true);
1619
1620 return false;
1621}
1622
Douglas Gregora686e1b2012-01-27 19:52:33 +00001623namespace {
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001624
Douglas Gregora686e1b2012-01-27 19:52:33 +00001625 /// \brief Enumerates the known attributes.
1626 enum AttributeKind {
1627 /// \brief An unknown attribute.
1628 AT_unknown,
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001629
Douglas Gregora686e1b2012-01-27 19:52:33 +00001630 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001631 AT_system,
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001632
Richard Smith77944862014-03-02 05:58:18 +00001633 /// \brief The 'extern_c' attribute.
1634 AT_extern_c,
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001635
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001636 /// \brief The 'exhaustive' attribute.
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001637 AT_exhaustive,
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001638
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001639 /// \brief The 'no_undeclared_includes' attribute.
1640 AT_no_undeclared_includes
Douglas Gregora686e1b2012-01-27 19:52:33 +00001641 };
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00001642
1643} // namespace
Douglas Gregora686e1b2012-01-27 19:52:33 +00001644
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001645/// Private modules are canonicalized as Foo_Private. Clang provides extra
1646/// module map search logic to find the appropriate private module when PCH
1647/// is used with implicit module maps. Warn when private modules are written
1648/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1649static void diagnosePrivateModules(const ModuleMap &Map,
1650 DiagnosticsEngine &Diags,
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001651 const Module *ActiveModule,
1652 SourceLocation InlineParent) {
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001653
1654 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001655 const Module *M, SourceRange ReplLoc) {
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001656 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1657 diag::note_mmap_rename_top_level_private_module);
1658 D << BadName << M->Name;
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001659 D << FixItHint::CreateReplacement(ReplLoc, Canonical);
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001660 };
1661
1662 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1663 auto const *M = E->getValue();
1664 if (M->Directory != ActiveModule->Directory)
1665 continue;
1666
1667 SmallString<128> FullName(ActiveModule->getFullModuleName());
1668 if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
1669 continue;
1670 SmallString<128> Canonical(M->Name);
1671 Canonical.append("_Private");
1672
1673 // Foo.Private -> Foo_Private
1674 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1675 M->Name == ActiveModule->Parent->Name) {
1676 Diags.Report(ActiveModule->DefinitionLoc,
1677 diag::warn_mmap_mismatched_private_submodule)
1678 << FullName;
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001679 GenNoteAndFixIt(FullName, Canonical, M,
1680 SourceRange(InlineParent, ActiveModule->DefinitionLoc));
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001681 continue;
1682 }
1683
1684 // FooPrivate and whatnots -> Foo_Private
1685 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1686 ActiveModule->Name != Canonical) {
1687 Diags.Report(ActiveModule->DefinitionLoc,
1688 diag::warn_mmap_mismatched_private_module_name)
1689 << ActiveModule->Name;
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001690 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1691 SourceRange(ActiveModule->DefinitionLoc));
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001692 }
1693 }
1694}
1695
Douglas Gregor718292f2011-11-11 19:10:28 +00001696/// \brief Parse a module declaration.
1697///
1698/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001699/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001700/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1701/// { module-member* }
1702///
Douglas Gregor718292f2011-11-11 19:10:28 +00001703/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001704/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001705/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001706/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001707/// export-declaration
Douglas Gregorf0b11de2017-09-14 23:38:44 +00001708/// export-as-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001709/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001710///
1711/// submodule-declaration:
1712/// module-declaration
1713/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001714void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001715 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001716 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1717 if (Tok.is(MMToken::ExternKeyword)) {
1718 parseExternModuleDecl();
1719 return;
1720 }
1721
Douglas Gregorf2161a72011-12-06 17:16:41 +00001722 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001723 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001724 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001725 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001726
Douglas Gregorf2161a72011-12-06 17:16:41 +00001727 // Parse 'explicit' keyword, if present.
1728 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001729 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001730 Explicit = true;
1731 }
1732
1733 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001734 if (Tok.is(MMToken::FrameworkKeyword)) {
1735 consumeToken();
1736 Framework = true;
1737 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001738
1739 // Parse 'module' keyword.
1740 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001741 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001742 consumeToken();
1743 HadError = true;
1744 return;
1745 }
1746 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001747
1748 // If we have a wildcard for the module name, this is an inferred submodule.
1749 // Parse it.
1750 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001751 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001752
1753 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001754 ModuleId Id;
1755 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001756 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001757 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001758 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001759
Douglas Gregore7ab3662011-12-07 02:23:45 +00001760 if (ActiveModule) {
1761 if (Id.size() > 1) {
1762 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1763 << SourceRange(Id.front().second, Id.back().second);
1764
1765 HadError = true;
1766 return;
1767 }
1768 } else if (Id.size() == 1 && Explicit) {
1769 // Top-level modules can't be explicit.
1770 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1771 Explicit = false;
1772 ExplicitLoc = SourceLocation();
1773 HadError = true;
1774 }
1775
1776 Module *PreviousActiveModule = ActiveModule;
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001777 SourceLocation LastInlineParentLoc = SourceLocation();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001778 if (Id.size() > 1) {
1779 // This module map defines a submodule. Go find the module of which it
1780 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001781 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001782 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001783 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1784 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001785 if (I == 0)
1786 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001787 ActiveModule = Next;
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001788 LastInlineParentLoc = Id[I].second;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001789 continue;
1790 }
1791
1792 if (ActiveModule) {
1793 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001794 << Id[I].first
1795 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001796 } else {
1797 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1798 }
1799 HadError = true;
1800 return;
1801 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001802
1803 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1804 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1805 "submodule defined in same file as 'module *' that allowed its "
1806 "top-level module");
1807 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1808 }
1809 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001810
1811 StringRef ModuleName = Id.back().first;
1812 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001813
Douglas Gregora686e1b2012-01-27 19:52:33 +00001814 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001815 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00001816 if (parseOptionalAttributes(Attrs))
1817 return;
1818
Douglas Gregor718292f2011-11-11 19:10:28 +00001819 // Parse the opening brace.
1820 if (!Tok.is(MMToken::LBrace)) {
1821 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1822 << ModuleName;
1823 HadError = true;
1824 return;
1825 }
1826 SourceLocation LBraceLoc = consumeToken();
1827
1828 // Determine whether this (sub)module has already been defined.
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001829 Module *ShadowingModule = nullptr;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001830 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Richard Smith4a3751f2017-05-08 20:30:47 +00001831 // We might see a (re)definition of a module that we already have a
1832 // definition for in two cases:
1833 // - If we loaded one definition from an AST file and we've just found a
1834 // corresponding definition in a module map file, or
1835 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
1836 // - If we're building a (preprocessed) module and we've just loaded the
1837 // module map file from which it was created.
1838 bool ParsedAsMainInput =
1839 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1840 Map.LangOpts.CurrentModule == ModuleName &&
1841 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1842 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1843 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001844 // Skip the module definition.
1845 skipUntil(MMToken::RBrace);
1846 if (Tok.is(MMToken::RBrace))
1847 consumeToken();
1848 else {
1849 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1850 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1851 HadError = true;
1852 }
1853 return;
1854 }
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001855
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00001856 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001857 ShadowingModule = Existing;
1858 } else {
1859 // This is not a shawdowed module decl, it is an illegal redefinition.
1860 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1861 << ModuleName;
1862 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1863
1864 // Skip the module definition.
1865 skipUntil(MMToken::RBrace);
1866 if (Tok.is(MMToken::RBrace))
1867 consumeToken();
1868
1869 HadError = true;
1870 return;
1871 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001872 }
1873
1874 // Start defining this module.
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001875 if (ShadowingModule) {
1876 ActiveModule =
1877 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
1878 } else {
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00001879 ActiveModule =
1880 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
1881 .first;
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00001882 }
1883
Douglas Gregoreb90e832012-01-04 23:32:19 +00001884 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001885 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001886 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001887 if (Attrs.IsExternC)
1888 ActiveModule->IsExternC = true;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001889 if (Attrs.NoUndeclaredIncludes ||
1890 (!ActiveModule->Parent && ModuleName == "Darwin"))
1891 ActiveModule->NoUndeclaredIncludes = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001892 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001893
Jordan Rose90b0a1f2018-04-20 17:16:04 +00001894 StringRef MapFileName(ModuleMapFile->getName());
1895 if (MapFileName.endswith("module.private.modulemap") ||
1896 MapFileName.endswith("module_private.map")) {
1897 ActiveModule->ModuleMapIsPrivate = true;
1898 }
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001899
1900 // Private modules named as FooPrivate, Foo.Private or similar are likely a
1901 // user error; provide warnings, notes and fixits to direct users to use
1902 // Foo_Private instead.
1903 SourceLocation StartLoc =
1904 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
Bruno Cardoso Lopes297299192017-12-22 02:53:30 +00001905 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
1906 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
1907 StartLoc) &&
1908 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
1909 StartLoc) &&
Jordan Rose90b0a1f2018-04-20 17:16:04 +00001910 ActiveModule->ModuleMapIsPrivate)
Bruno Cardoso Lopes7d294862018-03-30 05:17:58 +00001911 diagnosePrivateModules(Map, Diags, ActiveModule, LastInlineParentLoc);
Graydon Hoare4d867642016-12-21 00:24:39 +00001912
Douglas Gregor718292f2011-11-11 19:10:28 +00001913 bool Done = false;
1914 do {
1915 switch (Tok.Kind) {
1916 case MMToken::EndOfFile:
1917 case MMToken::RBrace:
1918 Done = true;
1919 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001920
1921 case MMToken::ConfigMacros:
1922 parseConfigMacros();
1923 break;
1924
Douglas Gregorfb912652013-03-20 21:10:35 +00001925 case MMToken::Conflict:
1926 parseConflict();
1927 break;
1928
Douglas Gregor718292f2011-11-11 19:10:28 +00001929 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001930 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001931 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001932 case MMToken::ModuleKeyword:
1933 parseModuleDecl();
1934 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001935
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001936 case MMToken::ExportKeyword:
1937 parseExportDecl();
1938 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001939
Douglas Gregorf0b11de2017-09-14 23:38:44 +00001940 case MMToken::ExportAsKeyword:
1941 parseExportAsDecl();
1942 break;
1943
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001944 case MMToken::UseKeyword:
1945 parseUseDecl();
1946 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001947
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001948 case MMToken::RequiresKeyword:
1949 parseRequiresDecl();
1950 break;
1951
Richard Smith202210b2014-10-24 20:23:01 +00001952 case MMToken::TextualKeyword:
1953 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001954 break;
Richard Smith306d8922014-10-22 23:50:56 +00001955
Douglas Gregor524e33e2011-12-08 19:11:24 +00001956 case MMToken::UmbrellaKeyword: {
1957 SourceLocation UmbrellaLoc = consumeToken();
1958 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001959 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001960 else
1961 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001962 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001963 }
Richard Smith202210b2014-10-24 20:23:01 +00001964
1965 case MMToken::ExcludeKeyword:
1966 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001967 break;
Richard Smith202210b2014-10-24 20:23:01 +00001968
1969 case MMToken::PrivateKeyword:
1970 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001971 break;
Richard Smith202210b2014-10-24 20:23:01 +00001972
Douglas Gregor322f6332011-12-08 18:00:48 +00001973 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001974 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001975 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001976
1977 case MMToken::LinkKeyword:
1978 parseLinkDecl();
1979 break;
1980
Douglas Gregor718292f2011-11-11 19:10:28 +00001981 default:
1982 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1983 consumeToken();
1984 break;
1985 }
1986 } while (!Done);
1987
1988 if (Tok.is(MMToken::RBrace))
1989 consumeToken();
1990 else {
1991 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1992 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1993 HadError = true;
1994 }
1995
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001996 // If the active module is a top-level framework, and there are no link
1997 // libraries, automatically link against the framework.
1998 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1999 ActiveModule->LinkLibraries.empty()) {
2000 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
2001 }
2002
Ben Langmuirec8c9752014-04-18 22:07:31 +00002003 // If the module meets all requirements but is still unavailable, mark the
2004 // whole tree as unavailable to prevent it from building.
2005 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
2006 ActiveModule->Parent) {
2007 ActiveModule->getTopLevelModule()->markUnavailable();
2008 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2009 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2010 }
2011
Douglas Gregore7ab3662011-12-07 02:23:45 +00002012 // We're done parsing this module. Pop back to the previous module.
2013 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00002014}
Douglas Gregorf2161a72011-12-06 17:16:41 +00002015
Daniel Jasper97292842013-09-11 07:20:44 +00002016/// \brief Parse an extern module declaration.
2017///
2018/// extern module-declaration:
2019/// 'extern' 'module' module-id string-literal
2020void ModuleMapParser::parseExternModuleDecl() {
2021 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00002022 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00002023
2024 // Parse 'module' keyword.
2025 if (!Tok.is(MMToken::ModuleKeyword)) {
2026 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2027 consumeToken();
2028 HadError = true;
2029 return;
2030 }
2031 consumeToken(); // 'module' keyword
2032
2033 // Parse the module name.
2034 ModuleId Id;
2035 if (parseModuleId(Id)) {
2036 HadError = true;
2037 return;
2038 }
2039
2040 // Parse the referenced module map file name.
2041 if (!Tok.is(MMToken::StringLiteral)) {
2042 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2043 HadError = true;
2044 return;
2045 }
2046 std::string FileName = Tok.getString();
2047 consumeToken(); // filename
2048
2049 StringRef FileNameRef = FileName;
2050 SmallString<128> ModuleMapFileName;
2051 if (llvm::sys::path::is_relative(FileNameRef)) {
2052 ModuleMapFileName += Directory->getName();
2053 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00002054 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00002055 }
2056 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00002057 Map.parseModuleMapFile(
2058 File, /*IsSystem=*/false,
2059 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2060 ? Directory
Richard Smith8128f332017-05-05 22:18:51 +00002061 : File->getDir(),
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00002062 FileID(), nullptr, ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00002063}
2064
Ben Langmuir7ff29142015-08-13 17:13:33 +00002065/// Whether to add the requirement \p Feature to the module \p M.
2066///
2067/// This preserves backwards compatibility for two hacks in the Darwin system
2068/// module map files:
2069///
2070/// 1. The use of 'requires excluded' to make headers non-modular, which
2071/// should really be mapped to 'textual' now that we have this feature. We
2072/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
2073/// true. Later, this bit will be used to map all the headers inside this
2074/// module to 'textual'.
2075///
2076/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
2077///
2078/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
2079/// was never correct and causes issues now that we check it, so drop it.
2080static bool shouldAddRequirement(Module *M, StringRef Feature,
2081 bool &IsRequiresExcludedHack) {
Benjamin Kramer8013e812016-11-15 18:56:39 +00002082 if (Feature == "excluded" &&
2083 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
2084 M->fullModuleNameIs({"Tcl", "Private"}))) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00002085 IsRequiresExcludedHack = true;
2086 return false;
Benjamin Kramer8013e812016-11-15 18:56:39 +00002087 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00002088 return false;
2089 }
2090
2091 return true;
2092}
2093
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002094/// \brief Parse a requires declaration.
2095///
2096/// requires-declaration:
2097/// 'requires' feature-list
2098///
2099/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00002100/// feature ',' feature-list
2101/// feature
2102///
2103/// feature:
2104/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002105void ModuleMapParser::parseRequiresDecl() {
2106 assert(Tok.is(MMToken::RequiresKeyword));
2107
2108 // Parse 'requires' keyword.
2109 consumeToken();
2110
2111 // Parse the feature-list.
2112 do {
Richard Smitha3feee22013-10-28 22:18:19 +00002113 bool RequiredState = true;
2114 if (Tok.is(MMToken::Exclaim)) {
2115 RequiredState = false;
2116 consumeToken();
2117 }
2118
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002119 if (!Tok.is(MMToken::Identifier)) {
2120 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
2121 HadError = true;
2122 return;
2123 }
2124
2125 // Consume the feature name.
2126 std::string Feature = Tok.getString();
2127 consumeToken();
2128
Ben Langmuir7ff29142015-08-13 17:13:33 +00002129 bool IsRequiresExcludedHack = false;
2130 bool ShouldAddRequirement =
2131 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
2132
2133 if (IsRequiresExcludedHack)
2134 UsesRequiresExcludedHack.insert(ActiveModule);
2135
2136 if (ShouldAddRequirement) {
2137 // Add this feature.
2138 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2139 *Map.Target);
2140 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002141
2142 if (!Tok.is(MMToken::Comma))
2143 break;
2144
2145 // Consume the comma.
2146 consumeToken();
2147 } while (true);
2148}
2149
Douglas Gregor718292f2011-11-11 19:10:28 +00002150/// \brief Parse a header declaration.
2151///
2152/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00002153/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00002154/// 'private' 'textual'[opt] 'header' string-literal
2155/// 'exclude' 'header' string-literal
2156/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00002157///
2158/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002159void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
2160 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00002161 // We've already consumed the first token.
2162 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
2163 if (LeadingToken == MMToken::PrivateKeyword) {
2164 Role = ModuleMap::PrivateHeader;
2165 // 'private' may optionally be followed by 'textual'.
2166 if (Tok.is(MMToken::TextualKeyword)) {
2167 LeadingToken = Tok.Kind;
2168 consumeToken();
2169 }
2170 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00002171
Richard Smith202210b2014-10-24 20:23:01 +00002172 if (LeadingToken == MMToken::TextualKeyword)
2173 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2174
Ben Langmuir7ff29142015-08-13 17:13:33 +00002175 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2176 // Mark this header 'textual' (see doc comment for
2177 // Module::UsesRequiresExcludedHack).
2178 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2179 }
2180
Richard Smith202210b2014-10-24 20:23:01 +00002181 if (LeadingToken != MMToken::HeaderKeyword) {
2182 if (!Tok.is(MMToken::HeaderKeyword)) {
2183 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2184 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
2185 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
2186 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
2187 return;
2188 }
2189 consumeToken();
2190 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00002191
Douglas Gregor718292f2011-11-11 19:10:28 +00002192 // Parse the header name.
2193 if (!Tok.is(MMToken::StringLiteral)) {
2194 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2195 << "header";
2196 HadError = true;
2197 return;
2198 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00002199 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002200 Header.FileName = Tok.getString();
2201 Header.FileNameLoc = consumeToken();
Richard Smith1d609872017-05-26 00:01:53 +00002202 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Richard Smith040e1262017-06-02 01:55:39 +00002203 Header.Kind =
2204 (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded
2205 : Map.headerRoleToKind(Role));
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00002206
Douglas Gregor524e33e2011-12-08 19:11:24 +00002207 // Check whether we already have an umbrella.
Richard Smith1d609872017-05-26 00:01:53 +00002208 if (Header.IsUmbrella && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002209 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00002210 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00002211 HadError = true;
2212 return;
2213 }
2214
Richard Smith040e1262017-06-02 01:55:39 +00002215 // If we were given stat information, parse it so we can skip looking for
2216 // the file.
2217 if (Tok.is(MMToken::LBrace)) {
2218 SourceLocation LBraceLoc = consumeToken();
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00002219
Richard Smith040e1262017-06-02 01:55:39 +00002220 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
2221 enum Attribute { Size, ModTime, Unknown };
2222 StringRef Str = Tok.getString();
2223 SourceLocation Loc = consumeToken();
2224 switch (llvm::StringSwitch<Attribute>(Str)
2225 .Case("size", Size)
2226 .Case("mtime", ModTime)
2227 .Default(Unknown)) {
2228 case Size:
2229 if (Header.Size)
2230 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2231 if (!Tok.is(MMToken::IntegerLiteral)) {
2232 Diags.Report(Tok.getLocation(),
2233 diag::err_mmap_invalid_header_attribute_value) << Str;
2234 skipUntil(MMToken::RBrace);
2235 break;
2236 }
2237 Header.Size = Tok.getInteger();
2238 consumeToken();
2239 break;
Richard Smith3c1a41a2014-12-02 00:08:08 +00002240
Richard Smith040e1262017-06-02 01:55:39 +00002241 case ModTime:
2242 if (Header.ModTime)
2243 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2244 if (!Tok.is(MMToken::IntegerLiteral)) {
2245 Diags.Report(Tok.getLocation(),
2246 diag::err_mmap_invalid_header_attribute_value) << Str;
2247 skipUntil(MMToken::RBrace);
2248 break;
2249 }
2250 Header.ModTime = Tok.getInteger();
2251 consumeToken();
2252 break;
2253
2254 case Unknown:
2255 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2256 skipUntil(MMToken::RBrace);
2257 break;
Douglas Gregor322f6332011-12-08 18:00:48 +00002258 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00002259 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002260
Richard Smith040e1262017-06-02 01:55:39 +00002261 if (Tok.is(MMToken::RBrace))
2262 consumeToken();
2263 else {
2264 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2265 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2266 HadError = true;
2267 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00002268 }
Richard Smith040e1262017-06-02 01:55:39 +00002269
2270 Map.addUnresolvedHeader(ActiveModule, std::move(Header));
Douglas Gregor718292f2011-11-11 19:10:28 +00002271}
2272
Ben Langmuir41f81992015-08-13 17:30:07 +00002273static int compareModuleHeaders(const Module::Header *A,
2274 const Module::Header *B) {
2275 return A->NameAsWritten.compare(B->NameAsWritten);
2276}
2277
Douglas Gregor524e33e2011-12-08 19:11:24 +00002278/// \brief Parse an umbrella directory declaration.
2279///
2280/// umbrella-dir-declaration:
2281/// umbrella string-literal
2282void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
2283 // Parse the directory name.
2284 if (!Tok.is(MMToken::StringLiteral)) {
2285 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2286 << "umbrella";
2287 HadError = true;
2288 return;
2289 }
2290
2291 std::string DirName = Tok.getString();
2292 SourceLocation DirNameLoc = consumeToken();
2293
2294 // Check whether we already have an umbrella.
2295 if (ActiveModule->Umbrella) {
2296 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2297 << ActiveModule->getFullModuleName();
2298 HadError = true;
2299 return;
2300 }
2301
2302 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00002303 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002304 if (llvm::sys::path::is_absolute(DirName))
2305 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2306 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00002307 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002308 PathName = Directory->getName();
2309 llvm::sys::path::append(PathName, DirName);
2310 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2311 }
2312
2313 if (!Dir) {
Vassil Vassileva0320b92017-04-18 20:57:29 +00002314 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
Douglas Gregor524e33e2011-12-08 19:11:24 +00002315 << DirName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002316 return;
2317 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00002318
2319 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2320 // Mark this header 'textual' (see doc comment for
2321 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2322 // directory is relatively expensive, in practice this only applies to the
2323 // uncommonly used Tcl module on Darwin platforms.
2324 std::error_code EC;
2325 SmallVector<Module::Header, 6> Headers;
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002326 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2327 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002328 I != E && !EC; I.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002329 if (const FileEntry *FE =
2330 SourceMgr.getFileManager().getFile(I->getName())) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00002331
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002332 Module::Header Header = {I->getName(), FE};
Ben Langmuir7ff29142015-08-13 17:13:33 +00002333 Headers.push_back(std::move(Header));
2334 }
2335 }
2336
2337 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00002338 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2339
Ben Langmuir7ff29142015-08-13 17:13:33 +00002340 for (auto &Header : Headers)
2341 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2342 return;
2343 }
2344
Douglas Gregor524e33e2011-12-08 19:11:24 +00002345 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2346 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2347 << OwningModule->getFullModuleName();
2348 HadError = true;
2349 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002350 }
2351
Douglas Gregor524e33e2011-12-08 19:11:24 +00002352 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00002353 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00002354}
2355
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002356/// \brief Parse a module export declaration.
2357///
2358/// export-declaration:
2359/// 'export' wildcard-module-id
2360///
2361/// wildcard-module-id:
2362/// identifier
2363/// '*'
2364/// identifier '.' wildcard-module-id
2365void ModuleMapParser::parseExportDecl() {
2366 assert(Tok.is(MMToken::ExportKeyword));
2367 SourceLocation ExportLoc = consumeToken();
2368
2369 // Parse the module-id with an optional wildcard at the end.
2370 ModuleId ParsedModuleId;
2371 bool Wildcard = false;
2372 do {
Richard Smith306d8922014-10-22 23:50:56 +00002373 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002374 if (Tok.is(MMToken::Identifier)) {
2375 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
2376 Tok.getLocation()));
2377 consumeToken();
2378
2379 if (Tok.is(MMToken::Period)) {
2380 consumeToken();
2381 continue;
2382 }
2383
2384 break;
2385 }
2386
2387 if(Tok.is(MMToken::Star)) {
2388 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00002389 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002390 break;
2391 }
2392
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002393 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002394 HadError = true;
2395 return;
2396 } while (true);
2397
2398 Module::UnresolvedExportDecl Unresolved = {
2399 ExportLoc, ParsedModuleId, Wildcard
2400 };
2401 ActiveModule->UnresolvedExports.push_back(Unresolved);
2402}
2403
Douglas Gregorf0b11de2017-09-14 23:38:44 +00002404/// \brief Parse a module export_as declaration.
2405///
2406/// export-as-declaration:
2407/// 'export_as' identifier
2408void ModuleMapParser::parseExportAsDecl() {
2409 assert(Tok.is(MMToken::ExportAsKeyword));
2410 consumeToken();
2411
2412 if (!Tok.is(MMToken::Identifier)) {
2413 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2414 HadError = true;
2415 return;
2416 }
2417
2418 if (ActiveModule->Parent) {
2419 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
2420 consumeToken();
2421 return;
2422 }
2423
2424 if (!ActiveModule->ExportAsModule.empty()) {
2425 if (ActiveModule->ExportAsModule == Tok.getString()) {
2426 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2427 << ActiveModule->Name << Tok.getString();
2428 } else {
2429 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2430 << ActiveModule->Name << ActiveModule->ExportAsModule
2431 << Tok.getString();
2432 }
2433 }
2434
2435 ActiveModule->ExportAsModule = Tok.getString();
Bruno Cardoso Lopesa3b5f712018-04-16 19:42:32 +00002436 Map.addLinkAsDependency(ActiveModule);
2437
Douglas Gregorf0b11de2017-09-14 23:38:44 +00002438 consumeToken();
2439}
2440
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002441/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002442///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002443/// use-declaration:
2444/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002445void ModuleMapParser::parseUseDecl() {
2446 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002447 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002448 // Parse the module-id.
2449 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002450 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002451
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002452 if (ActiveModule->Parent)
2453 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2454 else
2455 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002456}
2457
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002458/// \brief Parse a link declaration.
2459///
2460/// module-declaration:
2461/// 'link' 'framework'[opt] string-literal
2462void ModuleMapParser::parseLinkDecl() {
2463 assert(Tok.is(MMToken::LinkKeyword));
2464 SourceLocation LinkLoc = consumeToken();
2465
2466 // Parse the optional 'framework' keyword.
2467 bool IsFramework = false;
2468 if (Tok.is(MMToken::FrameworkKeyword)) {
2469 consumeToken();
2470 IsFramework = true;
2471 }
2472
2473 // Parse the library name
2474 if (!Tok.is(MMToken::StringLiteral)) {
2475 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2476 << IsFramework << SourceRange(LinkLoc);
2477 HadError = true;
2478 return;
2479 }
2480
2481 std::string LibraryName = Tok.getString();
2482 consumeToken();
2483 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2484 IsFramework));
2485}
2486
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002487/// \brief Parse a configuration macro declaration.
2488///
2489/// module-declaration:
2490/// 'config_macros' attributes[opt] config-macro-list?
2491///
2492/// config-macro-list:
2493/// identifier (',' identifier)?
2494void ModuleMapParser::parseConfigMacros() {
2495 assert(Tok.is(MMToken::ConfigMacros));
2496 SourceLocation ConfigMacrosLoc = consumeToken();
2497
2498 // Only top-level modules can have configuration macros.
2499 if (ActiveModule->Parent) {
2500 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2501 }
2502
2503 // Parse the optional attributes.
2504 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002505 if (parseOptionalAttributes(Attrs))
2506 return;
2507
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002508 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2509 ActiveModule->ConfigMacrosExhaustive = true;
2510 }
2511
2512 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002513 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002514 if (!Tok.is(MMToken::Identifier))
2515 return;
2516
2517 // Consume the first identifier.
2518 if (!ActiveModule->Parent) {
2519 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2520 }
2521 consumeToken();
2522
2523 do {
2524 // If there's a comma, consume it.
2525 if (!Tok.is(MMToken::Comma))
2526 break;
2527 consumeToken();
2528
2529 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002530 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002531 if (!Tok.is(MMToken::Identifier)) {
2532 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2533 break;
2534 }
2535
2536 // Consume the macro name.
2537 if (!ActiveModule->Parent) {
2538 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2539 }
2540 consumeToken();
2541 } while (true);
2542}
2543
Douglas Gregorfb912652013-03-20 21:10:35 +00002544/// \brief Format a module-id into a string.
2545static std::string formatModuleId(const ModuleId &Id) {
2546 std::string result;
2547 {
2548 llvm::raw_string_ostream OS(result);
2549
2550 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2551 if (I)
2552 OS << ".";
2553 OS << Id[I].first;
2554 }
2555 }
2556
2557 return result;
2558}
2559
2560/// \brief Parse a conflict declaration.
2561///
2562/// module-declaration:
2563/// 'conflict' module-id ',' string-literal
2564void ModuleMapParser::parseConflict() {
2565 assert(Tok.is(MMToken::Conflict));
2566 SourceLocation ConflictLoc = consumeToken();
2567 Module::UnresolvedConflict Conflict;
2568
2569 // Parse the module-id.
2570 if (parseModuleId(Conflict.Id))
2571 return;
2572
2573 // Parse the ','.
2574 if (!Tok.is(MMToken::Comma)) {
2575 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2576 << SourceRange(ConflictLoc);
2577 return;
2578 }
2579 consumeToken();
2580
2581 // Parse the message.
2582 if (!Tok.is(MMToken::StringLiteral)) {
2583 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2584 << formatModuleId(Conflict.Id);
2585 return;
2586 }
2587 Conflict.Message = Tok.getString().str();
2588 consumeToken();
2589
2590 // Add this unresolved conflict.
2591 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2592}
2593
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002594/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002595///
2596/// module-declaration:
2597/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2598/// { inferred-module-member* }
2599///
2600/// inferred-module-member:
2601/// 'export' '*'
2602/// 'exclude' identifier
2603void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002604 assert(Tok.is(MMToken::Star));
2605 SourceLocation StarLoc = consumeToken();
2606 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002607
Douglas Gregor73441092011-12-05 22:27:44 +00002608 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002609 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002610 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2611 Failed = true;
2612 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002613
2614 if (ActiveModule) {
2615 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002616 if (!Failed && ActiveModule->IsAvailable &&
2617 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002618 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2619 Failed = true;
2620 }
2621
2622 // Check for redefinition of an inferred module.
2623 if (!Failed && ActiveModule->InferSubmodules) {
2624 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2625 if (ActiveModule->InferredSubmoduleLoc.isValid())
2626 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2627 diag::note_mmap_prev_definition);
2628 Failed = true;
2629 }
2630
2631 // Check for the 'framework' keyword, which is not permitted here.
2632 if (Framework) {
2633 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2634 Framework = false;
2635 }
2636 } else if (Explicit) {
2637 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2638 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002639 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002640
Douglas Gregor73441092011-12-05 22:27:44 +00002641 // If there were any problems with this inferred submodule, skip its body.
2642 if (Failed) {
2643 if (Tok.is(MMToken::LBrace)) {
2644 consumeToken();
2645 skipUntil(MMToken::RBrace);
2646 if (Tok.is(MMToken::RBrace))
2647 consumeToken();
2648 }
2649 HadError = true;
2650 return;
2651 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002652
2653 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002654 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002655 if (parseOptionalAttributes(Attrs))
2656 return;
Douglas Gregor9194a912012-11-06 19:39:40 +00002657
2658 if (ActiveModule) {
2659 // Note that we have an inferred submodule.
2660 ActiveModule->InferSubmodules = true;
2661 ActiveModule->InferredSubmoduleLoc = StarLoc;
2662 ActiveModule->InferExplicitSubmodules = Explicit;
2663 } else {
2664 // We'll be inferring framework modules for this directory.
2665 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002666 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002667 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002668 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002669 }
2670
Douglas Gregor73441092011-12-05 22:27:44 +00002671 // Parse the opening brace.
2672 if (!Tok.is(MMToken::LBrace)) {
2673 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2674 HadError = true;
2675 return;
2676 }
2677 SourceLocation LBraceLoc = consumeToken();
2678
2679 // Parse the body of the inferred submodule.
2680 bool Done = false;
2681 do {
2682 switch (Tok.Kind) {
2683 case MMToken::EndOfFile:
2684 case MMToken::RBrace:
2685 Done = true;
2686 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002687
Eugene Zelenkoafd1b1c2017-12-06 23:18:41 +00002688 case MMToken::ExcludeKeyword:
Douglas Gregor9194a912012-11-06 19:39:40 +00002689 if (ActiveModule) {
2690 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002691 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002692 consumeToken();
2693 break;
2694 }
2695
2696 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002697 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002698 if (!Tok.is(MMToken::Identifier)) {
2699 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2700 break;
2701 }
2702
2703 Map.InferredDirectories[Directory].ExcludedModules
2704 .push_back(Tok.getString());
2705 consumeToken();
2706 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002707
2708 case MMToken::ExportKeyword:
2709 if (!ActiveModule) {
2710 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002711 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002712 consumeToken();
2713 break;
2714 }
2715
Douglas Gregor73441092011-12-05 22:27:44 +00002716 consumeToken();
2717 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002718 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002719 else
2720 Diags.Report(Tok.getLocation(),
2721 diag::err_mmap_expected_export_wildcard);
2722 consumeToken();
2723 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002724
Douglas Gregor73441092011-12-05 22:27:44 +00002725 case MMToken::ExplicitKeyword:
2726 case MMToken::ModuleKeyword:
2727 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002728 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002729 case MMToken::UmbrellaKeyword:
2730 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002731 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002732 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002733 consumeToken();
2734 break;
2735 }
2736 } while (!Done);
2737
2738 if (Tok.is(MMToken::RBrace))
2739 consumeToken();
2740 else {
2741 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2742 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2743 HadError = true;
2744 }
2745}
2746
Douglas Gregor9194a912012-11-06 19:39:40 +00002747/// \brief Parse optional attributes.
2748///
2749/// attributes:
2750/// attribute attributes
2751/// attribute
2752///
2753/// attribute:
2754/// [ identifier ]
2755///
2756/// \param Attrs Will be filled in with the parsed attributes.
2757///
2758/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002759bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002760 bool HadError = false;
2761
2762 while (Tok.is(MMToken::LSquare)) {
2763 // Consume the '['.
2764 SourceLocation LSquareLoc = consumeToken();
2765
2766 // Check whether we have an attribute name here.
2767 if (!Tok.is(MMToken::Identifier)) {
2768 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2769 skipUntil(MMToken::RSquare);
2770 if (Tok.is(MMToken::RSquare))
2771 consumeToken();
2772 HadError = true;
2773 }
2774
2775 // Decode the attribute name.
2776 AttributeKind Attribute
2777 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002778 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002779 .Case("extern_c", AT_extern_c)
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002780 .Case("no_undeclared_includes", AT_no_undeclared_includes)
Douglas Gregor9194a912012-11-06 19:39:40 +00002781 .Case("system", AT_system)
2782 .Default(AT_unknown);
2783 switch (Attribute) {
2784 case AT_unknown:
2785 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2786 << Tok.getString();
2787 break;
2788
2789 case AT_system:
2790 Attrs.IsSystem = true;
2791 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002792
Richard Smith77944862014-03-02 05:58:18 +00002793 case AT_extern_c:
2794 Attrs.IsExternC = true;
2795 break;
2796
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002797 case AT_exhaustive:
2798 Attrs.IsExhaustive = true;
2799 break;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002800
2801 case AT_no_undeclared_includes:
2802 Attrs.NoUndeclaredIncludes = true;
2803 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002804 }
2805 consumeToken();
2806
2807 // Consume the ']'.
2808 if (!Tok.is(MMToken::RSquare)) {
2809 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2810 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2811 skipUntil(MMToken::RSquare);
2812 HadError = true;
2813 }
2814
2815 if (Tok.is(MMToken::RSquare))
2816 consumeToken();
2817 }
2818
2819 return HadError;
2820}
2821
Douglas Gregor718292f2011-11-11 19:10:28 +00002822/// \brief Parse a module map file.
2823///
2824/// module-map-file:
2825/// module-declaration*
2826bool ModuleMapParser::parseModuleMapFile() {
2827 do {
2828 switch (Tok.Kind) {
2829 case MMToken::EndOfFile:
2830 return HadError;
2831
Douglas Gregore7ab3662011-12-07 02:23:45 +00002832 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002833 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002834 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002835 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002836 parseModuleDecl();
2837 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002838
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002839 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002840 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002841 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002842 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002843 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002844 case MMToken::ExportKeyword:
Douglas Gregorf0b11de2017-09-14 23:38:44 +00002845 case MMToken::ExportAsKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002846 case MMToken::HeaderKeyword:
2847 case MMToken::Identifier:
2848 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002849 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002850 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002851 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002852 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002853 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002854 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002855 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002856 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002857 case MMToken::StringLiteral:
Richard Smith040e1262017-06-02 01:55:39 +00002858 case MMToken::IntegerLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002859 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002860 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002861 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002862 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2863 HadError = true;
2864 consumeToken();
2865 break;
2866 }
2867 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002868}
2869
Richard Smith9acb99e32014-12-10 03:09:48 +00002870bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00002871 const DirectoryEntry *Dir, FileID ID,
Richard Smith8128f332017-05-05 22:18:51 +00002872 unsigned *Offset,
Richard Smithae6df272015-07-14 02:06:01 +00002873 SourceLocation ExternModuleLoc) {
Richard Smith8128f332017-05-05 22:18:51 +00002874 assert(Target && "Missing target information");
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002875 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2876 = ParsedModuleMap.find(File);
2877 if (Known != ParsedModuleMap.end())
2878 return Known->second;
2879
Richard Smith8128f332017-05-05 22:18:51 +00002880 // If the module map file wasn't already entered, do so now.
2881 if (ID.isInvalid()) {
Richard Smithf3f84612017-06-29 02:19:42 +00002882 auto FileCharacter =
2883 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
Richard Smith8128f332017-05-05 22:18:51 +00002884 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2885 }
2886
Craig Topperd2d442c2014-05-17 23:10:59 +00002887 assert(Target && "Missing target information");
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002888 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002889 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002890 return ParsedModuleMap[File] = true;
Richard Smith8128f332017-05-05 22:18:51 +00002891 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2892 "invalid buffer offset");
Ben Langmuir984e1df2014-03-19 20:23:34 +00002893
Douglas Gregor718292f2011-11-11 19:10:28 +00002894 // Parse this module map file.
Richard Smith8128f332017-05-05 22:18:51 +00002895 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2896 Buffer->getBufferStart(),
2897 Buffer->getBufferStart() + (Offset ? *Offset : 0),
2898 Buffer->getBufferEnd());
Richard Smith2a6edb32015-08-09 04:46:57 +00002899 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002900 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Bruno Cardoso Lopesc192d192018-01-05 22:13:56 +00002901 IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002902 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002903 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002904
Richard Smith8128f332017-05-05 22:18:51 +00002905 if (Offset) {
2906 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
2907 assert(Loc.first == ID && "stopped in a different file?");
2908 *Offset = Loc.second;
2909 }
2910
Richard Smith2a6edb32015-08-09 04:46:57 +00002911 // Notify callbacks that we parsed it.
2912 for (const auto &Cb : Callbacks)
2913 Cb->moduleMapFileRead(Start, *File, IsSystem);
Bruno Cardoso Lopes8587dfd2018-01-05 02:33:18 +00002914
Douglas Gregor718292f2011-11-11 19:10:28 +00002915 return Result;
2916}