blob: 40f78ce25ceb3be2e682afb0d72d7874655015bb [file] [log] [blame]
Douglas Gregor718292f2011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Richard Smith9acb99e32014-12-10 03:09:48 +000022#include "clang/Lex/HeaderSearchOptions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000023#include "clang/Lex/LexDiagnostic.h"
24#include "clang/Lex/Lexer.h"
25#include "clang/Lex/LiteralSupport.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000028#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000029#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000030#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000031#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000032#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000033#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000034#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000035#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000036#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000037using namespace clang;
38
Richard Smith040e1262017-06-02 01:55:39 +000039Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
40 switch ((int)Role) {
41 default: llvm_unreachable("unknown header role");
42 case NormalHeader:
43 return Module::HK_Normal;
44 case PrivateHeader:
45 return Module::HK_Private;
46 case TextualHeader:
47 return Module::HK_Textual;
48 case PrivateHeader | TextualHeader:
49 return Module::HK_PrivateTextual;
50 }
51}
52
53ModuleMap::ModuleHeaderRole
54ModuleMap::headerKindToRole(Module::HeaderKind Kind) {
55 switch ((int)Kind) {
56 case Module::HK_Normal:
57 return NormalHeader;
58 case Module::HK_Private:
59 return PrivateHeader;
60 case Module::HK_Textual:
61 return TextualHeader;
62 case Module::HK_PrivateTextual:
63 return ModuleHeaderRole(PrivateHeader | TextualHeader);
64 case Module::HK_Excluded:
65 llvm_unreachable("unexpected header kind");
66 }
67 llvm_unreachable("unknown header kind");
68}
69
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000070Module::ExportDecl
71ModuleMap::resolveExport(Module *Mod,
72 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000073 bool Complain) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +000074 // We may have just a wildcard.
75 if (Unresolved.Id.empty()) {
76 assert(Unresolved.Wildcard && "Invalid unresolved export");
Craig Topperd2d442c2014-05-17 23:10:59 +000077 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +000078 }
79
Douglas Gregorfb912652013-03-20 21:10:35 +000080 // Resolve the module-id.
81 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
82 if (!Context)
83 return Module::ExportDecl();
84
85 return Module::ExportDecl(Context, Unresolved.Wildcard);
86}
87
88Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
89 bool Complain) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000090 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000091 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000092 if (!Context) {
93 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000094 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000095 << Id[0].first << Mod->getFullModuleName();
96
Craig Topperd2d442c2014-05-17 23:10:59 +000097 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000098 }
99
100 // Dig into the module path.
Douglas Gregorfb912652013-03-20 21:10:35 +0000101 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
102 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000103 if (!Sub) {
104 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000105 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +0000106 << Id[I].first << Context->getFullModuleName()
107 << SourceRange(Id[0].second, Id[I-1].second);
108
Craig Topperd2d442c2014-05-17 23:10:59 +0000109 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000110 }
Douglas Gregorfb912652013-03-20 21:10:35 +0000111
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000112 Context = Sub;
113 }
Douglas Gregorfb912652013-03-20 21:10:35 +0000114
115 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000116}
117
Richard Smith1d609872017-05-26 00:01:53 +0000118/// \brief Append to \p Paths the set of paths needed to get to the
119/// subframework in which the given module lives.
120static void appendSubframeworkPaths(Module *Mod,
121 SmallVectorImpl<char> &Path) {
122 // Collect the framework names from the given module to the top-level module.
123 SmallVector<StringRef, 2> Paths;
124 for (; Mod; Mod = Mod->Parent) {
125 if (Mod->IsFramework)
126 Paths.push_back(Mod->Name);
127 }
128
129 if (Paths.empty())
130 return;
131
132 // Add Frameworks/Name.framework for each subframework.
133 for (unsigned I = Paths.size() - 1; I != 0; --I)
134 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
135}
136
137const FileEntry *
Richard Smith040e1262017-06-02 01:55:39 +0000138ModuleMap::findHeader(Module *M,
139 const Module::UnresolvedHeaderDirective &Header,
140 SmallVectorImpl<char> &RelativePathName) {
141 auto GetFile = [&](StringRef Filename) -> const FileEntry * {
142 auto *File = SourceMgr.getFileManager().getFile(Filename);
143 if (!File ||
144 (Header.Size && File->getSize() != *Header.Size) ||
145 (Header.ModTime && File->getModificationTime() != *Header.ModTime))
146 return nullptr;
147 return File;
148 };
149
Richard Smith1d609872017-05-26 00:01:53 +0000150 if (llvm::sys::path::is_absolute(Header.FileName)) {
151 RelativePathName.clear();
152 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
Richard Smith040e1262017-06-02 01:55:39 +0000153 return GetFile(Header.FileName);
Richard Smith1d609872017-05-26 00:01:53 +0000154 }
155
156 // Search for the header file within the module's home directory.
157 auto *Directory = M->Directory;
158 SmallString<128> FullPathName(Directory->getName());
159 unsigned FullPathLength = FullPathName.size();
160
161 if (M->isPartOfFramework()) {
162 appendSubframeworkPaths(M, RelativePathName);
163 unsigned RelativePathLength = RelativePathName.size();
164
165 // Check whether this file is in the public headers.
166 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
167 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith040e1262017-06-02 01:55:39 +0000168 if (auto *File = GetFile(FullPathName))
Richard Smith1d609872017-05-26 00:01:53 +0000169 return File;
170
171 // Check whether this file is in the private headers.
172 // Ideally, private modules in the form 'FrameworkName.Private' should
173 // be defined as 'module FrameworkName.Private', and not as
174 // 'framework module FrameworkName.Private', since a 'Private.Framework'
175 // does not usually exist. However, since both are currently widely used
176 // for private modules, make sure we find the right path in both cases.
177 if (M->IsFramework && M->Name == "Private")
178 RelativePathName.clear();
179 else
180 RelativePathName.resize(RelativePathLength);
181 FullPathName.resize(FullPathLength);
182 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
183 Header.FileName);
184 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith040e1262017-06-02 01:55:39 +0000185 return GetFile(FullPathName);
Richard Smith1d609872017-05-26 00:01:53 +0000186 }
187
188 // Lookup for normal headers.
189 llvm::sys::path::append(RelativePathName, Header.FileName);
190 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith040e1262017-06-02 01:55:39 +0000191 return GetFile(FullPathName);
Richard Smith1d609872017-05-26 00:01:53 +0000192}
193
Richard Smith040e1262017-06-02 01:55:39 +0000194void ModuleMap::resolveHeader(Module *Mod,
195 const Module::UnresolvedHeaderDirective &Header) {
196 SmallString<128> RelativePathName;
197 if (const FileEntry *File = findHeader(Mod, Header, RelativePathName)) {
198 if (Header.IsUmbrella) {
199 const DirectoryEntry *UmbrellaDir = File->getDir();
200 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
201 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
202 << UmbrellaMod->getFullModuleName();
203 else
204 // Record this umbrella header.
205 setUmbrellaHeader(Mod, File, RelativePathName.str());
206 } else {
207 Module::Header H = {RelativePathName.str(), File};
208 if (Header.Kind == Module::HK_Excluded)
209 excludeHeader(Mod, H);
210 else
211 addHeader(Mod, H, headerKindToRole(Header.Kind));
212 }
213 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
214 // There's a builtin header but no corresponding on-disk header. Assume
215 // this was supposed to modularize the builtin header alone.
216 } else if (Header.Kind == Module::HK_Excluded) {
217 // Ignore missing excluded header files. They're optional anyway.
218 } else {
219 // If we find a module that has a missing header, we mark this module as
220 // unavailable and store the header directive for displaying diagnostics.
221 Mod->MissingHeaders.push_back(Header);
222 // A missing header with stat information doesn't make the module
223 // unavailable; this keeps our behavior consistent as headers are lazily
224 // resolved. (Such a module still can't be built though, except from
225 // preprocessed source.)
226 if (!Header.Size && !Header.ModTime)
227 Mod->markUnavailable();
228 }
229}
230
231bool ModuleMap::resolveAsBuiltinHeader(
232 Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
233 if (Header.Kind == Module::HK_Excluded ||
234 llvm::sys::path::is_absolute(Header.FileName) ||
235 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
236 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
237 !isBuiltinHeader(Header.FileName))
238 return false;
Richard Smith1d609872017-05-26 00:01:53 +0000239
240 // This is a system module with a top-level header. This header
241 // may have a counterpart (or replacement) in the set of headers
242 // supplied by Clang. Find that builtin header.
Richard Smith040e1262017-06-02 01:55:39 +0000243 SmallString<128> Path;
244 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
245 auto *File = SourceMgr.getFileManager().getFile(Path);
246 if (!File)
247 return false;
248
249 auto Role = headerKindToRole(Header.Kind);
250 Module::Header H = {Path.str(), File};
251 addHeader(Mod, H, Role);
252 return true;
Richard Smith1d609872017-05-26 00:01:53 +0000253}
254
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000255ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000256 const LangOptions &LangOpts, const TargetInfo *Target,
257 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +0000258 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Craig Topperd2d442c2014-05-17 23:10:59 +0000259 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
Richard Smith7e82e012016-02-19 22:25:36 +0000260 SourceModule(nullptr), NumCreatedModules(0) {
Richard Smith0414b852015-02-14 05:32:00 +0000261 MMapLangOpts.LineComment = true;
262}
Douglas Gregor718292f2011-11-11 19:10:28 +0000263
264ModuleMap::~ModuleMap() {
Davide Italiano21668752016-03-08 23:58:08 +0000265 for (auto &M : Modules)
266 delete M.getValue();
Douglas Gregor718292f2011-11-11 19:10:28 +0000267}
268
Douglas Gregor89929282012-01-30 06:01:29 +0000269void ModuleMap::setTarget(const TargetInfo &Target) {
270 assert((!this->Target || this->Target == &Target) &&
271 "Improper target override");
272 this->Target = &Target;
273}
274
Douglas Gregor056396a2012-10-12 21:15:50 +0000275/// \brief "Sanitize" a filename so that it can be used as an identifier.
276static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
277 SmallVectorImpl<char> &Buffer) {
278 if (Name.empty())
279 return Name;
280
Jordan Rosea7d03842013-02-08 22:30:41 +0000281 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000282 // If we don't already have something with the form of an identifier,
283 // create a buffer with the sanitized name.
284 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000285 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000286 Buffer.push_back('_');
287 Buffer.reserve(Buffer.size() + Name.size());
288 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000289 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000290 Buffer.push_back(Name[I]);
291 else
292 Buffer.push_back('_');
293 }
294
295 Name = StringRef(Buffer.data(), Buffer.size());
296 }
297
298 while (llvm::StringSwitch<bool>(Name)
299#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
300#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
301#include "clang/Basic/TokenKinds.def"
302 .Default(false)) {
303 if (Name.data() != Buffer.data())
304 Buffer.append(Name.begin(), Name.end());
305 Buffer.push_back('_');
306 Name = StringRef(Buffer.data(), Buffer.size());
307 }
308
309 return Name;
310}
311
Douglas Gregor34d52742013-05-02 17:58:30 +0000312/// \brief Determine whether the given file name is the name of a builtin
313/// header, supplied by Clang to replace, override, or augment existing system
314/// headers.
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000315bool ModuleMap::isBuiltinHeader(StringRef FileName) {
Douglas Gregor34d52742013-05-02 17:58:30 +0000316 return llvm::StringSwitch<bool>(FileName)
317 .Case("float.h", true)
318 .Case("iso646.h", true)
319 .Case("limits.h", true)
320 .Case("stdalign.h", true)
321 .Case("stdarg.h", true)
Ben Langmuir3c4b1292016-03-09 23:31:34 +0000322 .Case("stdatomic.h", true)
Douglas Gregor34d52742013-05-02 17:58:30 +0000323 .Case("stdbool.h", true)
324 .Case("stddef.h", true)
325 .Case("stdint.h", true)
326 .Case("tgmath.h", true)
327 .Case("unwind.h", true)
328 .Default(false);
329}
330
Daniel Jasper92669ee2013-12-20 12:09:36 +0000331ModuleMap::HeadersMap::iterator
332ModuleMap::findKnownHeader(const FileEntry *File) {
Richard Smith040e1262017-06-02 01:55:39 +0000333 resolveHeaderDirectives(File);
Douglas Gregor59527662012-10-15 06:28:11 +0000334 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000335 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
336 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Bruno Cardoso Lopesba1b5c92017-01-11 02:14:51 +0000337 ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000338 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000339 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000340 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000341 return Known;
342}
343
Ben Langmuir44691382014-04-10 00:39:10 +0000344ModuleMap::KnownHeader
345ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
346 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000347 if (UmbrellaDirs.empty())
348 return KnownHeader();
349
Ben Langmuir44691382014-04-10 00:39:10 +0000350 const DirectoryEntry *Dir = File->getDir();
351 assert(Dir && "file in no directory");
352
353 // Note: as an egregious but useful hack we use the real path here, because
354 // frameworks moving from top-level frameworks to embedded frameworks tend
355 // to be symlinked from the top-level location to the embedded location,
356 // and we need to resolve lookups as if we had found the embedded location.
357 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
358
359 // Keep walking up the directory hierarchy, looking for a directory with
360 // an umbrella header.
361 do {
362 auto KnownDir = UmbrellaDirs.find(Dir);
363 if (KnownDir != UmbrellaDirs.end())
364 return KnownHeader(KnownDir->second, NormalHeader);
365
366 IntermediateDirs.push_back(Dir);
367
368 // Retrieve our parent path.
369 DirName = llvm::sys::path::parent_path(DirName);
370 if (DirName.empty())
371 break;
372
373 // Resolve the parent path to a directory entry.
374 Dir = SourceMgr.getFileManager().getDirectory(DirName);
375 } while (Dir);
376 return KnownHeader();
377}
378
Daniel Jasper92669ee2013-12-20 12:09:36 +0000379static bool violatesPrivateInclude(Module *RequestingModule,
380 const FileEntry *IncFileEnt,
Richard Smith4eb83932016-04-27 21:57:05 +0000381 ModuleMap::KnownHeader Header) {
Richard Smith202210b2014-10-24 20:23:01 +0000382#ifndef NDEBUG
Richard Smith4eb83932016-04-27 21:57:05 +0000383 if (Header.getRole() & ModuleMap::PrivateHeader) {
Richard Smith2708e522015-03-10 00:19:04 +0000384 // Check for consistency between the module header role
385 // as obtained from the lookup and as obtained from the module.
386 // This check is not cheap, so enable it only for debugging.
387 bool IsPrivate = false;
388 SmallVectorImpl<Module::Header> *HeaderList[] = {
Richard Smith4eb83932016-04-27 21:57:05 +0000389 &Header.getModule()->Headers[Module::HK_Private],
390 &Header.getModule()->Headers[Module::HK_PrivateTextual]};
Richard Smith2708e522015-03-10 00:19:04 +0000391 for (auto *Hs : HeaderList)
392 IsPrivate |=
393 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000394 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000395 }) != Hs->end();
Richard Smith4eb83932016-04-27 21:57:05 +0000396 assert(IsPrivate && "inconsistent headers and roles");
Richard Smith2708e522015-03-10 00:19:04 +0000397 }
Richard Smith202210b2014-10-24 20:23:01 +0000398#endif
Richard Smith4eb83932016-04-27 21:57:05 +0000399 return !Header.isAccessibleFrom(RequestingModule);
Daniel Jasper92669ee2013-12-20 12:09:36 +0000400}
401
Ben Langmuir71e1a642014-05-05 21:44:13 +0000402static Module *getTopLevelOrNull(Module *M) {
403 return M ? M->getTopLevelModule() : nullptr;
404}
405
Daniel Jasper92669ee2013-12-20 12:09:36 +0000406void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
Richard Smith8d4e90b2016-03-14 17:52:37 +0000407 bool RequestingModuleIsModuleInterface,
Daniel Jasper92669ee2013-12-20 12:09:36 +0000408 SourceLocation FilenameLoc,
409 StringRef Filename,
410 const FileEntry *File) {
411 // No errors for indirect modules. This may be a bit of a problem for modules
412 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000413 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000414 return;
415
Richard Smith040e1262017-06-02 01:55:39 +0000416 if (RequestingModule) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000417 resolveUses(RequestingModule, /*Complain=*/false);
Richard Smith040e1262017-06-02 01:55:39 +0000418 resolveHeaderDirectives(RequestingModule);
419 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000420
Ben Langmuir71e1a642014-05-05 21:44:13 +0000421 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000422 Module *Private = nullptr;
423 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000424
Ben Langmuir71e1a642014-05-05 21:44:13 +0000425 HeadersMap::iterator Known = findKnownHeader(File);
426 if (Known != Headers.end()) {
427 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000428 // Remember private headers for later printing of a diagnostic.
Richard Smith4eb83932016-04-27 21:57:05 +0000429 if (violatesPrivateInclude(RequestingModule, File, Header)) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000430 Private = Header.getModule();
431 continue;
432 }
433
434 // If uses need to be specified explicitly, we are only allowed to return
435 // modules that are explicitly used by the requesting module.
436 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000437 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000438 NotUsed = Header.getModule();
439 continue;
440 }
441
442 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000443 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000444 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000445
446 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000447 }
448
449 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000450 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000451 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000452 << Filename;
453 return;
454 }
455
456 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000457 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000458 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000459 << RequestingModule->getFullModuleName() << Filename;
460 return;
461 }
462
Ben Langmuir71e1a642014-05-05 21:44:13 +0000463 if (Excluded || isHeaderInUmbrellaDirs(File))
464 return;
465
466 // At this point, only non-modular includes remain.
467
468 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000469 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000470 << RequestingModule->getFullModuleName() << Filename;
Manman Rena67e4d32016-08-26 17:16:46 +0000471 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
472 LangOpts.isCompilingModule()) {
473 // Do not diagnose when we are not compiling a module.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000474 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
475 diag::warn_non_modular_include_in_framework_module :
476 diag::warn_non_modular_include_in_module;
Manman Ren70a77382016-10-21 23:27:37 +0000477 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
478 << File->getName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000479 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000480}
481
Richard Smithec87a502015-02-13 23:50:20 +0000482static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
483 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000484 // Prefer available modules.
485 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
486 return true;
487
Richard Smithec87a502015-02-13 23:50:20 +0000488 // Prefer a public header over a private header.
489 if ((New.getRole() & ModuleMap::PrivateHeader) !=
490 (Old.getRole() & ModuleMap::PrivateHeader))
491 return !(New.getRole() & ModuleMap::PrivateHeader);
492
493 // Prefer a non-textual header over a textual header.
494 if ((New.getRole() & ModuleMap::TextualHeader) !=
495 (Old.getRole() & ModuleMap::TextualHeader))
496 return !(New.getRole() & ModuleMap::TextualHeader);
497
498 // Don't have a reason to choose between these. Just keep the first one.
499 return false;
500}
501
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000502ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
503 bool AllowTextual) {
Richard Smith306d8922014-10-22 23:50:56 +0000504 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000505 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000506 return ModuleMap::KnownHeader();
507 return R;
508 };
509
Sean Silva4881e8b2015-06-10 01:37:59 +0000510 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000511 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000512 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000513 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000514 for (KnownHeader &H : Known->second) {
Richard Smith7e82e012016-02-19 22:25:36 +0000515 // Prefer a header from the source module over all others.
516 if (H.getModule()->getTopLevelModule() == SourceModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000517 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000518 if (!Result || isBetterKnownHeader(H, Result))
519 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000520 }
Richard Smith306d8922014-10-22 23:50:56 +0000521 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000522 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000523
Richard Smith386bb072015-08-18 23:42:23 +0000524 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
525}
526
527ModuleMap::KnownHeader
528ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
529 assert(!Headers.count(File) && "already have a module for this header");
530
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000531 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000532 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
533 if (H) {
534 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000535
Ben Langmuir44691382014-04-10 00:39:10 +0000536 // Search up the module stack until we find a module with an umbrella
537 // directory.
538 Module *UmbrellaModule = Result;
539 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
540 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000541
Ben Langmuir44691382014-04-10 00:39:10 +0000542 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000543 const FileEntry *UmbrellaModuleMap =
544 getModuleMapFileForUniquing(UmbrellaModule);
545
Ben Langmuir44691382014-04-10 00:39:10 +0000546 // Infer submodules for each of the directories we found between
547 // the directory of the umbrella header and the directory where
548 // the actual header is located.
549 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000550
Ben Langmuir44691382014-04-10 00:39:10 +0000551 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
552 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000553 SmallString<32> NameBuf;
554 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000555 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000556 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
557 Explicit).first;
558 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000559 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000560
561 // Associate the module and the directory.
562 UmbrellaDirs[SkippedDirs[I-1]] = Result;
563
564 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000565 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000566 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000567 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000568 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000569
Ben Langmuir44691382014-04-10 00:39:10 +0000570 // Infer a submodule with the same name as this header file.
571 SmallString<32> NameBuf;
572 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000573 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000574 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
575 Explicit).first;
576 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000577 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000578 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000579
Ben Langmuir44691382014-04-10 00:39:10 +0000580 // If inferred submodules export everything they import, add a
581 // wildcard to the set of exports.
582 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000583 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000584 } else {
585 // Record each of the directories we stepped through as being part of
586 // the module we found, since the umbrella header covers them all.
587 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
588 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000589 }
Ben Langmuir44691382014-04-10 00:39:10 +0000590
Richard Smith386bb072015-08-18 23:42:23 +0000591 KnownHeader Header(Result, NormalHeader);
592 Headers[File].push_back(Header);
593 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000594 }
Richard Smith306d8922014-10-22 23:50:56 +0000595
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000596 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000597}
598
Richard Smith386bb072015-08-18 23:42:23 +0000599ArrayRef<ModuleMap::KnownHeader>
600ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
Richard Smith040e1262017-06-02 01:55:39 +0000601 resolveHeaderDirectives(File);
Richard Smith386bb072015-08-18 23:42:23 +0000602 auto It = Headers.find(File);
603 if (It == Headers.end())
604 return None;
605 return It->second;
606}
607
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000608bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000609 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000610}
611
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000612bool
613ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
614 const Module *RequestingModule) const {
Richard Smith040e1262017-06-02 01:55:39 +0000615 resolveHeaderDirectives(Header);
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000616 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000617 if (Known != Headers.end()) {
618 for (SmallVectorImpl<KnownHeader>::const_iterator
619 I = Known->second.begin(),
620 E = Known->second.end();
621 I != E; ++I) {
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000622
623 if (I->isAvailable() &&
624 (!RequestingModule ||
625 I->getModule()->isSubModuleOf(RequestingModule))) {
626 // When no requesting module is available, the caller is looking if a
627 // header is part a module by only looking into the module map. This is
628 // done by warn_uncovered_module_header checks; don't consider textual
629 // headers part of it in this mode, otherwise we get misleading warnings
630 // that a umbrella header is not including a textual header.
631 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
632 continue;
Daniel Jasper97da9172013-10-22 08:09:47 +0000633 return false;
Bruno Cardoso Lopes052d95a2017-01-12 19:15:33 +0000634 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000635 }
636 return true;
637 }
Richard Smith50996ce2014-04-08 13:13:04 +0000638
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000639 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000640 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000641 StringRef DirName = Dir->getName();
642
Richard Smith50996ce2014-04-08 13:13:04 +0000643 auto IsUnavailable = [&](const Module *M) {
644 return !M->isAvailable() && (!RequestingModule ||
645 M->isSubModuleOf(RequestingModule));
646 };
647
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000648 // Keep walking up the directory hierarchy, looking for a directory with
649 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000650 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000651 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000652 = UmbrellaDirs.find(Dir);
653 if (KnownDir != UmbrellaDirs.end()) {
654 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000655 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000656 return true;
657
658 // Search up the module stack until we find a module with an umbrella
659 // directory.
660 Module *UmbrellaModule = Found;
661 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
662 UmbrellaModule = UmbrellaModule->Parent;
663
664 if (UmbrellaModule->InferSubmodules) {
665 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
666 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000667 SmallString<32> NameBuf;
668 StringRef Name = sanitizeFilenameAsIdentifier(
669 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
670 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000671 Found = lookupModuleQualified(Name, Found);
672 if (!Found)
673 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000674 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000675 return true;
676 }
677
678 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000679 SmallString<32> NameBuf;
680 StringRef Name = sanitizeFilenameAsIdentifier(
681 llvm::sys::path::stem(Header->getName()),
682 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000683 Found = lookupModuleQualified(Name, Found);
684 if (!Found)
685 return false;
686 }
687
Richard Smith50996ce2014-04-08 13:13:04 +0000688 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000689 }
690
691 SkippedDirs.push_back(Dir);
692
693 // Retrieve our parent path.
694 DirName = llvm::sys::path::parent_path(DirName);
695 if (DirName.empty())
696 break;
697
698 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000699 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000700 } while (Dir);
701
702 return false;
703}
704
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000705Module *ModuleMap::findModule(StringRef Name) const {
706 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000707 if (Known != Modules.end())
708 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000709
710 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000711}
712
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000713Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
714 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000715 for(; Context; Context = Context->Parent) {
716 if (Module *Sub = lookupModuleQualified(Name, Context))
717 return Sub;
718 }
719
720 return findModule(Name);
721}
722
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000723Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000724 if (!Context)
725 return findModule(Name);
726
Douglas Gregoreb90e832012-01-04 23:32:19 +0000727 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000728}
729
David Blaikie9ffe5a32017-01-30 05:00:26 +0000730std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
731 Module *Parent,
732 bool IsFramework,
733 bool IsExplicit) {
Douglas Gregor69021972011-11-30 17:33:56 +0000734 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000735 if (Module *Sub = lookupModuleQualified(Name, Parent))
736 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000737
738 // Create a new module with this name.
David Blaikie9ffe5a32017-01-30 05:00:26 +0000739 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
740 IsExplicit, NumCreatedModules++);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000741 if (!Parent) {
Richard Smith7e82e012016-02-19 22:25:36 +0000742 if (LangOpts.CurrentModule == Name)
743 SourceModule = Result;
Douglas Gregor69021972011-11-30 17:33:56 +0000744 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000745 }
Douglas Gregor69021972011-11-30 17:33:56 +0000746 return std::make_pair(Result, true);
747}
748
Richard Smithbbcc9f02016-08-26 00:14:38 +0000749Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
750 StringRef Name) {
751 assert(LangOpts.CurrentModule == Name && "module name mismatch");
752 assert(!Modules[Name] && "redefining existing module");
753
754 auto *Result =
755 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
756 /*IsExplicit*/ false, NumCreatedModules++);
Richard Smith145e15a2017-04-24 23:12:30 +0000757 Result->Kind = Module::ModuleInterfaceUnit;
Richard Smithbbcc9f02016-08-26 00:14:38 +0000758 Modules[Name] = SourceModule = Result;
759
760 // Mark the main source file as being within the newly-created module so that
761 // declarations and macros are properly visibility-restricted to it.
762 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
763 assert(MainFile && "no input file for module interface");
764 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
765
766 return Result;
767}
768
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000769/// \brief For a framework module, infer the framework against which we
770/// should link.
771static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
772 FileManager &FileMgr) {
773 assert(Mod->IsFramework && "Can only infer linking for framework modules");
774 assert(!Mod->isSubFramework() &&
775 "Can only infer linking for top-level frameworks");
776
777 SmallString<128> LibName;
778 LibName += FrameworkDir->getName();
779 llvm::sys::path::append(LibName, Mod->Name);
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000780
781 // The library name of a framework has more than one possible extension since
782 // the introduction of the text-based dynamic library format. We need to check
783 // for both before we give up.
Benjamin Kramer8013e812016-11-15 18:56:39 +0000784 for (const char *extension : {"", ".tbd"}) {
Juergen Ributzka8aaae5a2015-11-13 19:08:07 +0000785 llvm::sys::path::replace_extension(LibName, extension);
786 if (FileMgr.getFile(LibName)) {
787 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
788 /*IsFramework=*/true));
789 return;
790 }
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000791 }
792}
793
Ben Langmuira5254002015-07-02 13:19:48 +0000794Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
795 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000796 Attributes Attrs;
797 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000798 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000799}
800
Ben Langmuira5254002015-07-02 13:19:48 +0000801Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000802 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000803 // Note: as an egregious but useful hack we use the real path here, because
804 // we might be looking at an embedded framework that symlinks out to a
805 // top-level framework, and we need to infer as if we were naming the
806 // top-level framework.
807 StringRef FrameworkDirName =
808 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
809
810 // In case this is a case-insensitive filesystem, use the canonical
811 // directory name as the ModuleName, since modules are case-sensitive.
812 // FIXME: we should be able to give a fix-it hint for the correct spelling.
813 SmallString<32> ModuleNameStorage;
814 StringRef ModuleName = sanitizeFilenameAsIdentifier(
815 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000816
Douglas Gregor56c64012011-11-17 01:41:17 +0000817 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000818 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
819 return Mod;
820
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000821 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000822
823 // If the framework has a parent path from which we're allowed to infer
824 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000825 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000826 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000827 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000828 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000829 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000830 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000831 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000832 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
833 // Check whether we have already looked into the parent directory
834 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000835 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000836 inferred = InferredDirectories.find(ParentDir);
837 if (inferred == InferredDirectories.end()) {
838 // We haven't looked here before. Load a module map, if there is
839 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000840 bool IsFrameworkDir = Parent.endswith(".framework");
841 if (const FileEntry *ModMapFile =
842 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000843 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000844 inferred = InferredDirectories.find(ParentDir);
845 }
846
847 if (inferred == InferredDirectories.end())
848 inferred = InferredDirectories.insert(
849 std::make_pair(ParentDir, InferredDirectory())).first;
850 }
851
852 if (inferred->second.InferModules) {
853 // We're allowed to infer for this directory, but make sure it's okay
854 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000855 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000856 canInfer = std::find(inferred->second.ExcludedModules.begin(),
857 inferred->second.ExcludedModules.end(),
858 Name) == inferred->second.ExcludedModules.end();
859
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000860 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
861 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
862 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000863 Attrs.NoUndeclaredIncludes |=
864 inferred->second.Attrs.NoUndeclaredIncludes;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000865 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000866 }
867 }
868 }
869
870 // If we're not allowed to infer a framework module, don't.
871 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000872 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000873 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000874 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000875
876
Douglas Gregor56c64012011-11-17 01:41:17 +0000877 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000878 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000879 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000880 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000881
882 // FIXME: If there's no umbrella header, we could probably scan the
883 // framework to load *everything*. But, it's not clear that this is a good
884 // idea.
885 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000886 return nullptr;
887
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000888 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000889 /*IsFramework=*/true, /*IsExplicit=*/false,
890 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000891 InferredModuleAllowedBy[Result] = ModuleMapFile;
892 Result->IsInferred = true;
Richard Smith7e82e012016-02-19 22:25:36 +0000893 if (!Parent) {
894 if (LangOpts.CurrentModule == ModuleName)
895 SourceModule = Result;
896 Modules[ModuleName] = Result;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000897 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000898
899 Result->IsSystem |= Attrs.IsSystem;
900 Result->IsExternC |= Attrs.IsExternC;
901 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +0000902 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Richard Smith2b63d152015-05-16 02:28:53 +0000903 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000904
Douglas Gregor322f6332011-12-08 18:00:48 +0000905 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000906 //
907 // The "Headers/" component of the name is implied because this is
908 // a framework module.
909 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
Douglas Gregord8bd7532011-12-05 17:40:25 +0000910
911 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000912 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
913
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000914 // module * { export * }
915 Result->InferSubmodules = true;
916 Result->InferExportWildcard = true;
917
Douglas Gregore89dbc12011-12-06 19:39:29 +0000918 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000919 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000920 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000921 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000922 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000923 llvm::sys::path::native(SubframeworksDirName);
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000924 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
925 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
926 DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000927 Dir != DirEnd && !EC; Dir.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000928 if (!StringRef(Dir->getName()).endswith(".framework"))
Douglas Gregore89dbc12011-12-06 19:39:29 +0000929 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000930
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +0000931 if (const DirectoryEntry *SubframeworkDir =
932 FileMgr.getDirectory(Dir->getName())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000933 // Note: as an egregious but useful hack, we use the real path here and
934 // check whether it is actually a subdirectory of the parent directory.
935 // This will not be the case if the 'subframework' is actually a symlink
936 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000937 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
938 bool FoundParent = false;
939 do {
940 // Get the parent directory name.
941 SubframeworkDirName
942 = llvm::sys::path::parent_path(SubframeworkDirName);
943 if (SubframeworkDirName.empty())
944 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000945
Douglas Gregore00c8b22013-01-26 00:55:12 +0000946 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
947 FoundParent = true;
948 break;
949 }
950 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000951
Douglas Gregore00c8b22013-01-26 00:55:12 +0000952 if (!FoundParent)
953 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000954
Douglas Gregore89dbc12011-12-06 19:39:29 +0000955 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000956 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000957 }
958 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000959
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000960 // If the module is a top-level framework, automatically link against the
961 // framework.
962 if (!Result->isSubFramework()) {
963 inferFrameworkLink(Result, FrameworkDir, FileMgr);
964 }
965
Douglas Gregor56c64012011-11-17 01:41:17 +0000966 return Result;
967}
968
Richard Smith2b63d152015-05-16 02:28:53 +0000969void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
970 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000971 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000972 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000973 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000974 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Bruno Cardoso Lopesb3a0fa42016-05-13 22:21:51 +0000975
976 // Notify callbacks that we just added a new header.
977 for (const auto &Cb : Callbacks)
978 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000979}
980
Richard Smith2b63d152015-05-16 02:28:53 +0000981void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
982 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000983 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000984 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000985 UmbrellaDirs[UmbrellaDir] = Mod;
986}
987
Richard Smith040e1262017-06-02 01:55:39 +0000988void ModuleMap::addUnresolvedHeader(Module *Mod,
989 Module::UnresolvedHeaderDirective Header) {
990 // If there is a builtin counterpart to this file, add it now so it can
991 // wrap the system header.
992 if (resolveAsBuiltinHeader(Mod, Header)) {
993 // If we have both a builtin and system version of the file, the
994 // builtin version may want to inject macros into the system header, so
995 // force the system header to be treated as a textual header in this
996 // case.
997 Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
998 headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
999 Header.HasBuiltinHeader = true;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +00001000 }
Richard Smith040e1262017-06-02 01:55:39 +00001001
1002 // If possible, don't stat the header until we need to. This requires the
1003 // user to have provided us with some stat information about the file.
1004 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1005 // headers.
1006 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1007 Header.Kind != Module::HK_Excluded) {
1008 // We expect more variation in mtime than size, so if we're given both,
1009 // use the mtime as the key.
1010 if (Header.ModTime)
1011 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1012 else
1013 LazyHeadersBySize[*Header.Size].push_back(Mod);
1014 Mod->UnresolvedHeaders.push_back(Header);
1015 return;
1016 }
1017
1018 // We don't have stat information or can't defer looking this file up.
1019 // Perform the lookup now.
1020 resolveHeader(Mod, Header);
1021}
1022
1023void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
1024 auto BySize = LazyHeadersBySize.find(File->getSize());
1025 if (BySize != LazyHeadersBySize.end()) {
1026 for (auto *M : BySize->second)
1027 resolveHeaderDirectives(M);
1028 LazyHeadersBySize.erase(BySize);
1029 }
1030
1031 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1032 if (ByModTime != LazyHeadersByModTime.end()) {
1033 for (auto *M : ByModTime->second)
1034 resolveHeaderDirectives(M);
1035 LazyHeadersByModTime.erase(ByModTime);
1036 }
1037}
1038
1039void ModuleMap::resolveHeaderDirectives(Module *Mod) const {
1040 for (auto &Header : Mod->UnresolvedHeaders)
1041 // This operation is logically const; we're just changing how we represent
1042 // the header information for this file.
1043 const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header);
1044 Mod->UnresolvedHeaders.clear();
Douglas Gregora89c5ac2011-12-06 01:10:29 +00001045}
1046
Richard Smith3c1a41a2014-12-02 00:08:08 +00001047void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +00001048 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +00001049 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +00001050
Richard Smith386bb072015-08-18 23:42:23 +00001051 // Only add each header to the headers list once.
1052 // FIXME: Should we diagnose if a header is listed twice in the
1053 // same module definition?
1054 auto &HeaderList = Headers[Header.Entry];
1055 for (auto H : HeaderList)
1056 if (H == KH)
1057 return;
1058
1059 HeaderList.push_back(KH);
Piotr Padlewski1ec383c2016-12-23 11:40:44 +00001060 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
Richard Smith386bb072015-08-18 23:42:23 +00001061
Richard Smith7e82e012016-02-19 22:25:36 +00001062 bool isCompilingModuleHeader =
Richard Smithbbcc9f02016-08-26 00:14:38 +00001063 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
Richard Smithd8879c82015-08-24 21:59:32 +00001064 if (!Imported || isCompilingModuleHeader) {
1065 // When we import HeaderFileInfo, the external source is expected to
1066 // set the isModuleHeader flag itself.
1067 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
1068 isCompilingModuleHeader);
1069 }
Bruno Cardoso Lopese62cfd72016-03-30 23:54:25 +00001070
1071 // Notify callbacks that we just added a new header.
1072 for (const auto &Cb : Callbacks)
Bruno Cardoso Lopesf0841792016-05-06 23:21:50 +00001073 Cb->moduleMapAddHeader(Header.Entry->getName());
Richard Smith3c1a41a2014-12-02 00:08:08 +00001074}
1075
1076void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +00001077 // Add this as a known header so we won't implicitly add it to any
1078 // umbrella directory module.
1079 // FIXME: Should we only exclude it from umbrella modules within the
1080 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +00001081 (void) Headers[Header.Entry];
1082
1083 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +00001084}
1085
Douglas Gregor514b6362011-11-29 19:06:37 +00001086const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001087ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00001088 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +00001089 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +00001090
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00001091 return SourceMgr.getFileEntryForID(
1092 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +00001093}
1094
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001095const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001096 if (M->IsInferred) {
1097 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1098 return InferredModuleAllowedBy.find(M)->second;
1099 }
1100 return getContainingModuleMapFile(M);
1101}
1102
1103void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
1104 assert(M->IsInferred && "module not inferred");
1105 InferredModuleAllowedBy[M] = ModMap;
1106}
1107
Yaron Kerencdae9412016-01-29 19:38:18 +00001108LLVM_DUMP_METHOD void ModuleMap::dump() {
Douglas Gregor718292f2011-11-11 19:10:28 +00001109 llvm::errs() << "Modules:";
1110 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1111 MEnd = Modules.end();
1112 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +00001113 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +00001114
1115 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +00001116 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +00001117 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001118 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
1119 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1120 E = H->second.end();
1121 I != E; ++I) {
1122 if (I != H->second.begin())
1123 llvm::errs() << ",";
1124 llvm::errs() << I->getModule()->getFullModuleName();
1125 }
1126 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +00001127 }
1128}
1129
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001130bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001131 auto Unresolved = std::move(Mod->UnresolvedExports);
1132 Mod->UnresolvedExports.clear();
1133 for (auto &UE : Unresolved) {
1134 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001135 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001136 Mod->Exports.push_back(Export);
1137 else
Richard Smith42413142015-05-15 20:05:43 +00001138 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001139 }
Richard Smith42413142015-05-15 20:05:43 +00001140 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001141}
1142
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001143bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001144 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
1145 Mod->UnresolvedDirectUses.clear();
1146 for (auto &UDU : Unresolved) {
1147 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001148 if (DirectUse)
1149 Mod->DirectUses.push_back(DirectUse);
1150 else
Richard Smith42413142015-05-15 20:05:43 +00001151 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001152 }
Richard Smith42413142015-05-15 20:05:43 +00001153 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001154}
1155
Douglas Gregorfb912652013-03-20 21:10:35 +00001156bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +00001157 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +00001158 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +00001159 for (auto &UC : Unresolved) {
1160 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1161 Module::Conflict Conflict;
1162 Conflict.Other = OtherMod;
1163 Conflict.Message = UC.Message;
1164 Mod->Conflicts.push_back(Conflict);
1165 } else
1166 Mod->UnresolvedConflicts.push_back(UC);
1167 }
1168 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +00001169}
1170
Douglas Gregor718292f2011-11-11 19:10:28 +00001171//----------------------------------------------------------------------------//
1172// Module map file parser
1173//----------------------------------------------------------------------------//
1174
1175namespace clang {
1176 /// \brief A token in a module map file.
1177 struct MMToken {
1178 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001179 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001180 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +00001181 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +00001182 EndOfFile,
1183 HeaderKeyword,
1184 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +00001185 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +00001186 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001187 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001188 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +00001189 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +00001190 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001191 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001192 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001193 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001194 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001195 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001196 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001197 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001198 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +00001199 StringLiteral,
Richard Smith040e1262017-06-02 01:55:39 +00001200 IntegerLiteral,
Richard Smith306d8922014-10-22 23:50:56 +00001201 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +00001202 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +00001203 RBrace,
1204 LSquare,
1205 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +00001206 } Kind;
1207
1208 unsigned Location;
1209 unsigned StringLength;
Richard Smith040e1262017-06-02 01:55:39 +00001210 union {
1211 // If Kind != IntegerLiteral.
1212 const char *StringData;
1213 // If Kind == IntegerLiteral.
1214 uint64_t IntegerValue;
1215 };
Douglas Gregor718292f2011-11-11 19:10:28 +00001216
1217 void clear() {
1218 Kind = EndOfFile;
1219 Location = 0;
1220 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +00001221 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +00001222 }
1223
1224 bool is(TokenKind K) const { return Kind == K; }
1225
1226 SourceLocation getLocation() const {
1227 return SourceLocation::getFromRawEncoding(Location);
1228 }
Richard Smith040e1262017-06-02 01:55:39 +00001229
1230 uint64_t getInteger() const {
1231 return Kind == IntegerLiteral ? IntegerValue : 0;
1232 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001233
1234 StringRef getString() const {
Richard Smith040e1262017-06-02 01:55:39 +00001235 return Kind == IntegerLiteral ? StringRef()
1236 : StringRef(StringData, StringLength);
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 }
1238 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001239
Douglas Gregor718292f2011-11-11 19:10:28 +00001240 class ModuleMapParser {
1241 Lexer &L;
1242 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001243
1244 /// \brief Default target information, used only for string literal
1245 /// parsing.
1246 const TargetInfo *Target;
1247
Douglas Gregor718292f2011-11-11 19:10:28 +00001248 DiagnosticsEngine &Diags;
1249 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001250
1251 /// \brief The current module map file.
1252 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001253
Richard Smith9acb99e32014-12-10 03:09:48 +00001254 /// \brief The directory that file names in this module map file should
1255 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001256 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001257
Douglas Gregor963c5532013-06-21 16:28:10 +00001258 /// \brief Whether this module map is in a system header directory.
1259 bool IsSystem;
1260
Douglas Gregor718292f2011-11-11 19:10:28 +00001261 /// \brief Whether an error occurred.
1262 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001263
Douglas Gregor718292f2011-11-11 19:10:28 +00001264 /// \brief Stores string data for the various string literals referenced
1265 /// during parsing.
1266 llvm::BumpPtrAllocator StringData;
1267
1268 /// \brief The current token.
1269 MMToken Tok;
1270
1271 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001272 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001273
1274 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1275 /// contents as 'textual'.
1276 ///
1277 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1278 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1279 /// non-modular headers. For backwards compatibility, we continue to
1280 /// support this idiom for just these modules, and map the headers to
1281 /// 'textual' to match the original intent.
1282 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1283
Douglas Gregor718292f2011-11-11 19:10:28 +00001284 /// \brief Consume the current token and return its location.
1285 SourceLocation consumeToken();
1286
1287 /// \brief Skip tokens until we reach the a token with the given kind
1288 /// (or the end of the file).
1289 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001290
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001291 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001292 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001293 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001294 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001295 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001296 void parseHeaderDecl(clang::MMToken::TokenKind,
1297 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001298 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001299 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001300 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001301 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001302 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001303 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001304 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001305
1306 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001307 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001308
Douglas Gregor718292f2011-11-11 19:10:28 +00001309 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001310 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001311 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001312 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001313 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001314 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001315 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001316 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001317 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001318 ModuleMapFile(ModuleMapFile), Directory(Directory),
Richard Smith1d609872017-05-26 00:01:53 +00001319 IsSystem(IsSystem), HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001320 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001321 Tok.clear();
1322 consumeToken();
1323 }
1324
1325 bool parseModuleMapFile();
Richard Smith8128f332017-05-05 22:18:51 +00001326
1327 bool terminatedByDirective() { return false; }
1328 SourceLocation getLocation() { return Tok.getLocation(); }
Douglas Gregor718292f2011-11-11 19:10:28 +00001329 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001330}
Douglas Gregor718292f2011-11-11 19:10:28 +00001331
1332SourceLocation ModuleMapParser::consumeToken() {
Douglas Gregor718292f2011-11-11 19:10:28 +00001333 SourceLocation Result = Tok.getLocation();
Richard Smith8128f332017-05-05 22:18:51 +00001334
1335retry:
Douglas Gregor718292f2011-11-11 19:10:28 +00001336 Tok.clear();
Douglas Gregor718292f2011-11-11 19:10:28 +00001337 Token LToken;
1338 L.LexFromRawLexer(LToken);
1339 Tok.Location = LToken.getLocation().getRawEncoding();
1340 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001341 case tok::raw_identifier: {
1342 StringRef RI = LToken.getRawIdentifier();
1343 Tok.StringData = RI.data();
1344 Tok.StringLength = RI.size();
1345 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001346 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001347 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001348 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001349 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001350 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001351 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001352 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001353 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001354 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001355 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001356 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001357 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001358 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001359 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001360 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001361 .Default(MMToken::Identifier);
1362 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001363 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001364
1365 case tok::comma:
1366 Tok.Kind = MMToken::Comma;
1367 break;
1368
Douglas Gregor718292f2011-11-11 19:10:28 +00001369 case tok::eof:
1370 Tok.Kind = MMToken::EndOfFile;
1371 break;
1372
1373 case tok::l_brace:
1374 Tok.Kind = MMToken::LBrace;
1375 break;
1376
Douglas Gregora686e1b2012-01-27 19:52:33 +00001377 case tok::l_square:
1378 Tok.Kind = MMToken::LSquare;
1379 break;
1380
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001381 case tok::period:
1382 Tok.Kind = MMToken::Period;
1383 break;
1384
Douglas Gregor718292f2011-11-11 19:10:28 +00001385 case tok::r_brace:
1386 Tok.Kind = MMToken::RBrace;
1387 break;
1388
Douglas Gregora686e1b2012-01-27 19:52:33 +00001389 case tok::r_square:
1390 Tok.Kind = MMToken::RSquare;
1391 break;
1392
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001393 case tok::star:
1394 Tok.Kind = MMToken::Star;
1395 break;
1396
Richard Smitha3feee22013-10-28 22:18:19 +00001397 case tok::exclaim:
1398 Tok.Kind = MMToken::Exclaim;
1399 break;
1400
Douglas Gregor718292f2011-11-11 19:10:28 +00001401 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001402 if (LToken.hasUDSuffix()) {
1403 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1404 HadError = true;
1405 goto retry;
1406 }
1407
Douglas Gregor718292f2011-11-11 19:10:28 +00001408 // Parse the string literal.
1409 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001410 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001411 if (StringLiteral.hadError)
1412 goto retry;
1413
1414 // Copy the string literal into our string data allocator.
1415 unsigned Length = StringLiteral.GetStringLength();
1416 char *Saved = StringData.Allocate<char>(Length + 1);
1417 memcpy(Saved, StringLiteral.GetString().data(), Length);
1418 Saved[Length] = 0;
1419
1420 // Form the token.
1421 Tok.Kind = MMToken::StringLiteral;
1422 Tok.StringData = Saved;
1423 Tok.StringLength = Length;
1424 break;
1425 }
Richard Smith040e1262017-06-02 01:55:39 +00001426
1427 case tok::numeric_constant: {
1428 // We don't support any suffixes or other complications.
1429 SmallString<32> SpellingBuffer;
1430 SpellingBuffer.resize(LToken.getLength() + 1);
1431 const char *Start = SpellingBuffer.data();
1432 unsigned Length =
1433 Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts());
1434 uint64_t Value;
1435 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1436 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1437 HadError = true;
1438 goto retry;
1439 }
1440
1441 Tok.Kind = MMToken::IntegerLiteral;
1442 Tok.IntegerValue = Value;
1443 break;
1444 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001445
1446 case tok::comment:
1447 goto retry;
Richard Smith8128f332017-05-05 22:18:51 +00001448
1449 case tok::hash:
1450 // A module map can be terminated prematurely by
1451 // #pragma clang module contents
1452 // When building the module, we'll treat the rest of the file as the
1453 // contents of the module.
1454 {
1455 auto NextIsIdent = [&](StringRef Str) -> bool {
1456 L.LexFromRawLexer(LToken);
1457 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1458 LToken.getRawIdentifier() == Str;
1459 };
1460 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1461 NextIsIdent("module") && NextIsIdent("contents")) {
1462 Tok.Kind = MMToken::EndOfFile;
1463 break;
1464 }
1465 }
1466 LLVM_FALLTHROUGH;
1467
Douglas Gregor718292f2011-11-11 19:10:28 +00001468 default:
Richard Smith8128f332017-05-05 22:18:51 +00001469 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
Douglas Gregor718292f2011-11-11 19:10:28 +00001470 HadError = true;
1471 goto retry;
1472 }
1473
1474 return Result;
1475}
1476
1477void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1478 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001479 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001480 do {
1481 switch (Tok.Kind) {
1482 case MMToken::EndOfFile:
1483 return;
1484
1485 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001486 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001487 return;
1488
1489 ++braceDepth;
1490 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001491
1492 case MMToken::LSquare:
1493 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1494 return;
1495
1496 ++squareDepth;
1497 break;
1498
Douglas Gregor718292f2011-11-11 19:10:28 +00001499 case MMToken::RBrace:
1500 if (braceDepth > 0)
1501 --braceDepth;
1502 else if (Tok.is(K))
1503 return;
1504 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001505
1506 case MMToken::RSquare:
1507 if (squareDepth > 0)
1508 --squareDepth;
1509 else if (Tok.is(K))
1510 return;
1511 break;
1512
Douglas Gregor718292f2011-11-11 19:10:28 +00001513 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001514 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001515 return;
1516 break;
1517 }
1518
1519 consumeToken();
1520 } while (true);
1521}
1522
Douglas Gregore7ab3662011-12-07 02:23:45 +00001523/// \brief Parse a module-id.
1524///
1525/// module-id:
1526/// identifier
1527/// identifier '.' module-id
1528///
1529/// \returns true if an error occurred, false otherwise.
1530bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1531 Id.clear();
1532 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001533 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001534 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1535 consumeToken();
1536 } else {
1537 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1538 return true;
1539 }
1540
1541 if (!Tok.is(MMToken::Period))
1542 break;
1543
1544 consumeToken();
1545 } while (true);
1546
1547 return false;
1548}
1549
Douglas Gregora686e1b2012-01-27 19:52:33 +00001550namespace {
1551 /// \brief Enumerates the known attributes.
1552 enum AttributeKind {
1553 /// \brief An unknown attribute.
1554 AT_unknown,
1555 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001556 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001557 /// \brief The 'extern_c' attribute.
1558 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001559 /// \brief The 'exhaustive' attribute.
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001560 AT_exhaustive,
1561 /// \brief The 'no_undeclared_includes' attribute.
1562 AT_no_undeclared_includes
Douglas Gregora686e1b2012-01-27 19:52:33 +00001563 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001564}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001565
Douglas Gregor718292f2011-11-11 19:10:28 +00001566/// \brief Parse a module declaration.
1567///
1568/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001569/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001570/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1571/// { module-member* }
1572///
Douglas Gregor718292f2011-11-11 19:10:28 +00001573/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001574/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001575/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001576/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001577/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001578/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001579///
1580/// submodule-declaration:
1581/// module-declaration
1582/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001583void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001584 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001585 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1586 if (Tok.is(MMToken::ExternKeyword)) {
1587 parseExternModuleDecl();
1588 return;
1589 }
1590
Douglas Gregorf2161a72011-12-06 17:16:41 +00001591 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001592 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001593 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001594 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001595
Douglas Gregorf2161a72011-12-06 17:16:41 +00001596 // Parse 'explicit' keyword, if present.
1597 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001598 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001599 Explicit = true;
1600 }
1601
1602 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001603 if (Tok.is(MMToken::FrameworkKeyword)) {
1604 consumeToken();
1605 Framework = true;
1606 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001607
1608 // Parse 'module' keyword.
1609 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001610 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001611 consumeToken();
1612 HadError = true;
1613 return;
1614 }
1615 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001616
1617 // If we have a wildcard for the module name, this is an inferred submodule.
1618 // Parse it.
1619 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001620 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001621
1622 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001623 ModuleId Id;
1624 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001625 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001626 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001627 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001628
Douglas Gregore7ab3662011-12-07 02:23:45 +00001629 if (ActiveModule) {
1630 if (Id.size() > 1) {
1631 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1632 << SourceRange(Id.front().second, Id.back().second);
1633
1634 HadError = true;
1635 return;
1636 }
1637 } else if (Id.size() == 1 && Explicit) {
1638 // Top-level modules can't be explicit.
1639 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1640 Explicit = false;
1641 ExplicitLoc = SourceLocation();
1642 HadError = true;
1643 }
1644
1645 Module *PreviousActiveModule = ActiveModule;
1646 if (Id.size() > 1) {
1647 // This module map defines a submodule. Go find the module of which it
1648 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001649 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001650 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001651 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1652 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001653 if (I == 0)
1654 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001655 ActiveModule = Next;
1656 continue;
1657 }
1658
1659 if (ActiveModule) {
1660 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001661 << Id[I].first
1662 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001663 } else {
1664 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1665 }
1666 HadError = true;
1667 return;
1668 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001669
1670 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1671 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1672 "submodule defined in same file as 'module *' that allowed its "
1673 "top-level module");
1674 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1675 }
1676 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001677
1678 StringRef ModuleName = Id.back().first;
1679 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001680
Douglas Gregora686e1b2012-01-27 19:52:33 +00001681 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001682 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00001683 if (parseOptionalAttributes(Attrs))
1684 return;
1685
Douglas Gregora686e1b2012-01-27 19:52:33 +00001686
Douglas Gregor718292f2011-11-11 19:10:28 +00001687 // Parse the opening brace.
1688 if (!Tok.is(MMToken::LBrace)) {
1689 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1690 << ModuleName;
1691 HadError = true;
1692 return;
1693 }
1694 SourceLocation LBraceLoc = consumeToken();
1695
1696 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001697 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Richard Smith4a3751f2017-05-08 20:30:47 +00001698 // We might see a (re)definition of a module that we already have a
1699 // definition for in two cases:
1700 // - If we loaded one definition from an AST file and we've just found a
1701 // corresponding definition in a module map file, or
1702 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
1703 // - If we're building a (preprocessed) module and we've just loaded the
1704 // module map file from which it was created.
1705 bool ParsedAsMainInput =
1706 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
1707 Map.LangOpts.CurrentModule == ModuleName &&
1708 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
1709 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
1710 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001711 // Skip the module definition.
1712 skipUntil(MMToken::RBrace);
1713 if (Tok.is(MMToken::RBrace))
1714 consumeToken();
1715 else {
1716 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1717 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1718 HadError = true;
1719 }
1720 return;
1721 }
1722
Douglas Gregor718292f2011-11-11 19:10:28 +00001723 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1724 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001725 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001726
1727 // Skip the module definition.
1728 skipUntil(MMToken::RBrace);
1729 if (Tok.is(MMToken::RBrace))
1730 consumeToken();
1731
1732 HadError = true;
1733 return;
1734 }
1735
1736 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001737 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1738 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001739 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001740 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001741 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001742 if (Attrs.IsExternC)
1743 ActiveModule->IsExternC = true;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00001744 if (Attrs.NoUndeclaredIncludes ||
1745 (!ActiveModule->Parent && ModuleName == "Darwin"))
1746 ActiveModule->NoUndeclaredIncludes = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001747 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001748
Graydon Hoare4d867642016-12-21 00:24:39 +00001749 if (!ActiveModule->Parent) {
1750 StringRef MapFileName(ModuleMapFile->getName());
1751 if (MapFileName.endswith("module.private.modulemap") ||
1752 MapFileName.endswith("module_private.map")) {
1753 // Adding a top-level module from a private modulemap is likely a
1754 // user error; we check to see if there's another top-level module
1755 // defined in the non-private map in the same dir, and if so emit a
1756 // warning.
1757 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1758 auto const *M = E->getValue();
1759 if (!M->Parent &&
1760 M->Directory == ActiveModule->Directory &&
1761 M->Name != ActiveModule->Name) {
1762 Diags.Report(ActiveModule->DefinitionLoc,
1763 diag::warn_mmap_mismatched_top_level_private)
1764 << ActiveModule->Name << M->Name;
1765 // The pattern we're defending against here is typically due to
1766 // a module named FooPrivate which is supposed to be a submodule
1767 // called Foo.Private. Emit a fixit in that case.
1768 auto D =
1769 Diags.Report(ActiveModule->DefinitionLoc,
1770 diag::note_mmap_rename_top_level_private_as_submodule);
1771 D << ActiveModule->Name << M->Name;
1772 StringRef Bad(ActiveModule->Name);
1773 if (Bad.consume_back("Private")) {
1774 SmallString<128> Fixed = Bad;
1775 Fixed.append(".Private");
1776 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
1777 Fixed);
1778 }
1779 break;
1780 }
1781 }
1782 }
1783 }
1784
Douglas Gregor718292f2011-11-11 19:10:28 +00001785 bool Done = false;
1786 do {
1787 switch (Tok.Kind) {
1788 case MMToken::EndOfFile:
1789 case MMToken::RBrace:
1790 Done = true;
1791 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001792
1793 case MMToken::ConfigMacros:
1794 parseConfigMacros();
1795 break;
1796
Douglas Gregorfb912652013-03-20 21:10:35 +00001797 case MMToken::Conflict:
1798 parseConflict();
1799 break;
1800
Douglas Gregor718292f2011-11-11 19:10:28 +00001801 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001802 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001803 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001804 case MMToken::ModuleKeyword:
1805 parseModuleDecl();
1806 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001807
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001808 case MMToken::ExportKeyword:
1809 parseExportDecl();
1810 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001811
1812 case MMToken::UseKeyword:
1813 parseUseDecl();
1814 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001815
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001816 case MMToken::RequiresKeyword:
1817 parseRequiresDecl();
1818 break;
1819
Richard Smith202210b2014-10-24 20:23:01 +00001820 case MMToken::TextualKeyword:
1821 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001822 break;
Richard Smith306d8922014-10-22 23:50:56 +00001823
Douglas Gregor524e33e2011-12-08 19:11:24 +00001824 case MMToken::UmbrellaKeyword: {
1825 SourceLocation UmbrellaLoc = consumeToken();
1826 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001827 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001828 else
1829 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001830 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001831 }
Richard Smith202210b2014-10-24 20:23:01 +00001832
1833 case MMToken::ExcludeKeyword:
1834 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001835 break;
Richard Smith202210b2014-10-24 20:23:01 +00001836
1837 case MMToken::PrivateKeyword:
1838 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001839 break;
Richard Smith202210b2014-10-24 20:23:01 +00001840
Douglas Gregor322f6332011-12-08 18:00:48 +00001841 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001842 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001843 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001844
1845 case MMToken::LinkKeyword:
1846 parseLinkDecl();
1847 break;
1848
Douglas Gregor718292f2011-11-11 19:10:28 +00001849 default:
1850 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1851 consumeToken();
1852 break;
1853 }
1854 } while (!Done);
1855
1856 if (Tok.is(MMToken::RBrace))
1857 consumeToken();
1858 else {
1859 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1860 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1861 HadError = true;
1862 }
1863
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001864 // If the active module is a top-level framework, and there are no link
1865 // libraries, automatically link against the framework.
1866 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1867 ActiveModule->LinkLibraries.empty()) {
1868 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1869 }
1870
Ben Langmuirec8c9752014-04-18 22:07:31 +00001871 // If the module meets all requirements but is still unavailable, mark the
1872 // whole tree as unavailable to prevent it from building.
1873 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1874 ActiveModule->Parent) {
1875 ActiveModule->getTopLevelModule()->markUnavailable();
1876 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1877 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1878 }
1879
Douglas Gregore7ab3662011-12-07 02:23:45 +00001880 // We're done parsing this module. Pop back to the previous module.
1881 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001882}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001883
Daniel Jasper97292842013-09-11 07:20:44 +00001884/// \brief Parse an extern module declaration.
1885///
1886/// extern module-declaration:
1887/// 'extern' 'module' module-id string-literal
1888void ModuleMapParser::parseExternModuleDecl() {
1889 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001890 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001891
1892 // Parse 'module' keyword.
1893 if (!Tok.is(MMToken::ModuleKeyword)) {
1894 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1895 consumeToken();
1896 HadError = true;
1897 return;
1898 }
1899 consumeToken(); // 'module' keyword
1900
1901 // Parse the module name.
1902 ModuleId Id;
1903 if (parseModuleId(Id)) {
1904 HadError = true;
1905 return;
1906 }
1907
1908 // Parse the referenced module map file name.
1909 if (!Tok.is(MMToken::StringLiteral)) {
1910 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1911 HadError = true;
1912 return;
1913 }
1914 std::string FileName = Tok.getString();
1915 consumeToken(); // filename
1916
1917 StringRef FileNameRef = FileName;
1918 SmallString<128> ModuleMapFileName;
1919 if (llvm::sys::path::is_relative(FileNameRef)) {
1920 ModuleMapFileName += Directory->getName();
1921 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001922 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001923 }
1924 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001925 Map.parseModuleMapFile(
1926 File, /*IsSystem=*/false,
1927 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1928 ? Directory
Richard Smith8128f332017-05-05 22:18:51 +00001929 : File->getDir(),
1930 FileID(), nullptr, ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001931}
1932
Ben Langmuir7ff29142015-08-13 17:13:33 +00001933/// Whether to add the requirement \p Feature to the module \p M.
1934///
1935/// This preserves backwards compatibility for two hacks in the Darwin system
1936/// module map files:
1937///
1938/// 1. The use of 'requires excluded' to make headers non-modular, which
1939/// should really be mapped to 'textual' now that we have this feature. We
1940/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1941/// true. Later, this bit will be used to map all the headers inside this
1942/// module to 'textual'.
1943///
1944/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1945///
1946/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1947/// was never correct and causes issues now that we check it, so drop it.
1948static bool shouldAddRequirement(Module *M, StringRef Feature,
1949 bool &IsRequiresExcludedHack) {
Benjamin Kramer8013e812016-11-15 18:56:39 +00001950 if (Feature == "excluded" &&
1951 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
1952 M->fullModuleNameIs({"Tcl", "Private"}))) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00001953 IsRequiresExcludedHack = true;
1954 return false;
Benjamin Kramer8013e812016-11-15 18:56:39 +00001955 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00001956 return false;
1957 }
1958
1959 return true;
1960}
1961
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001962/// \brief Parse a requires declaration.
1963///
1964/// requires-declaration:
1965/// 'requires' feature-list
1966///
1967/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001968/// feature ',' feature-list
1969/// feature
1970///
1971/// feature:
1972/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001973void ModuleMapParser::parseRequiresDecl() {
1974 assert(Tok.is(MMToken::RequiresKeyword));
1975
1976 // Parse 'requires' keyword.
1977 consumeToken();
1978
1979 // Parse the feature-list.
1980 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001981 bool RequiredState = true;
1982 if (Tok.is(MMToken::Exclaim)) {
1983 RequiredState = false;
1984 consumeToken();
1985 }
1986
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001987 if (!Tok.is(MMToken::Identifier)) {
1988 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1989 HadError = true;
1990 return;
1991 }
1992
1993 // Consume the feature name.
1994 std::string Feature = Tok.getString();
1995 consumeToken();
1996
Ben Langmuir7ff29142015-08-13 17:13:33 +00001997 bool IsRequiresExcludedHack = false;
1998 bool ShouldAddRequirement =
1999 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
2000
2001 if (IsRequiresExcludedHack)
2002 UsesRequiresExcludedHack.insert(ActiveModule);
2003
2004 if (ShouldAddRequirement) {
2005 // Add this feature.
2006 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2007 *Map.Target);
2008 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002009
2010 if (!Tok.is(MMToken::Comma))
2011 break;
2012
2013 // Consume the comma.
2014 consumeToken();
2015 } while (true);
2016}
2017
Douglas Gregor718292f2011-11-11 19:10:28 +00002018/// \brief Parse a header declaration.
2019///
2020/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00002021/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00002022/// 'private' 'textual'[opt] 'header' string-literal
2023/// 'exclude' 'header' string-literal
2024/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00002025///
2026/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002027void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
2028 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00002029 // We've already consumed the first token.
2030 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
2031 if (LeadingToken == MMToken::PrivateKeyword) {
2032 Role = ModuleMap::PrivateHeader;
2033 // 'private' may optionally be followed by 'textual'.
2034 if (Tok.is(MMToken::TextualKeyword)) {
2035 LeadingToken = Tok.Kind;
2036 consumeToken();
2037 }
2038 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00002039
Richard Smith202210b2014-10-24 20:23:01 +00002040 if (LeadingToken == MMToken::TextualKeyword)
2041 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2042
Ben Langmuir7ff29142015-08-13 17:13:33 +00002043 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2044 // Mark this header 'textual' (see doc comment for
2045 // Module::UsesRequiresExcludedHack).
2046 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2047 }
2048
Richard Smith202210b2014-10-24 20:23:01 +00002049 if (LeadingToken != MMToken::HeaderKeyword) {
2050 if (!Tok.is(MMToken::HeaderKeyword)) {
2051 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2052 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
2053 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
2054 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
2055 return;
2056 }
2057 consumeToken();
2058 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00002059
Douglas Gregor718292f2011-11-11 19:10:28 +00002060 // Parse the header name.
2061 if (!Tok.is(MMToken::StringLiteral)) {
2062 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2063 << "header";
2064 HadError = true;
2065 return;
2066 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00002067 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002068 Header.FileName = Tok.getString();
2069 Header.FileNameLoc = consumeToken();
Richard Smith1d609872017-05-26 00:01:53 +00002070 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Richard Smith040e1262017-06-02 01:55:39 +00002071 Header.Kind =
2072 (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded
2073 : Map.headerRoleToKind(Role));
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00002074
Douglas Gregor524e33e2011-12-08 19:11:24 +00002075 // Check whether we already have an umbrella.
Richard Smith1d609872017-05-26 00:01:53 +00002076 if (Header.IsUmbrella && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002077 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00002078 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00002079 HadError = true;
2080 return;
2081 }
2082
Richard Smith040e1262017-06-02 01:55:39 +00002083 // If we were given stat information, parse it so we can skip looking for
2084 // the file.
2085 if (Tok.is(MMToken::LBrace)) {
2086 SourceLocation LBraceLoc = consumeToken();
Bruno Cardoso Lopes08ebd612017-03-21 16:43:51 +00002087
Richard Smith040e1262017-06-02 01:55:39 +00002088 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
2089 enum Attribute { Size, ModTime, Unknown };
2090 StringRef Str = Tok.getString();
2091 SourceLocation Loc = consumeToken();
2092 switch (llvm::StringSwitch<Attribute>(Str)
2093 .Case("size", Size)
2094 .Case("mtime", ModTime)
2095 .Default(Unknown)) {
2096 case Size:
2097 if (Header.Size)
2098 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2099 if (!Tok.is(MMToken::IntegerLiteral)) {
2100 Diags.Report(Tok.getLocation(),
2101 diag::err_mmap_invalid_header_attribute_value) << Str;
2102 skipUntil(MMToken::RBrace);
2103 break;
2104 }
2105 Header.Size = Tok.getInteger();
2106 consumeToken();
2107 break;
Richard Smith3c1a41a2014-12-02 00:08:08 +00002108
Richard Smith040e1262017-06-02 01:55:39 +00002109 case ModTime:
2110 if (Header.ModTime)
2111 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2112 if (!Tok.is(MMToken::IntegerLiteral)) {
2113 Diags.Report(Tok.getLocation(),
2114 diag::err_mmap_invalid_header_attribute_value) << Str;
2115 skipUntil(MMToken::RBrace);
2116 break;
2117 }
2118 Header.ModTime = Tok.getInteger();
2119 consumeToken();
2120 break;
2121
2122 case Unknown:
2123 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2124 skipUntil(MMToken::RBrace);
2125 break;
Douglas Gregor322f6332011-12-08 18:00:48 +00002126 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00002127 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002128
Richard Smith040e1262017-06-02 01:55:39 +00002129 if (Tok.is(MMToken::RBrace))
2130 consumeToken();
2131 else {
2132 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2133 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2134 HadError = true;
2135 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00002136 }
Richard Smith040e1262017-06-02 01:55:39 +00002137
2138 Map.addUnresolvedHeader(ActiveModule, std::move(Header));
Douglas Gregor718292f2011-11-11 19:10:28 +00002139}
2140
Ben Langmuir41f81992015-08-13 17:30:07 +00002141static int compareModuleHeaders(const Module::Header *A,
2142 const Module::Header *B) {
2143 return A->NameAsWritten.compare(B->NameAsWritten);
2144}
2145
Douglas Gregor524e33e2011-12-08 19:11:24 +00002146/// \brief Parse an umbrella directory declaration.
2147///
2148/// umbrella-dir-declaration:
2149/// umbrella string-literal
2150void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
2151 // Parse the directory name.
2152 if (!Tok.is(MMToken::StringLiteral)) {
2153 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2154 << "umbrella";
2155 HadError = true;
2156 return;
2157 }
2158
2159 std::string DirName = Tok.getString();
2160 SourceLocation DirNameLoc = consumeToken();
2161
2162 // Check whether we already have an umbrella.
2163 if (ActiveModule->Umbrella) {
2164 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2165 << ActiveModule->getFullModuleName();
2166 HadError = true;
2167 return;
2168 }
2169
2170 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00002171 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002172 if (llvm::sys::path::is_absolute(DirName))
2173 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2174 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00002175 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002176 PathName = Directory->getName();
2177 llvm::sys::path::append(PathName, DirName);
2178 Dir = SourceMgr.getFileManager().getDirectory(PathName);
2179 }
2180
2181 if (!Dir) {
Vassil Vassileva0320b92017-04-18 20:57:29 +00002182 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
Douglas Gregor524e33e2011-12-08 19:11:24 +00002183 << DirName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00002184 return;
2185 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00002186
2187 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2188 // Mark this header 'textual' (see doc comment for
2189 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2190 // directory is relatively expensive, in practice this only applies to the
2191 // uncommonly used Tcl module on Darwin platforms.
2192 std::error_code EC;
2193 SmallVector<Module::Header, 6> Headers;
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002194 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
2195 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002196 I != E && !EC; I.increment(EC)) {
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002197 if (const FileEntry *FE =
2198 SourceMgr.getFileManager().getFile(I->getName())) {
Ben Langmuir7ff29142015-08-13 17:13:33 +00002199
Bruno Cardoso Lopesb171a592016-05-16 16:46:01 +00002200 Module::Header Header = {I->getName(), FE};
Ben Langmuir7ff29142015-08-13 17:13:33 +00002201 Headers.push_back(std::move(Header));
2202 }
2203 }
2204
2205 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00002206 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2207
Ben Langmuir7ff29142015-08-13 17:13:33 +00002208 for (auto &Header : Headers)
2209 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2210 return;
2211 }
2212
Douglas Gregor524e33e2011-12-08 19:11:24 +00002213 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2214 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2215 << OwningModule->getFullModuleName();
2216 HadError = true;
2217 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00002218 }
2219
Douglas Gregor524e33e2011-12-08 19:11:24 +00002220 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00002221 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00002222}
2223
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002224/// \brief Parse a module export declaration.
2225///
2226/// export-declaration:
2227/// 'export' wildcard-module-id
2228///
2229/// wildcard-module-id:
2230/// identifier
2231/// '*'
2232/// identifier '.' wildcard-module-id
2233void ModuleMapParser::parseExportDecl() {
2234 assert(Tok.is(MMToken::ExportKeyword));
2235 SourceLocation ExportLoc = consumeToken();
2236
2237 // Parse the module-id with an optional wildcard at the end.
2238 ModuleId ParsedModuleId;
2239 bool Wildcard = false;
2240 do {
Richard Smith306d8922014-10-22 23:50:56 +00002241 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002242 if (Tok.is(MMToken::Identifier)) {
2243 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
2244 Tok.getLocation()));
2245 consumeToken();
2246
2247 if (Tok.is(MMToken::Period)) {
2248 consumeToken();
2249 continue;
2250 }
2251
2252 break;
2253 }
2254
2255 if(Tok.is(MMToken::Star)) {
2256 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00002257 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002258 break;
2259 }
2260
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002261 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002262 HadError = true;
2263 return;
2264 } while (true);
2265
2266 Module::UnresolvedExportDecl Unresolved = {
2267 ExportLoc, ParsedModuleId, Wildcard
2268 };
2269 ActiveModule->UnresolvedExports.push_back(Unresolved);
2270}
2271
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002272/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002273///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002274/// use-declaration:
2275/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002276void ModuleMapParser::parseUseDecl() {
2277 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002278 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002279 // Parse the module-id.
2280 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002281 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002282
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002283 if (ActiveModule->Parent)
2284 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2285 else
2286 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002287}
2288
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002289/// \brief Parse a link declaration.
2290///
2291/// module-declaration:
2292/// 'link' 'framework'[opt] string-literal
2293void ModuleMapParser::parseLinkDecl() {
2294 assert(Tok.is(MMToken::LinkKeyword));
2295 SourceLocation LinkLoc = consumeToken();
2296
2297 // Parse the optional 'framework' keyword.
2298 bool IsFramework = false;
2299 if (Tok.is(MMToken::FrameworkKeyword)) {
2300 consumeToken();
2301 IsFramework = true;
2302 }
2303
2304 // Parse the library name
2305 if (!Tok.is(MMToken::StringLiteral)) {
2306 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2307 << IsFramework << SourceRange(LinkLoc);
2308 HadError = true;
2309 return;
2310 }
2311
2312 std::string LibraryName = Tok.getString();
2313 consumeToken();
2314 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2315 IsFramework));
2316}
2317
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002318/// \brief Parse a configuration macro declaration.
2319///
2320/// module-declaration:
2321/// 'config_macros' attributes[opt] config-macro-list?
2322///
2323/// config-macro-list:
2324/// identifier (',' identifier)?
2325void ModuleMapParser::parseConfigMacros() {
2326 assert(Tok.is(MMToken::ConfigMacros));
2327 SourceLocation ConfigMacrosLoc = consumeToken();
2328
2329 // Only top-level modules can have configuration macros.
2330 if (ActiveModule->Parent) {
2331 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2332 }
2333
2334 // Parse the optional attributes.
2335 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002336 if (parseOptionalAttributes(Attrs))
2337 return;
2338
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002339 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2340 ActiveModule->ConfigMacrosExhaustive = true;
2341 }
2342
2343 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002344 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002345 if (!Tok.is(MMToken::Identifier))
2346 return;
2347
2348 // Consume the first identifier.
2349 if (!ActiveModule->Parent) {
2350 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2351 }
2352 consumeToken();
2353
2354 do {
2355 // If there's a comma, consume it.
2356 if (!Tok.is(MMToken::Comma))
2357 break;
2358 consumeToken();
2359
2360 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002361 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002362 if (!Tok.is(MMToken::Identifier)) {
2363 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2364 break;
2365 }
2366
2367 // Consume the macro name.
2368 if (!ActiveModule->Parent) {
2369 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2370 }
2371 consumeToken();
2372 } while (true);
2373}
2374
Douglas Gregorfb912652013-03-20 21:10:35 +00002375/// \brief Format a module-id into a string.
2376static std::string formatModuleId(const ModuleId &Id) {
2377 std::string result;
2378 {
2379 llvm::raw_string_ostream OS(result);
2380
2381 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2382 if (I)
2383 OS << ".";
2384 OS << Id[I].first;
2385 }
2386 }
2387
2388 return result;
2389}
2390
2391/// \brief Parse a conflict declaration.
2392///
2393/// module-declaration:
2394/// 'conflict' module-id ',' string-literal
2395void ModuleMapParser::parseConflict() {
2396 assert(Tok.is(MMToken::Conflict));
2397 SourceLocation ConflictLoc = consumeToken();
2398 Module::UnresolvedConflict Conflict;
2399
2400 // Parse the module-id.
2401 if (parseModuleId(Conflict.Id))
2402 return;
2403
2404 // Parse the ','.
2405 if (!Tok.is(MMToken::Comma)) {
2406 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2407 << SourceRange(ConflictLoc);
2408 return;
2409 }
2410 consumeToken();
2411
2412 // Parse the message.
2413 if (!Tok.is(MMToken::StringLiteral)) {
2414 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2415 << formatModuleId(Conflict.Id);
2416 return;
2417 }
2418 Conflict.Message = Tok.getString().str();
2419 consumeToken();
2420
2421 // Add this unresolved conflict.
2422 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2423}
2424
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002425/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002426///
2427/// module-declaration:
2428/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2429/// { inferred-module-member* }
2430///
2431/// inferred-module-member:
2432/// 'export' '*'
2433/// 'exclude' identifier
2434void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002435 assert(Tok.is(MMToken::Star));
2436 SourceLocation StarLoc = consumeToken();
2437 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002438
Douglas Gregor73441092011-12-05 22:27:44 +00002439 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002440 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002441 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2442 Failed = true;
2443 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002444
2445 if (ActiveModule) {
2446 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002447 if (!Failed && ActiveModule->IsAvailable &&
2448 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002449 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2450 Failed = true;
2451 }
2452
2453 // Check for redefinition of an inferred module.
2454 if (!Failed && ActiveModule->InferSubmodules) {
2455 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2456 if (ActiveModule->InferredSubmoduleLoc.isValid())
2457 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2458 diag::note_mmap_prev_definition);
2459 Failed = true;
2460 }
2461
2462 // Check for the 'framework' keyword, which is not permitted here.
2463 if (Framework) {
2464 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2465 Framework = false;
2466 }
2467 } else if (Explicit) {
2468 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2469 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002470 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002471
Douglas Gregor73441092011-12-05 22:27:44 +00002472 // If there were any problems with this inferred submodule, skip its body.
2473 if (Failed) {
2474 if (Tok.is(MMToken::LBrace)) {
2475 consumeToken();
2476 skipUntil(MMToken::RBrace);
2477 if (Tok.is(MMToken::RBrace))
2478 consumeToken();
2479 }
2480 HadError = true;
2481 return;
2482 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002483
2484 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002485 Attributes Attrs;
Davide Italiano5d29dee2016-03-06 04:20:05 +00002486 if (parseOptionalAttributes(Attrs))
2487 return;
Douglas Gregor9194a912012-11-06 19:39:40 +00002488
2489 if (ActiveModule) {
2490 // Note that we have an inferred submodule.
2491 ActiveModule->InferSubmodules = true;
2492 ActiveModule->InferredSubmoduleLoc = StarLoc;
2493 ActiveModule->InferExplicitSubmodules = Explicit;
2494 } else {
2495 // We'll be inferring framework modules for this directory.
2496 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002497 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002498 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002499 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002500 }
2501
Douglas Gregor73441092011-12-05 22:27:44 +00002502 // Parse the opening brace.
2503 if (!Tok.is(MMToken::LBrace)) {
2504 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2505 HadError = true;
2506 return;
2507 }
2508 SourceLocation LBraceLoc = consumeToken();
2509
2510 // Parse the body of the inferred submodule.
2511 bool Done = false;
2512 do {
2513 switch (Tok.Kind) {
2514 case MMToken::EndOfFile:
2515 case MMToken::RBrace:
2516 Done = true;
2517 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002518
2519 case MMToken::ExcludeKeyword: {
2520 if (ActiveModule) {
2521 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002522 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002523 consumeToken();
2524 break;
2525 }
2526
2527 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002528 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002529 if (!Tok.is(MMToken::Identifier)) {
2530 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2531 break;
2532 }
2533
2534 Map.InferredDirectories[Directory].ExcludedModules
2535 .push_back(Tok.getString());
2536 consumeToken();
2537 break;
2538 }
2539
2540 case MMToken::ExportKeyword:
2541 if (!ActiveModule) {
2542 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002543 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002544 consumeToken();
2545 break;
2546 }
2547
Douglas Gregor73441092011-12-05 22:27:44 +00002548 consumeToken();
2549 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002550 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002551 else
2552 Diags.Report(Tok.getLocation(),
2553 diag::err_mmap_expected_export_wildcard);
2554 consumeToken();
2555 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002556
Douglas Gregor73441092011-12-05 22:27:44 +00002557 case MMToken::ExplicitKeyword:
2558 case MMToken::ModuleKeyword:
2559 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002560 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002561 case MMToken::UmbrellaKeyword:
2562 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002563 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002564 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002565 consumeToken();
2566 break;
2567 }
2568 } while (!Done);
2569
2570 if (Tok.is(MMToken::RBrace))
2571 consumeToken();
2572 else {
2573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2574 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2575 HadError = true;
2576 }
2577}
2578
Douglas Gregor9194a912012-11-06 19:39:40 +00002579/// \brief Parse optional attributes.
2580///
2581/// attributes:
2582/// attribute attributes
2583/// attribute
2584///
2585/// attribute:
2586/// [ identifier ]
2587///
2588/// \param Attrs Will be filled in with the parsed attributes.
2589///
2590/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002591bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002592 bool HadError = false;
2593
2594 while (Tok.is(MMToken::LSquare)) {
2595 // Consume the '['.
2596 SourceLocation LSquareLoc = consumeToken();
2597
2598 // Check whether we have an attribute name here.
2599 if (!Tok.is(MMToken::Identifier)) {
2600 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2601 skipUntil(MMToken::RSquare);
2602 if (Tok.is(MMToken::RSquare))
2603 consumeToken();
2604 HadError = true;
2605 }
2606
2607 // Decode the attribute name.
2608 AttributeKind Attribute
2609 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002610 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002611 .Case("extern_c", AT_extern_c)
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002612 .Case("no_undeclared_includes", AT_no_undeclared_includes)
Douglas Gregor9194a912012-11-06 19:39:40 +00002613 .Case("system", AT_system)
2614 .Default(AT_unknown);
2615 switch (Attribute) {
2616 case AT_unknown:
2617 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2618 << Tok.getString();
2619 break;
2620
2621 case AT_system:
2622 Attrs.IsSystem = true;
2623 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002624
Richard Smith77944862014-03-02 05:58:18 +00002625 case AT_extern_c:
2626 Attrs.IsExternC = true;
2627 break;
2628
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002629 case AT_exhaustive:
2630 Attrs.IsExhaustive = true;
2631 break;
Bruno Cardoso Lopesed84df02016-10-21 01:41:56 +00002632
2633 case AT_no_undeclared_includes:
2634 Attrs.NoUndeclaredIncludes = true;
2635 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002636 }
2637 consumeToken();
2638
2639 // Consume the ']'.
2640 if (!Tok.is(MMToken::RSquare)) {
2641 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2642 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2643 skipUntil(MMToken::RSquare);
2644 HadError = true;
2645 }
2646
2647 if (Tok.is(MMToken::RSquare))
2648 consumeToken();
2649 }
2650
2651 return HadError;
2652}
2653
Douglas Gregor718292f2011-11-11 19:10:28 +00002654/// \brief Parse a module map file.
2655///
2656/// module-map-file:
2657/// module-declaration*
2658bool ModuleMapParser::parseModuleMapFile() {
2659 do {
2660 switch (Tok.Kind) {
2661 case MMToken::EndOfFile:
2662 return HadError;
2663
Douglas Gregore7ab3662011-12-07 02:23:45 +00002664 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002665 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002666 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002667 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002668 parseModuleDecl();
2669 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002670
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002671 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002672 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002673 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002674 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002675 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002676 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002677 case MMToken::HeaderKeyword:
2678 case MMToken::Identifier:
2679 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002680 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002681 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002682 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002683 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002684 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002685 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002686 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002687 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002688 case MMToken::StringLiteral:
Richard Smith040e1262017-06-02 01:55:39 +00002689 case MMToken::IntegerLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002690 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002691 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002692 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002693 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2694 HadError = true;
2695 consumeToken();
2696 break;
2697 }
2698 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002699}
2700
Richard Smith9acb99e32014-12-10 03:09:48 +00002701bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smith8128f332017-05-05 22:18:51 +00002702 const DirectoryEntry *Dir, FileID ID,
2703 unsigned *Offset,
Richard Smithae6df272015-07-14 02:06:01 +00002704 SourceLocation ExternModuleLoc) {
Richard Smith8128f332017-05-05 22:18:51 +00002705 assert(Target && "Missing target information");
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002706 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2707 = ParsedModuleMap.find(File);
2708 if (Known != ParsedModuleMap.end())
2709 return Known->second;
2710
Richard Smith8128f332017-05-05 22:18:51 +00002711 // If the module map file wasn't already entered, do so now.
2712 if (ID.isInvalid()) {
Richard Smithf3f84612017-06-29 02:19:42 +00002713 auto FileCharacter =
2714 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
Richard Smith8128f332017-05-05 22:18:51 +00002715 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2716 }
2717
Craig Topperd2d442c2014-05-17 23:10:59 +00002718 assert(Target && "Missing target information");
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002719 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002720 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002721 return ParsedModuleMap[File] = true;
Richard Smith8128f332017-05-05 22:18:51 +00002722 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
2723 "invalid buffer offset");
Ben Langmuir984e1df2014-03-19 20:23:34 +00002724
Douglas Gregor718292f2011-11-11 19:10:28 +00002725 // Parse this module map file.
Richard Smith8128f332017-05-05 22:18:51 +00002726 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
2727 Buffer->getBufferStart(),
2728 Buffer->getBufferStart() + (Offset ? *Offset : 0),
2729 Buffer->getBufferEnd());
Richard Smith2a6edb32015-08-09 04:46:57 +00002730 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002731 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Richard Smith1d609872017-05-26 00:01:53 +00002732 IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002733 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002734 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002735
Richard Smith8128f332017-05-05 22:18:51 +00002736 if (Offset) {
2737 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
2738 assert(Loc.first == ID && "stopped in a different file?");
2739 *Offset = Loc.second;
2740 }
2741
Richard Smith2a6edb32015-08-09 04:46:57 +00002742 // Notify callbacks that we parsed it.
2743 for (const auto &Cb : Callbacks)
2744 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002745 return Result;
2746}