1 //===--- 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"
15 #include "clang/Basic/CharInfo.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticOptions.h"
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Basic/TargetInfo.h"
20 #include "clang/Basic/TargetOptions.h"
21 #include "clang/Lex/HeaderSearch.h"
22 #include "clang/Lex/HeaderSearchOptions.h"
23 #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"
28 #include "llvm/Support/Allocator.h"
29 #include "llvm/Support/FileSystem.h"
30 #include "llvm/Support/Host.h"
31 #include "llvm/Support/Path.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include <stdlib.h>
34 #if defined(LLVM_ON_UNIX)
35 #include <limits.h>
36 #endif
37 using namespace clang;
38
39 Module::ExportDecl
resolveExport(Module * Mod,const Module::UnresolvedExportDecl & Unresolved,bool Complain) const40 ModuleMap::resolveExport(Module *Mod,
41 const Module::UnresolvedExportDecl &Unresolved,
42 bool Complain) const {
43 // We may have just a wildcard.
44 if (Unresolved.Id.empty()) {
45 assert(Unresolved.Wildcard && "Invalid unresolved export");
46 return Module::ExportDecl(nullptr, true);
47 }
48
49 // Resolve the module-id.
50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
51 if (!Context)
52 return Module::ExportDecl();
53
54 return Module::ExportDecl(Context, Unresolved.Wildcard);
55 }
56
resolveModuleId(const ModuleId & Id,Module * Mod,bool Complain) const57 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
58 bool Complain) const {
59 // Find the starting module.
60 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
61 if (!Context) {
62 if (Complain)
63 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
64 << Id[0].first << Mod->getFullModuleName();
65
66 return nullptr;
67 }
68
69 // Dig into the module path.
70 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
71 Module *Sub = lookupModuleQualified(Id[I].first, Context);
72 if (!Sub) {
73 if (Complain)
74 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
75 << Id[I].first << Context->getFullModuleName()
76 << SourceRange(Id[0].second, Id[I-1].second);
77
78 return nullptr;
79 }
80
81 Context = Sub;
82 }
83
84 return Context;
85 }
86
ModuleMap(SourceManager & SourceMgr,DiagnosticsEngine & Diags,const LangOptions & LangOpts,const TargetInfo * Target,HeaderSearch & HeaderInfo)87 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
88 const LangOptions &LangOpts, const TargetInfo *Target,
89 HeaderSearch &HeaderInfo)
90 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
91 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
92 CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
93 MMapLangOpts.LineComment = true;
94 }
95
~ModuleMap()96 ModuleMap::~ModuleMap() {
97 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
98 IEnd = Modules.end();
99 I != IEnd; ++I) {
100 delete I->getValue();
101 }
102 }
103
setTarget(const TargetInfo & Target)104 void ModuleMap::setTarget(const TargetInfo &Target) {
105 assert((!this->Target || this->Target == &Target) &&
106 "Improper target override");
107 this->Target = &Target;
108 }
109
110 /// \brief "Sanitize" a filename so that it can be used as an identifier.
sanitizeFilenameAsIdentifier(StringRef Name,SmallVectorImpl<char> & Buffer)111 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
112 SmallVectorImpl<char> &Buffer) {
113 if (Name.empty())
114 return Name;
115
116 if (!isValidIdentifier(Name)) {
117 // If we don't already have something with the form of an identifier,
118 // create a buffer with the sanitized name.
119 Buffer.clear();
120 if (isDigit(Name[0]))
121 Buffer.push_back('_');
122 Buffer.reserve(Buffer.size() + Name.size());
123 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
124 if (isIdentifierBody(Name[I]))
125 Buffer.push_back(Name[I]);
126 else
127 Buffer.push_back('_');
128 }
129
130 Name = StringRef(Buffer.data(), Buffer.size());
131 }
132
133 while (llvm::StringSwitch<bool>(Name)
134 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
135 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
136 #include "clang/Basic/TokenKinds.def"
137 .Default(false)) {
138 if (Name.data() != Buffer.data())
139 Buffer.append(Name.begin(), Name.end());
140 Buffer.push_back('_');
141 Name = StringRef(Buffer.data(), Buffer.size());
142 }
143
144 return Name;
145 }
146
147 /// \brief Determine whether the given file name is the name of a builtin
148 /// header, supplied by Clang to replace, override, or augment existing system
149 /// headers.
isBuiltinHeader(StringRef FileName)150 static bool isBuiltinHeader(StringRef FileName) {
151 return llvm::StringSwitch<bool>(FileName)
152 .Case("float.h", true)
153 .Case("iso646.h", true)
154 .Case("limits.h", true)
155 .Case("stdalign.h", true)
156 .Case("stdarg.h", true)
157 .Case("stdbool.h", true)
158 .Case("stddef.h", true)
159 .Case("stdint.h", true)
160 .Case("tgmath.h", true)
161 .Case("unwind.h", true)
162 .Default(false);
163 }
164
165 ModuleMap::HeadersMap::iterator
findKnownHeader(const FileEntry * File)166 ModuleMap::findKnownHeader(const FileEntry *File) {
167 HeadersMap::iterator Known = Headers.find(File);
168 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
169 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
170 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
171 HeaderInfo.loadTopLevelSystemModules();
172 return Headers.find(File);
173 }
174 return Known;
175 }
176
177 ModuleMap::KnownHeader
findHeaderInUmbrellaDirs(const FileEntry * File,SmallVectorImpl<const DirectoryEntry * > & IntermediateDirs)178 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
179 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
180 if (UmbrellaDirs.empty())
181 return KnownHeader();
182
183 const DirectoryEntry *Dir = File->getDir();
184 assert(Dir && "file in no directory");
185
186 // Note: as an egregious but useful hack we use the real path here, because
187 // frameworks moving from top-level frameworks to embedded frameworks tend
188 // to be symlinked from the top-level location to the embedded location,
189 // and we need to resolve lookups as if we had found the embedded location.
190 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
191
192 // Keep walking up the directory hierarchy, looking for a directory with
193 // an umbrella header.
194 do {
195 auto KnownDir = UmbrellaDirs.find(Dir);
196 if (KnownDir != UmbrellaDirs.end())
197 return KnownHeader(KnownDir->second, NormalHeader);
198
199 IntermediateDirs.push_back(Dir);
200
201 // Retrieve our parent path.
202 DirName = llvm::sys::path::parent_path(DirName);
203 if (DirName.empty())
204 break;
205
206 // Resolve the parent path to a directory entry.
207 Dir = SourceMgr.getFileManager().getDirectory(DirName);
208 } while (Dir);
209 return KnownHeader();
210 }
211
violatesPrivateInclude(Module * RequestingModule,const FileEntry * IncFileEnt,ModuleMap::ModuleHeaderRole Role,Module * RequestedModule)212 static bool violatesPrivateInclude(Module *RequestingModule,
213 const FileEntry *IncFileEnt,
214 ModuleMap::ModuleHeaderRole Role,
215 Module *RequestedModule) {
216 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
217 #ifndef NDEBUG
218 if (IsPrivateRole) {
219 // Check for consistency between the module header role
220 // as obtained from the lookup and as obtained from the module.
221 // This check is not cheap, so enable it only for debugging.
222 bool IsPrivate = false;
223 SmallVectorImpl<Module::Header> *HeaderList[] = {
224 &RequestedModule->Headers[Module::HK_Private],
225 &RequestedModule->Headers[Module::HK_PrivateTextual]};
226 for (auto *Hs : HeaderList)
227 IsPrivate |=
228 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
229 return H.Entry == IncFileEnt;
230 }) != Hs->end();
231 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
232 }
233 #endif
234 return IsPrivateRole &&
235 // FIXME: Should we map RequestingModule to its top-level module here
236 // too? This check is redundant with the isSubModuleOf check in
237 // diagnoseHeaderInclusion.
238 RequestedModule->getTopLevelModule() != RequestingModule;
239 }
240
getTopLevelOrNull(Module * M)241 static Module *getTopLevelOrNull(Module *M) {
242 return M ? M->getTopLevelModule() : nullptr;
243 }
244
diagnoseHeaderInclusion(Module * RequestingModule,SourceLocation FilenameLoc,StringRef Filename,const FileEntry * File)245 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
246 SourceLocation FilenameLoc,
247 StringRef Filename,
248 const FileEntry *File) {
249 // No errors for indirect modules. This may be a bit of a problem for modules
250 // with no source files.
251 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
252 return;
253
254 if (RequestingModule)
255 resolveUses(RequestingModule, /*Complain=*/false);
256
257 bool Excluded = false;
258 Module *Private = nullptr;
259 Module *NotUsed = nullptr;
260
261 HeadersMap::iterator Known = findKnownHeader(File);
262 if (Known != Headers.end()) {
263 for (const KnownHeader &Header : Known->second) {
264 // If 'File' is part of 'RequestingModule' we can definitely include it.
265 if (Header.getModule() &&
266 Header.getModule()->isSubModuleOf(RequestingModule))
267 return;
268
269 // Remember private headers for later printing of a diagnostic.
270 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
271 Header.getModule())) {
272 Private = Header.getModule();
273 continue;
274 }
275
276 // If uses need to be specified explicitly, we are only allowed to return
277 // modules that are explicitly used by the requesting module.
278 if (RequestingModule && LangOpts.ModulesDeclUse &&
279 !RequestingModule->directlyUses(Header.getModule())) {
280 NotUsed = Header.getModule();
281 continue;
282 }
283
284 // We have found a module that we can happily use.
285 return;
286 }
287
288 Excluded = true;
289 }
290
291 // We have found a header, but it is private.
292 if (Private) {
293 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
294 << Filename;
295 return;
296 }
297
298 // We have found a module, but we don't use it.
299 if (NotUsed) {
300 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
301 << RequestingModule->getFullModuleName() << Filename;
302 return;
303 }
304
305 if (Excluded || isHeaderInUmbrellaDirs(File))
306 return;
307
308 // At this point, only non-modular includes remain.
309
310 if (LangOpts.ModulesStrictDeclUse) {
311 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
312 << RequestingModule->getFullModuleName() << Filename;
313 } else if (RequestingModule) {
314 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
315 diag::warn_non_modular_include_in_framework_module :
316 diag::warn_non_modular_include_in_module;
317 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
318 }
319 }
320
isBetterKnownHeader(const ModuleMap::KnownHeader & New,const ModuleMap::KnownHeader & Old)321 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
322 const ModuleMap::KnownHeader &Old) {
323 // Prefer a public header over a private header.
324 if ((New.getRole() & ModuleMap::PrivateHeader) !=
325 (Old.getRole() & ModuleMap::PrivateHeader))
326 return !(New.getRole() & ModuleMap::PrivateHeader);
327
328 // Prefer a non-textual header over a textual header.
329 if ((New.getRole() & ModuleMap::TextualHeader) !=
330 (Old.getRole() & ModuleMap::TextualHeader))
331 return !(New.getRole() & ModuleMap::TextualHeader);
332
333 // Don't have a reason to choose between these. Just keep the first one.
334 return false;
335 }
336
findModuleForHeader(const FileEntry * File)337 ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
338 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
339 if (R.getRole() & ModuleMap::TextualHeader)
340 return ModuleMap::KnownHeader();
341 return R;
342 };
343
344 HeadersMap::iterator Known = findKnownHeader(File);
345 if (Known != Headers.end()) {
346 ModuleMap::KnownHeader Result;
347 // Iterate over all modules that 'File' is part of to find the best fit.
348 for (KnownHeader &H : Known->second) {
349 // Prefer a header from the current module over all others.
350 if (H.getModule()->getTopLevelModule() == CompilingModule)
351 return MakeResult(H);
352 // Cannot use a module if it is unavailable.
353 if (!H.getModule()->isAvailable())
354 continue;
355 if (!Result || isBetterKnownHeader(H, Result))
356 Result = H;
357 }
358 return MakeResult(Result);
359 }
360
361 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
362 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
363 if (H) {
364 Module *Result = H.getModule();
365
366 // Search up the module stack until we find a module with an umbrella
367 // directory.
368 Module *UmbrellaModule = Result;
369 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
370 UmbrellaModule = UmbrellaModule->Parent;
371
372 if (UmbrellaModule->InferSubmodules) {
373 const FileEntry *UmbrellaModuleMap =
374 getModuleMapFileForUniquing(UmbrellaModule);
375
376 // Infer submodules for each of the directories we found between
377 // the directory of the umbrella header and the directory where
378 // the actual header is located.
379 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
380
381 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
382 // Find or create the module that corresponds to this directory name.
383 SmallString<32> NameBuf;
384 StringRef Name = sanitizeFilenameAsIdentifier(
385 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
386 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
387 Explicit).first;
388 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
389 Result->IsInferred = true;
390
391 // Associate the module and the directory.
392 UmbrellaDirs[SkippedDirs[I-1]] = Result;
393
394 // If inferred submodules export everything they import, add a
395 // wildcard to the set of exports.
396 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
397 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
398 }
399
400 // Infer a submodule with the same name as this header file.
401 SmallString<32> NameBuf;
402 StringRef Name = sanitizeFilenameAsIdentifier(
403 llvm::sys::path::stem(File->getName()), NameBuf);
404 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
405 Explicit).first;
406 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
407 Result->IsInferred = true;
408 Result->addTopHeader(File);
409
410 // If inferred submodules export everything they import, add a
411 // wildcard to the set of exports.
412 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
413 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
414 } else {
415 // Record each of the directories we stepped through as being part of
416 // the module we found, since the umbrella header covers them all.
417 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
418 UmbrellaDirs[SkippedDirs[I]] = Result;
419 }
420
421 Headers[File].push_back(KnownHeader(Result, NormalHeader));
422
423 // If a header corresponds to an unavailable module, don't report
424 // that it maps to anything.
425 if (!Result->isAvailable())
426 return KnownHeader();
427
428 return MakeResult(Headers[File].back());
429 }
430
431 return KnownHeader();
432 }
433
isHeaderInUnavailableModule(const FileEntry * Header) const434 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
435 return isHeaderUnavailableInModule(Header, nullptr);
436 }
437
438 bool
isHeaderUnavailableInModule(const FileEntry * Header,const Module * RequestingModule) const439 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
440 const Module *RequestingModule) const {
441 HeadersMap::const_iterator Known = Headers.find(Header);
442 if (Known != Headers.end()) {
443 for (SmallVectorImpl<KnownHeader>::const_iterator
444 I = Known->second.begin(),
445 E = Known->second.end();
446 I != E; ++I) {
447 if (I->isAvailable() && (!RequestingModule ||
448 I->getModule()->isSubModuleOf(RequestingModule)))
449 return false;
450 }
451 return true;
452 }
453
454 const DirectoryEntry *Dir = Header->getDir();
455 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
456 StringRef DirName = Dir->getName();
457
458 auto IsUnavailable = [&](const Module *M) {
459 return !M->isAvailable() && (!RequestingModule ||
460 M->isSubModuleOf(RequestingModule));
461 };
462
463 // Keep walking up the directory hierarchy, looking for a directory with
464 // an umbrella header.
465 do {
466 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
467 = UmbrellaDirs.find(Dir);
468 if (KnownDir != UmbrellaDirs.end()) {
469 Module *Found = KnownDir->second;
470 if (IsUnavailable(Found))
471 return true;
472
473 // Search up the module stack until we find a module with an umbrella
474 // directory.
475 Module *UmbrellaModule = Found;
476 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
477 UmbrellaModule = UmbrellaModule->Parent;
478
479 if (UmbrellaModule->InferSubmodules) {
480 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
481 // Find or create the module that corresponds to this directory name.
482 SmallString<32> NameBuf;
483 StringRef Name = sanitizeFilenameAsIdentifier(
484 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
485 NameBuf);
486 Found = lookupModuleQualified(Name, Found);
487 if (!Found)
488 return false;
489 if (IsUnavailable(Found))
490 return true;
491 }
492
493 // Infer a submodule with the same name as this header file.
494 SmallString<32> NameBuf;
495 StringRef Name = sanitizeFilenameAsIdentifier(
496 llvm::sys::path::stem(Header->getName()),
497 NameBuf);
498 Found = lookupModuleQualified(Name, Found);
499 if (!Found)
500 return false;
501 }
502
503 return IsUnavailable(Found);
504 }
505
506 SkippedDirs.push_back(Dir);
507
508 // Retrieve our parent path.
509 DirName = llvm::sys::path::parent_path(DirName);
510 if (DirName.empty())
511 break;
512
513 // Resolve the parent path to a directory entry.
514 Dir = SourceMgr.getFileManager().getDirectory(DirName);
515 } while (Dir);
516
517 return false;
518 }
519
findModule(StringRef Name) const520 Module *ModuleMap::findModule(StringRef Name) const {
521 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
522 if (Known != Modules.end())
523 return Known->getValue();
524
525 return nullptr;
526 }
527
lookupModuleUnqualified(StringRef Name,Module * Context) const528 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
529 Module *Context) const {
530 for(; Context; Context = Context->Parent) {
531 if (Module *Sub = lookupModuleQualified(Name, Context))
532 return Sub;
533 }
534
535 return findModule(Name);
536 }
537
lookupModuleQualified(StringRef Name,Module * Context) const538 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
539 if (!Context)
540 return findModule(Name);
541
542 return Context->findSubmodule(Name);
543 }
544
545 std::pair<Module *, bool>
findOrCreateModule(StringRef Name,Module * Parent,bool IsFramework,bool IsExplicit)546 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
547 bool IsExplicit) {
548 // Try to find an existing module with this name.
549 if (Module *Sub = lookupModuleQualified(Name, Parent))
550 return std::make_pair(Sub, false);
551
552 // Create a new module with this name.
553 Module *Result = new Module(Name, SourceLocation(), Parent,
554 IsFramework, IsExplicit, NumCreatedModules++);
555 if (LangOpts.CurrentModule == Name) {
556 SourceModule = Result;
557 SourceModuleName = Name;
558 }
559 if (!Parent) {
560 Modules[Name] = Result;
561 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
562 Name == LangOpts.CurrentModule) {
563 CompilingModule = Result;
564 }
565 }
566 return std::make_pair(Result, true);
567 }
568
569 /// \brief For a framework module, infer the framework against which we
570 /// should link.
inferFrameworkLink(Module * Mod,const DirectoryEntry * FrameworkDir,FileManager & FileMgr)571 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
572 FileManager &FileMgr) {
573 assert(Mod->IsFramework && "Can only infer linking for framework modules");
574 assert(!Mod->isSubFramework() &&
575 "Can only infer linking for top-level frameworks");
576
577 SmallString<128> LibName;
578 LibName += FrameworkDir->getName();
579 llvm::sys::path::append(LibName, Mod->Name);
580 if (FileMgr.getFile(LibName)) {
581 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
582 /*IsFramework=*/true));
583 }
584 }
585
inferFrameworkModule(const DirectoryEntry * FrameworkDir,bool IsSystem,Module * Parent)586 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
587 bool IsSystem, Module *Parent) {
588 Attributes Attrs;
589 Attrs.IsSystem = IsSystem;
590 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
591 }
592
inferFrameworkModule(const DirectoryEntry * FrameworkDir,Attributes Attrs,Module * Parent)593 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
594 Attributes Attrs, Module *Parent) {
595 // Note: as an egregious but useful hack we use the real path here, because
596 // we might be looking at an embedded framework that symlinks out to a
597 // top-level framework, and we need to infer as if we were naming the
598 // top-level framework.
599 StringRef FrameworkDirName =
600 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
601
602 // In case this is a case-insensitive filesystem, use the canonical
603 // directory name as the ModuleName, since modules are case-sensitive.
604 // FIXME: we should be able to give a fix-it hint for the correct spelling.
605 SmallString<32> ModuleNameStorage;
606 StringRef ModuleName = sanitizeFilenameAsIdentifier(
607 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
608
609 // Check whether we've already found this module.
610 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
611 return Mod;
612
613 FileManager &FileMgr = SourceMgr.getFileManager();
614
615 // If the framework has a parent path from which we're allowed to infer
616 // a framework module, do so.
617 const FileEntry *ModuleMapFile = nullptr;
618 if (!Parent) {
619 // Determine whether we're allowed to infer a module map.
620 bool canInfer = false;
621 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
622 // Figure out the parent path.
623 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
624 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
625 // Check whether we have already looked into the parent directory
626 // for a module map.
627 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
628 inferred = InferredDirectories.find(ParentDir);
629 if (inferred == InferredDirectories.end()) {
630 // We haven't looked here before. Load a module map, if there is
631 // one.
632 bool IsFrameworkDir = Parent.endswith(".framework");
633 if (const FileEntry *ModMapFile =
634 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
635 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
636 inferred = InferredDirectories.find(ParentDir);
637 }
638
639 if (inferred == InferredDirectories.end())
640 inferred = InferredDirectories.insert(
641 std::make_pair(ParentDir, InferredDirectory())).first;
642 }
643
644 if (inferred->second.InferModules) {
645 // We're allowed to infer for this directory, but make sure it's okay
646 // to infer this particular module.
647 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
648 canInfer = std::find(inferred->second.ExcludedModules.begin(),
649 inferred->second.ExcludedModules.end(),
650 Name) == inferred->second.ExcludedModules.end();
651
652 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
653 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
654 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
655 ModuleMapFile = inferred->second.ModuleMapFile;
656 }
657 }
658 }
659
660 // If we're not allowed to infer a framework module, don't.
661 if (!canInfer)
662 return nullptr;
663 } else
664 ModuleMapFile = getModuleMapFileForUniquing(Parent);
665
666
667 // Look for an umbrella header.
668 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
669 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
670 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
671
672 // FIXME: If there's no umbrella header, we could probably scan the
673 // framework to load *everything*. But, it's not clear that this is a good
674 // idea.
675 if (!UmbrellaHeader)
676 return nullptr;
677
678 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
679 /*IsFramework=*/true, /*IsExplicit=*/false,
680 NumCreatedModules++);
681 InferredModuleAllowedBy[Result] = ModuleMapFile;
682 Result->IsInferred = true;
683 if (LangOpts.CurrentModule == ModuleName) {
684 SourceModule = Result;
685 SourceModuleName = ModuleName;
686 }
687
688 Result->IsSystem |= Attrs.IsSystem;
689 Result->IsExternC |= Attrs.IsExternC;
690 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
691 Result->Directory = FrameworkDir;
692
693 if (!Parent)
694 Modules[ModuleName] = Result;
695
696 // umbrella header "umbrella-header-name"
697 //
698 // The "Headers/" component of the name is implied because this is
699 // a framework module.
700 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
701
702 // export *
703 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
704
705 // module * { export * }
706 Result->InferSubmodules = true;
707 Result->InferExportWildcard = true;
708
709 // Look for subframeworks.
710 std::error_code EC;
711 SmallString<128> SubframeworksDirName
712 = StringRef(FrameworkDir->getName());
713 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
714 llvm::sys::path::native(SubframeworksDirName);
715 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(".framework"))
718 continue;
719
720 if (const DirectoryEntry *SubframeworkDir
721 = FileMgr.getDirectory(Dir->path())) {
722 // Note: as an egregious but useful hack, we use the real path here and
723 // check whether it is actually a subdirectory of the parent directory.
724 // This will not be the case if the 'subframework' is actually a symlink
725 // out to a top-level framework.
726 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
727 bool FoundParent = false;
728 do {
729 // Get the parent directory name.
730 SubframeworkDirName
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
733 break;
734
735 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
736 FoundParent = true;
737 break;
738 }
739 } while (true);
740
741 if (!FoundParent)
742 continue;
743
744 // FIXME: Do we want to warn about subframeworks without umbrella headers?
745 inferFrameworkModule(SubframeworkDir, Attrs, Result);
746 }
747 }
748
749 // If the module is a top-level framework, automatically link against the
750 // framework.
751 if (!Result->isSubFramework()) {
752 inferFrameworkLink(Result, FrameworkDir, FileMgr);
753 }
754
755 return Result;
756 }
757
setUmbrellaHeader(Module * Mod,const FileEntry * UmbrellaHeader,Twine NameAsWritten)758 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
759 Twine NameAsWritten) {
760 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
761 Mod->Umbrella = UmbrellaHeader;
762 Mod->UmbrellaAsWritten = NameAsWritten.str();
763 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
764 }
765
setUmbrellaDir(Module * Mod,const DirectoryEntry * UmbrellaDir,Twine NameAsWritten)766 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
767 Twine NameAsWritten) {
768 Mod->Umbrella = UmbrellaDir;
769 Mod->UmbrellaAsWritten = NameAsWritten.str();
770 UmbrellaDirs[UmbrellaDir] = Mod;
771 }
772
headerRoleToKind(ModuleMap::ModuleHeaderRole Role)773 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
774 switch ((int)Role) {
775 default: llvm_unreachable("unknown header role");
776 case ModuleMap::NormalHeader:
777 return Module::HK_Normal;
778 case ModuleMap::PrivateHeader:
779 return Module::HK_Private;
780 case ModuleMap::TextualHeader:
781 return Module::HK_Textual;
782 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
783 return Module::HK_PrivateTextual;
784 }
785 }
786
addHeader(Module * Mod,Module::Header Header,ModuleHeaderRole Role)787 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
788 ModuleHeaderRole Role) {
789 if (!(Role & TextualHeader)) {
790 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
791 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
792 isCompilingModuleHeader);
793 }
794 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
795
796 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
797 }
798
excludeHeader(Module * Mod,Module::Header Header)799 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
800 // Add this as a known header so we won't implicitly add it to any
801 // umbrella directory module.
802 // FIXME: Should we only exclude it from umbrella modules within the
803 // specified module?
804 (void) Headers[Header.Entry];
805
806 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
807 }
808
809 const FileEntry *
getContainingModuleMapFile(const Module * Module) const810 ModuleMap::getContainingModuleMapFile(const Module *Module) const {
811 if (Module->DefinitionLoc.isInvalid())
812 return nullptr;
813
814 return SourceMgr.getFileEntryForID(
815 SourceMgr.getFileID(Module->DefinitionLoc));
816 }
817
getModuleMapFileForUniquing(const Module * M) const818 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
819 if (M->IsInferred) {
820 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
821 return InferredModuleAllowedBy.find(M)->second;
822 }
823 return getContainingModuleMapFile(M);
824 }
825
setInferredModuleAllowedBy(Module * M,const FileEntry * ModMap)826 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
827 assert(M->IsInferred && "module not inferred");
828 InferredModuleAllowedBy[M] = ModMap;
829 }
830
dump()831 void ModuleMap::dump() {
832 llvm::errs() << "Modules:";
833 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
834 MEnd = Modules.end();
835 M != MEnd; ++M)
836 M->getValue()->print(llvm::errs(), 2);
837
838 llvm::errs() << "Headers:";
839 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
840 H != HEnd; ++H) {
841 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
842 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
843 E = H->second.end();
844 I != E; ++I) {
845 if (I != H->second.begin())
846 llvm::errs() << ",";
847 llvm::errs() << I->getModule()->getFullModuleName();
848 }
849 llvm::errs() << "\n";
850 }
851 }
852
resolveExports(Module * Mod,bool Complain)853 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
854 auto Unresolved = std::move(Mod->UnresolvedExports);
855 Mod->UnresolvedExports.clear();
856 for (auto &UE : Unresolved) {
857 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
858 if (Export.getPointer() || Export.getInt())
859 Mod->Exports.push_back(Export);
860 else
861 Mod->UnresolvedExports.push_back(UE);
862 }
863 return !Mod->UnresolvedExports.empty();
864 }
865
resolveUses(Module * Mod,bool Complain)866 bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
867 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
868 Mod->UnresolvedDirectUses.clear();
869 for (auto &UDU : Unresolved) {
870 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
871 if (DirectUse)
872 Mod->DirectUses.push_back(DirectUse);
873 else
874 Mod->UnresolvedDirectUses.push_back(UDU);
875 }
876 return !Mod->UnresolvedDirectUses.empty();
877 }
878
resolveConflicts(Module * Mod,bool Complain)879 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
880 auto Unresolved = std::move(Mod->UnresolvedConflicts);
881 Mod->UnresolvedConflicts.clear();
882 for (auto &UC : Unresolved) {
883 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
884 Module::Conflict Conflict;
885 Conflict.Other = OtherMod;
886 Conflict.Message = UC.Message;
887 Mod->Conflicts.push_back(Conflict);
888 } else
889 Mod->UnresolvedConflicts.push_back(UC);
890 }
891 return !Mod->UnresolvedConflicts.empty();
892 }
893
inferModuleFromLocation(FullSourceLoc Loc)894 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
895 if (Loc.isInvalid())
896 return nullptr;
897
898 // Use the expansion location to determine which module we're in.
899 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
900 if (!ExpansionLoc.isFileID())
901 return nullptr;
902
903 const SourceManager &SrcMgr = Loc.getManager();
904 FileID ExpansionFileID = ExpansionLoc.getFileID();
905
906 while (const FileEntry *ExpansionFile
907 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
908 // Find the module that owns this header (if any).
909 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
910 return Mod;
911
912 // No module owns this header, so look up the inclusion chain to see if
913 // any included header has an associated module.
914 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
915 if (IncludeLoc.isInvalid())
916 return nullptr;
917
918 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
919 }
920
921 return nullptr;
922 }
923
924 //----------------------------------------------------------------------------//
925 // Module map file parser
926 //----------------------------------------------------------------------------//
927
928 namespace clang {
929 /// \brief A token in a module map file.
930 struct MMToken {
931 enum TokenKind {
932 Comma,
933 ConfigMacros,
934 Conflict,
935 EndOfFile,
936 HeaderKeyword,
937 Identifier,
938 Exclaim,
939 ExcludeKeyword,
940 ExplicitKeyword,
941 ExportKeyword,
942 ExternKeyword,
943 FrameworkKeyword,
944 LinkKeyword,
945 ModuleKeyword,
946 Period,
947 PrivateKeyword,
948 UmbrellaKeyword,
949 UseKeyword,
950 RequiresKeyword,
951 Star,
952 StringLiteral,
953 TextualKeyword,
954 LBrace,
955 RBrace,
956 LSquare,
957 RSquare
958 } Kind;
959
960 unsigned Location;
961 unsigned StringLength;
962 const char *StringData;
963
clearclang::MMToken964 void clear() {
965 Kind = EndOfFile;
966 Location = 0;
967 StringLength = 0;
968 StringData = nullptr;
969 }
970
isclang::MMToken971 bool is(TokenKind K) const { return Kind == K; }
972
getLocationclang::MMToken973 SourceLocation getLocation() const {
974 return SourceLocation::getFromRawEncoding(Location);
975 }
976
getStringclang::MMToken977 StringRef getString() const {
978 return StringRef(StringData, StringLength);
979 }
980 };
981
982 class ModuleMapParser {
983 Lexer &L;
984 SourceManager &SourceMgr;
985
986 /// \brief Default target information, used only for string literal
987 /// parsing.
988 const TargetInfo *Target;
989
990 DiagnosticsEngine &Diags;
991 ModuleMap ⤅
992
993 /// \brief The current module map file.
994 const FileEntry *ModuleMapFile;
995
996 /// \brief The directory that file names in this module map file should
997 /// be resolved relative to.
998 const DirectoryEntry *Directory;
999
1000 /// \brief The directory containing Clang-supplied headers.
1001 const DirectoryEntry *BuiltinIncludeDir;
1002
1003 /// \brief Whether this module map is in a system header directory.
1004 bool IsSystem;
1005
1006 /// \brief Whether an error occurred.
1007 bool HadError;
1008
1009 /// \brief Stores string data for the various string literals referenced
1010 /// during parsing.
1011 llvm::BumpPtrAllocator StringData;
1012
1013 /// \brief The current token.
1014 MMToken Tok;
1015
1016 /// \brief The active module.
1017 Module *ActiveModule;
1018
1019 /// \brief Consume the current token and return its location.
1020 SourceLocation consumeToken();
1021
1022 /// \brief Skip tokens until we reach the a token with the given kind
1023 /// (or the end of the file).
1024 void skipUntil(MMToken::TokenKind K);
1025
1026 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
1027 bool parseModuleId(ModuleId &Id);
1028 void parseModuleDecl();
1029 void parseExternModuleDecl();
1030 void parseRequiresDecl();
1031 void parseHeaderDecl(clang::MMToken::TokenKind,
1032 SourceLocation LeadingLoc);
1033 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1034 void parseExportDecl();
1035 void parseUseDecl();
1036 void parseLinkDecl();
1037 void parseConfigMacros();
1038 void parseConflict();
1039 void parseInferredModuleDecl(bool Framework, bool Explicit);
1040
1041 typedef ModuleMap::Attributes Attributes;
1042 bool parseOptionalAttributes(Attributes &Attrs);
1043
1044 public:
ModuleMapParser(Lexer & L,SourceManager & SourceMgr,const TargetInfo * Target,DiagnosticsEngine & Diags,ModuleMap & Map,const FileEntry * ModuleMapFile,const DirectoryEntry * Directory,const DirectoryEntry * BuiltinIncludeDir,bool IsSystem)1045 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1046 const TargetInfo *Target,
1047 DiagnosticsEngine &Diags,
1048 ModuleMap &Map,
1049 const FileEntry *ModuleMapFile,
1050 const DirectoryEntry *Directory,
1051 const DirectoryEntry *BuiltinIncludeDir,
1052 bool IsSystem)
1053 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1054 ModuleMapFile(ModuleMapFile), Directory(Directory),
1055 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1056 HadError(false), ActiveModule(nullptr)
1057 {
1058 Tok.clear();
1059 consumeToken();
1060 }
1061
1062 bool parseModuleMapFile();
1063 };
1064 }
1065
consumeToken()1066 SourceLocation ModuleMapParser::consumeToken() {
1067 retry:
1068 SourceLocation Result = Tok.getLocation();
1069 Tok.clear();
1070
1071 Token LToken;
1072 L.LexFromRawLexer(LToken);
1073 Tok.Location = LToken.getLocation().getRawEncoding();
1074 switch (LToken.getKind()) {
1075 case tok::raw_identifier: {
1076 StringRef RI = LToken.getRawIdentifier();
1077 Tok.StringData = RI.data();
1078 Tok.StringLength = RI.size();
1079 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1080 .Case("config_macros", MMToken::ConfigMacros)
1081 .Case("conflict", MMToken::Conflict)
1082 .Case("exclude", MMToken::ExcludeKeyword)
1083 .Case("explicit", MMToken::ExplicitKeyword)
1084 .Case("export", MMToken::ExportKeyword)
1085 .Case("extern", MMToken::ExternKeyword)
1086 .Case("framework", MMToken::FrameworkKeyword)
1087 .Case("header", MMToken::HeaderKeyword)
1088 .Case("link", MMToken::LinkKeyword)
1089 .Case("module", MMToken::ModuleKeyword)
1090 .Case("private", MMToken::PrivateKeyword)
1091 .Case("requires", MMToken::RequiresKeyword)
1092 .Case("textual", MMToken::TextualKeyword)
1093 .Case("umbrella", MMToken::UmbrellaKeyword)
1094 .Case("use", MMToken::UseKeyword)
1095 .Default(MMToken::Identifier);
1096 break;
1097 }
1098
1099 case tok::comma:
1100 Tok.Kind = MMToken::Comma;
1101 break;
1102
1103 case tok::eof:
1104 Tok.Kind = MMToken::EndOfFile;
1105 break;
1106
1107 case tok::l_brace:
1108 Tok.Kind = MMToken::LBrace;
1109 break;
1110
1111 case tok::l_square:
1112 Tok.Kind = MMToken::LSquare;
1113 break;
1114
1115 case tok::period:
1116 Tok.Kind = MMToken::Period;
1117 break;
1118
1119 case tok::r_brace:
1120 Tok.Kind = MMToken::RBrace;
1121 break;
1122
1123 case tok::r_square:
1124 Tok.Kind = MMToken::RSquare;
1125 break;
1126
1127 case tok::star:
1128 Tok.Kind = MMToken::Star;
1129 break;
1130
1131 case tok::exclaim:
1132 Tok.Kind = MMToken::Exclaim;
1133 break;
1134
1135 case tok::string_literal: {
1136 if (LToken.hasUDSuffix()) {
1137 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1138 HadError = true;
1139 goto retry;
1140 }
1141
1142 // Parse the string literal.
1143 LangOptions LangOpts;
1144 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1145 if (StringLiteral.hadError)
1146 goto retry;
1147
1148 // Copy the string literal into our string data allocator.
1149 unsigned Length = StringLiteral.GetStringLength();
1150 char *Saved = StringData.Allocate<char>(Length + 1);
1151 memcpy(Saved, StringLiteral.GetString().data(), Length);
1152 Saved[Length] = 0;
1153
1154 // Form the token.
1155 Tok.Kind = MMToken::StringLiteral;
1156 Tok.StringData = Saved;
1157 Tok.StringLength = Length;
1158 break;
1159 }
1160
1161 case tok::comment:
1162 goto retry;
1163
1164 default:
1165 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1166 HadError = true;
1167 goto retry;
1168 }
1169
1170 return Result;
1171 }
1172
skipUntil(MMToken::TokenKind K)1173 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1174 unsigned braceDepth = 0;
1175 unsigned squareDepth = 0;
1176 do {
1177 switch (Tok.Kind) {
1178 case MMToken::EndOfFile:
1179 return;
1180
1181 case MMToken::LBrace:
1182 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1183 return;
1184
1185 ++braceDepth;
1186 break;
1187
1188 case MMToken::LSquare:
1189 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1190 return;
1191
1192 ++squareDepth;
1193 break;
1194
1195 case MMToken::RBrace:
1196 if (braceDepth > 0)
1197 --braceDepth;
1198 else if (Tok.is(K))
1199 return;
1200 break;
1201
1202 case MMToken::RSquare:
1203 if (squareDepth > 0)
1204 --squareDepth;
1205 else if (Tok.is(K))
1206 return;
1207 break;
1208
1209 default:
1210 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1211 return;
1212 break;
1213 }
1214
1215 consumeToken();
1216 } while (true);
1217 }
1218
1219 /// \brief Parse a module-id.
1220 ///
1221 /// module-id:
1222 /// identifier
1223 /// identifier '.' module-id
1224 ///
1225 /// \returns true if an error occurred, false otherwise.
parseModuleId(ModuleId & Id)1226 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1227 Id.clear();
1228 do {
1229 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1230 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1231 consumeToken();
1232 } else {
1233 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1234 return true;
1235 }
1236
1237 if (!Tok.is(MMToken::Period))
1238 break;
1239
1240 consumeToken();
1241 } while (true);
1242
1243 return false;
1244 }
1245
1246 namespace {
1247 /// \brief Enumerates the known attributes.
1248 enum AttributeKind {
1249 /// \brief An unknown attribute.
1250 AT_unknown,
1251 /// \brief The 'system' attribute.
1252 AT_system,
1253 /// \brief The 'extern_c' attribute.
1254 AT_extern_c,
1255 /// \brief The 'exhaustive' attribute.
1256 AT_exhaustive
1257 };
1258 }
1259
1260 /// \brief Parse a module declaration.
1261 ///
1262 /// module-declaration:
1263 /// 'extern' 'module' module-id string-literal
1264 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1265 /// { module-member* }
1266 ///
1267 /// module-member:
1268 /// requires-declaration
1269 /// header-declaration
1270 /// submodule-declaration
1271 /// export-declaration
1272 /// link-declaration
1273 ///
1274 /// submodule-declaration:
1275 /// module-declaration
1276 /// inferred-submodule-declaration
parseModuleDecl()1277 void ModuleMapParser::parseModuleDecl() {
1278 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1279 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1280 if (Tok.is(MMToken::ExternKeyword)) {
1281 parseExternModuleDecl();
1282 return;
1283 }
1284
1285 // Parse 'explicit' or 'framework' keyword, if present.
1286 SourceLocation ExplicitLoc;
1287 bool Explicit = false;
1288 bool Framework = false;
1289
1290 // Parse 'explicit' keyword, if present.
1291 if (Tok.is(MMToken::ExplicitKeyword)) {
1292 ExplicitLoc = consumeToken();
1293 Explicit = true;
1294 }
1295
1296 // Parse 'framework' keyword, if present.
1297 if (Tok.is(MMToken::FrameworkKeyword)) {
1298 consumeToken();
1299 Framework = true;
1300 }
1301
1302 // Parse 'module' keyword.
1303 if (!Tok.is(MMToken::ModuleKeyword)) {
1304 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1305 consumeToken();
1306 HadError = true;
1307 return;
1308 }
1309 consumeToken(); // 'module' keyword
1310
1311 // If we have a wildcard for the module name, this is an inferred submodule.
1312 // Parse it.
1313 if (Tok.is(MMToken::Star))
1314 return parseInferredModuleDecl(Framework, Explicit);
1315
1316 // Parse the module name.
1317 ModuleId Id;
1318 if (parseModuleId(Id)) {
1319 HadError = true;
1320 return;
1321 }
1322
1323 if (ActiveModule) {
1324 if (Id.size() > 1) {
1325 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1326 << SourceRange(Id.front().second, Id.back().second);
1327
1328 HadError = true;
1329 return;
1330 }
1331 } else if (Id.size() == 1 && Explicit) {
1332 // Top-level modules can't be explicit.
1333 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1334 Explicit = false;
1335 ExplicitLoc = SourceLocation();
1336 HadError = true;
1337 }
1338
1339 Module *PreviousActiveModule = ActiveModule;
1340 if (Id.size() > 1) {
1341 // This module map defines a submodule. Go find the module of which it
1342 // is a submodule.
1343 ActiveModule = nullptr;
1344 const Module *TopLevelModule = nullptr;
1345 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1346 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1347 if (I == 0)
1348 TopLevelModule = Next;
1349 ActiveModule = Next;
1350 continue;
1351 }
1352
1353 if (ActiveModule) {
1354 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1355 << Id[I].first
1356 << ActiveModule->getTopLevelModule()->getFullModuleName();
1357 } else {
1358 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1359 }
1360 HadError = true;
1361 return;
1362 }
1363
1364 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1365 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1366 "submodule defined in same file as 'module *' that allowed its "
1367 "top-level module");
1368 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1369 }
1370 }
1371
1372 StringRef ModuleName = Id.back().first;
1373 SourceLocation ModuleNameLoc = Id.back().second;
1374
1375 // Parse the optional attribute list.
1376 Attributes Attrs;
1377 parseOptionalAttributes(Attrs);
1378
1379 // Parse the opening brace.
1380 if (!Tok.is(MMToken::LBrace)) {
1381 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1382 << ModuleName;
1383 HadError = true;
1384 return;
1385 }
1386 SourceLocation LBraceLoc = consumeToken();
1387
1388 // Determine whether this (sub)module has already been defined.
1389 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1390 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1391 // Skip the module definition.
1392 skipUntil(MMToken::RBrace);
1393 if (Tok.is(MMToken::RBrace))
1394 consumeToken();
1395 else {
1396 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1397 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1398 HadError = true;
1399 }
1400 return;
1401 }
1402
1403 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1404 << ModuleName;
1405 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1406
1407 // Skip the module definition.
1408 skipUntil(MMToken::RBrace);
1409 if (Tok.is(MMToken::RBrace))
1410 consumeToken();
1411
1412 HadError = true;
1413 return;
1414 }
1415
1416 // Start defining this module.
1417 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1418 Explicit).first;
1419 ActiveModule->DefinitionLoc = ModuleNameLoc;
1420 if (Attrs.IsSystem || IsSystem)
1421 ActiveModule->IsSystem = true;
1422 if (Attrs.IsExternC)
1423 ActiveModule->IsExternC = true;
1424 ActiveModule->Directory = Directory;
1425
1426 bool Done = false;
1427 do {
1428 switch (Tok.Kind) {
1429 case MMToken::EndOfFile:
1430 case MMToken::RBrace:
1431 Done = true;
1432 break;
1433
1434 case MMToken::ConfigMacros:
1435 parseConfigMacros();
1436 break;
1437
1438 case MMToken::Conflict:
1439 parseConflict();
1440 break;
1441
1442 case MMToken::ExplicitKeyword:
1443 case MMToken::ExternKeyword:
1444 case MMToken::FrameworkKeyword:
1445 case MMToken::ModuleKeyword:
1446 parseModuleDecl();
1447 break;
1448
1449 case MMToken::ExportKeyword:
1450 parseExportDecl();
1451 break;
1452
1453 case MMToken::UseKeyword:
1454 parseUseDecl();
1455 break;
1456
1457 case MMToken::RequiresKeyword:
1458 parseRequiresDecl();
1459 break;
1460
1461 case MMToken::TextualKeyword:
1462 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
1463 break;
1464
1465 case MMToken::UmbrellaKeyword: {
1466 SourceLocation UmbrellaLoc = consumeToken();
1467 if (Tok.is(MMToken::HeaderKeyword))
1468 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1469 else
1470 parseUmbrellaDirDecl(UmbrellaLoc);
1471 break;
1472 }
1473
1474 case MMToken::ExcludeKeyword:
1475 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
1476 break;
1477
1478 case MMToken::PrivateKeyword:
1479 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
1480 break;
1481
1482 case MMToken::HeaderKeyword:
1483 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
1484 break;
1485
1486 case MMToken::LinkKeyword:
1487 parseLinkDecl();
1488 break;
1489
1490 default:
1491 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1492 consumeToken();
1493 break;
1494 }
1495 } while (!Done);
1496
1497 if (Tok.is(MMToken::RBrace))
1498 consumeToken();
1499 else {
1500 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1501 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1502 HadError = true;
1503 }
1504
1505 // If the active module is a top-level framework, and there are no link
1506 // libraries, automatically link against the framework.
1507 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1508 ActiveModule->LinkLibraries.empty()) {
1509 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1510 }
1511
1512 // If the module meets all requirements but is still unavailable, mark the
1513 // whole tree as unavailable to prevent it from building.
1514 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1515 ActiveModule->Parent) {
1516 ActiveModule->getTopLevelModule()->markUnavailable();
1517 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1518 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1519 }
1520
1521 // We're done parsing this module. Pop back to the previous module.
1522 ActiveModule = PreviousActiveModule;
1523 }
1524
1525 /// \brief Parse an extern module declaration.
1526 ///
1527 /// extern module-declaration:
1528 /// 'extern' 'module' module-id string-literal
parseExternModuleDecl()1529 void ModuleMapParser::parseExternModuleDecl() {
1530 assert(Tok.is(MMToken::ExternKeyword));
1531 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
1532
1533 // Parse 'module' keyword.
1534 if (!Tok.is(MMToken::ModuleKeyword)) {
1535 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1536 consumeToken();
1537 HadError = true;
1538 return;
1539 }
1540 consumeToken(); // 'module' keyword
1541
1542 // Parse the module name.
1543 ModuleId Id;
1544 if (parseModuleId(Id)) {
1545 HadError = true;
1546 return;
1547 }
1548
1549 // Parse the referenced module map file name.
1550 if (!Tok.is(MMToken::StringLiteral)) {
1551 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1552 HadError = true;
1553 return;
1554 }
1555 std::string FileName = Tok.getString();
1556 consumeToken(); // filename
1557
1558 StringRef FileNameRef = FileName;
1559 SmallString<128> ModuleMapFileName;
1560 if (llvm::sys::path::is_relative(FileNameRef)) {
1561 ModuleMapFileName += Directory->getName();
1562 llvm::sys::path::append(ModuleMapFileName, FileName);
1563 FileNameRef = ModuleMapFileName;
1564 }
1565 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1566 Map.parseModuleMapFile(
1567 File, /*IsSystem=*/false,
1568 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1569 ? Directory
1570 : File->getDir(), ExternLoc);
1571 }
1572
1573 /// \brief Parse a requires declaration.
1574 ///
1575 /// requires-declaration:
1576 /// 'requires' feature-list
1577 ///
1578 /// feature-list:
1579 /// feature ',' feature-list
1580 /// feature
1581 ///
1582 /// feature:
1583 /// '!'[opt] identifier
parseRequiresDecl()1584 void ModuleMapParser::parseRequiresDecl() {
1585 assert(Tok.is(MMToken::RequiresKeyword));
1586
1587 // Parse 'requires' keyword.
1588 consumeToken();
1589
1590 // Parse the feature-list.
1591 do {
1592 bool RequiredState = true;
1593 if (Tok.is(MMToken::Exclaim)) {
1594 RequiredState = false;
1595 consumeToken();
1596 }
1597
1598 if (!Tok.is(MMToken::Identifier)) {
1599 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1600 HadError = true;
1601 return;
1602 }
1603
1604 // Consume the feature name.
1605 std::string Feature = Tok.getString();
1606 consumeToken();
1607
1608 // Add this feature.
1609 ActiveModule->addRequirement(Feature, RequiredState,
1610 Map.LangOpts, *Map.Target);
1611
1612 if (!Tok.is(MMToken::Comma))
1613 break;
1614
1615 // Consume the comma.
1616 consumeToken();
1617 } while (true);
1618 }
1619
1620 /// \brief Append to \p Paths the set of paths needed to get to the
1621 /// subframework in which the given module lives.
appendSubframeworkPaths(Module * Mod,SmallVectorImpl<char> & Path)1622 static void appendSubframeworkPaths(Module *Mod,
1623 SmallVectorImpl<char> &Path) {
1624 // Collect the framework names from the given module to the top-level module.
1625 SmallVector<StringRef, 2> Paths;
1626 for (; Mod; Mod = Mod->Parent) {
1627 if (Mod->IsFramework)
1628 Paths.push_back(Mod->Name);
1629 }
1630
1631 if (Paths.empty())
1632 return;
1633
1634 // Add Frameworks/Name.framework for each subframework.
1635 for (unsigned I = Paths.size() - 1; I != 0; --I)
1636 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1637 }
1638
1639 /// \brief Parse a header declaration.
1640 ///
1641 /// header-declaration:
1642 /// 'textual'[opt] 'header' string-literal
1643 /// 'private' 'textual'[opt] 'header' string-literal
1644 /// 'exclude' 'header' string-literal
1645 /// 'umbrella' 'header' string-literal
1646 ///
1647 /// FIXME: Support 'private textual header'.
parseHeaderDecl(MMToken::TokenKind LeadingToken,SourceLocation LeadingLoc)1648 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1649 SourceLocation LeadingLoc) {
1650 // We've already consumed the first token.
1651 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1652 if (LeadingToken == MMToken::PrivateKeyword) {
1653 Role = ModuleMap::PrivateHeader;
1654 // 'private' may optionally be followed by 'textual'.
1655 if (Tok.is(MMToken::TextualKeyword)) {
1656 LeadingToken = Tok.Kind;
1657 consumeToken();
1658 }
1659 }
1660 if (LeadingToken == MMToken::TextualKeyword)
1661 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1662
1663 if (LeadingToken != MMToken::HeaderKeyword) {
1664 if (!Tok.is(MMToken::HeaderKeyword)) {
1665 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1666 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1667 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1668 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1669 return;
1670 }
1671 consumeToken();
1672 }
1673
1674 // Parse the header name.
1675 if (!Tok.is(MMToken::StringLiteral)) {
1676 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1677 << "header";
1678 HadError = true;
1679 return;
1680 }
1681 Module::UnresolvedHeaderDirective Header;
1682 Header.FileName = Tok.getString();
1683 Header.FileNameLoc = consumeToken();
1684
1685 // Check whether we already have an umbrella.
1686 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1687 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1688 << ActiveModule->getFullModuleName();
1689 HadError = true;
1690 return;
1691 }
1692
1693 // Look for this file.
1694 const FileEntry *File = nullptr;
1695 const FileEntry *BuiltinFile = nullptr;
1696 SmallString<128> RelativePathName;
1697 if (llvm::sys::path::is_absolute(Header.FileName)) {
1698 RelativePathName = Header.FileName;
1699 File = SourceMgr.getFileManager().getFile(RelativePathName);
1700 } else {
1701 // Search for the header file within the search directory.
1702 SmallString<128> FullPathName(Directory->getName());
1703 unsigned FullPathLength = FullPathName.size();
1704
1705 if (ActiveModule->isPartOfFramework()) {
1706 appendSubframeworkPaths(ActiveModule, RelativePathName);
1707
1708 // Check whether this file is in the public headers.
1709 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1710 llvm::sys::path::append(FullPathName, RelativePathName);
1711 File = SourceMgr.getFileManager().getFile(FullPathName);
1712
1713 if (!File) {
1714 // Check whether this file is in the private headers.
1715 // FIXME: Should we retain the subframework paths here?
1716 RelativePathName.clear();
1717 FullPathName.resize(FullPathLength);
1718 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1719 Header.FileName);
1720 llvm::sys::path::append(FullPathName, RelativePathName);
1721 File = SourceMgr.getFileManager().getFile(FullPathName);
1722 }
1723 } else {
1724 // Lookup for normal headers.
1725 llvm::sys::path::append(RelativePathName, Header.FileName);
1726 llvm::sys::path::append(FullPathName, RelativePathName);
1727 File = SourceMgr.getFileManager().getFile(FullPathName);
1728
1729 // If this is a system module with a top-level header, this header
1730 // may have a counterpart (or replacement) in the set of headers
1731 // supplied by Clang. Find that builtin header.
1732 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1733 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1734 isBuiltinHeader(Header.FileName)) {
1735 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1736 llvm::sys::path::append(BuiltinPathName, Header.FileName);
1737 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1738
1739 // If Clang supplies this header but the underlying system does not,
1740 // just silently swap in our builtin version. Otherwise, we'll end
1741 // up adding both (later).
1742 //
1743 // For local visibility, entirely replace the system file with our
1744 // one and textually include the system one. We need to pass macros
1745 // from our header to the system one if we #include_next it.
1746 //
1747 // FIXME: Can we do this in all cases?
1748 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
1749 File = BuiltinFile;
1750 RelativePathName = BuiltinPathName;
1751 BuiltinFile = nullptr;
1752 }
1753 }
1754 }
1755 }
1756
1757 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1758 // Come up with a lazy way to do this.
1759 if (File) {
1760 if (LeadingToken == MMToken::UmbrellaKeyword) {
1761 const DirectoryEntry *UmbrellaDir = File->getDir();
1762 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1763 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1764 << UmbrellaModule->getFullModuleName();
1765 HadError = true;
1766 } else {
1767 // Record this umbrella header.
1768 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
1769 }
1770 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1771 Module::Header H = {RelativePathName.str(), File};
1772 Map.excludeHeader(ActiveModule, H);
1773 } else {
1774 // If there is a builtin counterpart to this file, add it now, before
1775 // the "real" header, so we build the built-in one first when building
1776 // the module.
1777 if (BuiltinFile) {
1778 // FIXME: Taking the name from the FileEntry is unstable and can give
1779 // different results depending on how we've previously named that file
1780 // in this build.
1781 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1782 Map.addHeader(ActiveModule, H, Role);
1783 }
1784
1785 // Record this header.
1786 Module::Header H = { RelativePathName.str(), File };
1787 Map.addHeader(ActiveModule, H, Role);
1788 }
1789 } else if (LeadingToken != MMToken::ExcludeKeyword) {
1790 // Ignore excluded header files. They're optional anyway.
1791
1792 // If we find a module that has a missing header, we mark this module as
1793 // unavailable and store the header directive for displaying diagnostics.
1794 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1795 ActiveModule->markUnavailable();
1796 ActiveModule->MissingHeaders.push_back(Header);
1797 }
1798 }
1799
1800 /// \brief Parse an umbrella directory declaration.
1801 ///
1802 /// umbrella-dir-declaration:
1803 /// umbrella string-literal
parseUmbrellaDirDecl(SourceLocation UmbrellaLoc)1804 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1805 // Parse the directory name.
1806 if (!Tok.is(MMToken::StringLiteral)) {
1807 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1808 << "umbrella";
1809 HadError = true;
1810 return;
1811 }
1812
1813 std::string DirName = Tok.getString();
1814 SourceLocation DirNameLoc = consumeToken();
1815
1816 // Check whether we already have an umbrella.
1817 if (ActiveModule->Umbrella) {
1818 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1819 << ActiveModule->getFullModuleName();
1820 HadError = true;
1821 return;
1822 }
1823
1824 // Look for this file.
1825 const DirectoryEntry *Dir = nullptr;
1826 if (llvm::sys::path::is_absolute(DirName))
1827 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1828 else {
1829 SmallString<128> PathName;
1830 PathName = Directory->getName();
1831 llvm::sys::path::append(PathName, DirName);
1832 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1833 }
1834
1835 if (!Dir) {
1836 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1837 << DirName;
1838 HadError = true;
1839 return;
1840 }
1841
1842 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1843 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1844 << OwningModule->getFullModuleName();
1845 HadError = true;
1846 return;
1847 }
1848
1849 // Record this umbrella directory.
1850 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
1851 }
1852
1853 /// \brief Parse a module export declaration.
1854 ///
1855 /// export-declaration:
1856 /// 'export' wildcard-module-id
1857 ///
1858 /// wildcard-module-id:
1859 /// identifier
1860 /// '*'
1861 /// identifier '.' wildcard-module-id
parseExportDecl()1862 void ModuleMapParser::parseExportDecl() {
1863 assert(Tok.is(MMToken::ExportKeyword));
1864 SourceLocation ExportLoc = consumeToken();
1865
1866 // Parse the module-id with an optional wildcard at the end.
1867 ModuleId ParsedModuleId;
1868 bool Wildcard = false;
1869 do {
1870 // FIXME: Support string-literal module names here.
1871 if (Tok.is(MMToken::Identifier)) {
1872 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1873 Tok.getLocation()));
1874 consumeToken();
1875
1876 if (Tok.is(MMToken::Period)) {
1877 consumeToken();
1878 continue;
1879 }
1880
1881 break;
1882 }
1883
1884 if(Tok.is(MMToken::Star)) {
1885 Wildcard = true;
1886 consumeToken();
1887 break;
1888 }
1889
1890 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1891 HadError = true;
1892 return;
1893 } while (true);
1894
1895 Module::UnresolvedExportDecl Unresolved = {
1896 ExportLoc, ParsedModuleId, Wildcard
1897 };
1898 ActiveModule->UnresolvedExports.push_back(Unresolved);
1899 }
1900
1901 /// \brief Parse a module use declaration.
1902 ///
1903 /// use-declaration:
1904 /// 'use' wildcard-module-id
parseUseDecl()1905 void ModuleMapParser::parseUseDecl() {
1906 assert(Tok.is(MMToken::UseKeyword));
1907 auto KWLoc = consumeToken();
1908 // Parse the module-id.
1909 ModuleId ParsedModuleId;
1910 parseModuleId(ParsedModuleId);
1911
1912 if (ActiveModule->Parent)
1913 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
1914 else
1915 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1916 }
1917
1918 /// \brief Parse a link declaration.
1919 ///
1920 /// module-declaration:
1921 /// 'link' 'framework'[opt] string-literal
parseLinkDecl()1922 void ModuleMapParser::parseLinkDecl() {
1923 assert(Tok.is(MMToken::LinkKeyword));
1924 SourceLocation LinkLoc = consumeToken();
1925
1926 // Parse the optional 'framework' keyword.
1927 bool IsFramework = false;
1928 if (Tok.is(MMToken::FrameworkKeyword)) {
1929 consumeToken();
1930 IsFramework = true;
1931 }
1932
1933 // Parse the library name
1934 if (!Tok.is(MMToken::StringLiteral)) {
1935 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1936 << IsFramework << SourceRange(LinkLoc);
1937 HadError = true;
1938 return;
1939 }
1940
1941 std::string LibraryName = Tok.getString();
1942 consumeToken();
1943 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1944 IsFramework));
1945 }
1946
1947 /// \brief Parse a configuration macro declaration.
1948 ///
1949 /// module-declaration:
1950 /// 'config_macros' attributes[opt] config-macro-list?
1951 ///
1952 /// config-macro-list:
1953 /// identifier (',' identifier)?
parseConfigMacros()1954 void ModuleMapParser::parseConfigMacros() {
1955 assert(Tok.is(MMToken::ConfigMacros));
1956 SourceLocation ConfigMacrosLoc = consumeToken();
1957
1958 // Only top-level modules can have configuration macros.
1959 if (ActiveModule->Parent) {
1960 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1961 }
1962
1963 // Parse the optional attributes.
1964 Attributes Attrs;
1965 parseOptionalAttributes(Attrs);
1966 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1967 ActiveModule->ConfigMacrosExhaustive = true;
1968 }
1969
1970 // If we don't have an identifier, we're done.
1971 // FIXME: Support macros with the same name as a keyword here.
1972 if (!Tok.is(MMToken::Identifier))
1973 return;
1974
1975 // Consume the first identifier.
1976 if (!ActiveModule->Parent) {
1977 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1978 }
1979 consumeToken();
1980
1981 do {
1982 // If there's a comma, consume it.
1983 if (!Tok.is(MMToken::Comma))
1984 break;
1985 consumeToken();
1986
1987 // We expect to see a macro name here.
1988 // FIXME: Support macros with the same name as a keyword here.
1989 if (!Tok.is(MMToken::Identifier)) {
1990 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1991 break;
1992 }
1993
1994 // Consume the macro name.
1995 if (!ActiveModule->Parent) {
1996 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1997 }
1998 consumeToken();
1999 } while (true);
2000 }
2001
2002 /// \brief Format a module-id into a string.
formatModuleId(const ModuleId & Id)2003 static std::string formatModuleId(const ModuleId &Id) {
2004 std::string result;
2005 {
2006 llvm::raw_string_ostream OS(result);
2007
2008 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2009 if (I)
2010 OS << ".";
2011 OS << Id[I].first;
2012 }
2013 }
2014
2015 return result;
2016 }
2017
2018 /// \brief Parse a conflict declaration.
2019 ///
2020 /// module-declaration:
2021 /// 'conflict' module-id ',' string-literal
parseConflict()2022 void ModuleMapParser::parseConflict() {
2023 assert(Tok.is(MMToken::Conflict));
2024 SourceLocation ConflictLoc = consumeToken();
2025 Module::UnresolvedConflict Conflict;
2026
2027 // Parse the module-id.
2028 if (parseModuleId(Conflict.Id))
2029 return;
2030
2031 // Parse the ','.
2032 if (!Tok.is(MMToken::Comma)) {
2033 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2034 << SourceRange(ConflictLoc);
2035 return;
2036 }
2037 consumeToken();
2038
2039 // Parse the message.
2040 if (!Tok.is(MMToken::StringLiteral)) {
2041 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2042 << formatModuleId(Conflict.Id);
2043 return;
2044 }
2045 Conflict.Message = Tok.getString().str();
2046 consumeToken();
2047
2048 // Add this unresolved conflict.
2049 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2050 }
2051
2052 /// \brief Parse an inferred module declaration (wildcard modules).
2053 ///
2054 /// module-declaration:
2055 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2056 /// { inferred-module-member* }
2057 ///
2058 /// inferred-module-member:
2059 /// 'export' '*'
2060 /// 'exclude' identifier
parseInferredModuleDecl(bool Framework,bool Explicit)2061 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2062 assert(Tok.is(MMToken::Star));
2063 SourceLocation StarLoc = consumeToken();
2064 bool Failed = false;
2065
2066 // Inferred modules must be submodules.
2067 if (!ActiveModule && !Framework) {
2068 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2069 Failed = true;
2070 }
2071
2072 if (ActiveModule) {
2073 // Inferred modules must have umbrella directories.
2074 if (!Failed && ActiveModule->IsAvailable &&
2075 !ActiveModule->getUmbrellaDir()) {
2076 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2077 Failed = true;
2078 }
2079
2080 // Check for redefinition of an inferred module.
2081 if (!Failed && ActiveModule->InferSubmodules) {
2082 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2083 if (ActiveModule->InferredSubmoduleLoc.isValid())
2084 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2085 diag::note_mmap_prev_definition);
2086 Failed = true;
2087 }
2088
2089 // Check for the 'framework' keyword, which is not permitted here.
2090 if (Framework) {
2091 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2092 Framework = false;
2093 }
2094 } else if (Explicit) {
2095 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2096 Explicit = false;
2097 }
2098
2099 // If there were any problems with this inferred submodule, skip its body.
2100 if (Failed) {
2101 if (Tok.is(MMToken::LBrace)) {
2102 consumeToken();
2103 skipUntil(MMToken::RBrace);
2104 if (Tok.is(MMToken::RBrace))
2105 consumeToken();
2106 }
2107 HadError = true;
2108 return;
2109 }
2110
2111 // Parse optional attributes.
2112 Attributes Attrs;
2113 parseOptionalAttributes(Attrs);
2114
2115 if (ActiveModule) {
2116 // Note that we have an inferred submodule.
2117 ActiveModule->InferSubmodules = true;
2118 ActiveModule->InferredSubmoduleLoc = StarLoc;
2119 ActiveModule->InferExplicitSubmodules = Explicit;
2120 } else {
2121 // We'll be inferring framework modules for this directory.
2122 Map.InferredDirectories[Directory].InferModules = true;
2123 Map.InferredDirectories[Directory].Attrs = Attrs;
2124 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2125 // FIXME: Handle the 'framework' keyword.
2126 }
2127
2128 // Parse the opening brace.
2129 if (!Tok.is(MMToken::LBrace)) {
2130 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2131 HadError = true;
2132 return;
2133 }
2134 SourceLocation LBraceLoc = consumeToken();
2135
2136 // Parse the body of the inferred submodule.
2137 bool Done = false;
2138 do {
2139 switch (Tok.Kind) {
2140 case MMToken::EndOfFile:
2141 case MMToken::RBrace:
2142 Done = true;
2143 break;
2144
2145 case MMToken::ExcludeKeyword: {
2146 if (ActiveModule) {
2147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2148 << (ActiveModule != nullptr);
2149 consumeToken();
2150 break;
2151 }
2152
2153 consumeToken();
2154 // FIXME: Support string-literal module names here.
2155 if (!Tok.is(MMToken::Identifier)) {
2156 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2157 break;
2158 }
2159
2160 Map.InferredDirectories[Directory].ExcludedModules
2161 .push_back(Tok.getString());
2162 consumeToken();
2163 break;
2164 }
2165
2166 case MMToken::ExportKeyword:
2167 if (!ActiveModule) {
2168 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2169 << (ActiveModule != nullptr);
2170 consumeToken();
2171 break;
2172 }
2173
2174 consumeToken();
2175 if (Tok.is(MMToken::Star))
2176 ActiveModule->InferExportWildcard = true;
2177 else
2178 Diags.Report(Tok.getLocation(),
2179 diag::err_mmap_expected_export_wildcard);
2180 consumeToken();
2181 break;
2182
2183 case MMToken::ExplicitKeyword:
2184 case MMToken::ModuleKeyword:
2185 case MMToken::HeaderKeyword:
2186 case MMToken::PrivateKeyword:
2187 case MMToken::UmbrellaKeyword:
2188 default:
2189 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2190 << (ActiveModule != nullptr);
2191 consumeToken();
2192 break;
2193 }
2194 } while (!Done);
2195
2196 if (Tok.is(MMToken::RBrace))
2197 consumeToken();
2198 else {
2199 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2200 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2201 HadError = true;
2202 }
2203 }
2204
2205 /// \brief Parse optional attributes.
2206 ///
2207 /// attributes:
2208 /// attribute attributes
2209 /// attribute
2210 ///
2211 /// attribute:
2212 /// [ identifier ]
2213 ///
2214 /// \param Attrs Will be filled in with the parsed attributes.
2215 ///
2216 /// \returns true if an error occurred, false otherwise.
parseOptionalAttributes(Attributes & Attrs)2217 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2218 bool HadError = false;
2219
2220 while (Tok.is(MMToken::LSquare)) {
2221 // Consume the '['.
2222 SourceLocation LSquareLoc = consumeToken();
2223
2224 // Check whether we have an attribute name here.
2225 if (!Tok.is(MMToken::Identifier)) {
2226 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2227 skipUntil(MMToken::RSquare);
2228 if (Tok.is(MMToken::RSquare))
2229 consumeToken();
2230 HadError = true;
2231 }
2232
2233 // Decode the attribute name.
2234 AttributeKind Attribute
2235 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2236 .Case("exhaustive", AT_exhaustive)
2237 .Case("extern_c", AT_extern_c)
2238 .Case("system", AT_system)
2239 .Default(AT_unknown);
2240 switch (Attribute) {
2241 case AT_unknown:
2242 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2243 << Tok.getString();
2244 break;
2245
2246 case AT_system:
2247 Attrs.IsSystem = true;
2248 break;
2249
2250 case AT_extern_c:
2251 Attrs.IsExternC = true;
2252 break;
2253
2254 case AT_exhaustive:
2255 Attrs.IsExhaustive = true;
2256 break;
2257 }
2258 consumeToken();
2259
2260 // Consume the ']'.
2261 if (!Tok.is(MMToken::RSquare)) {
2262 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2263 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2264 skipUntil(MMToken::RSquare);
2265 HadError = true;
2266 }
2267
2268 if (Tok.is(MMToken::RSquare))
2269 consumeToken();
2270 }
2271
2272 return HadError;
2273 }
2274
2275 /// \brief Parse a module map file.
2276 ///
2277 /// module-map-file:
2278 /// module-declaration*
parseModuleMapFile()2279 bool ModuleMapParser::parseModuleMapFile() {
2280 do {
2281 switch (Tok.Kind) {
2282 case MMToken::EndOfFile:
2283 return HadError;
2284
2285 case MMToken::ExplicitKeyword:
2286 case MMToken::ExternKeyword:
2287 case MMToken::ModuleKeyword:
2288 case MMToken::FrameworkKeyword:
2289 parseModuleDecl();
2290 break;
2291
2292 case MMToken::Comma:
2293 case MMToken::ConfigMacros:
2294 case MMToken::Conflict:
2295 case MMToken::Exclaim:
2296 case MMToken::ExcludeKeyword:
2297 case MMToken::ExportKeyword:
2298 case MMToken::HeaderKeyword:
2299 case MMToken::Identifier:
2300 case MMToken::LBrace:
2301 case MMToken::LinkKeyword:
2302 case MMToken::LSquare:
2303 case MMToken::Period:
2304 case MMToken::PrivateKeyword:
2305 case MMToken::RBrace:
2306 case MMToken::RSquare:
2307 case MMToken::RequiresKeyword:
2308 case MMToken::Star:
2309 case MMToken::StringLiteral:
2310 case MMToken::TextualKeyword:
2311 case MMToken::UmbrellaKeyword:
2312 case MMToken::UseKeyword:
2313 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2314 HadError = true;
2315 consumeToken();
2316 break;
2317 }
2318 } while (true);
2319 }
2320
parseModuleMapFile(const FileEntry * File,bool IsSystem,const DirectoryEntry * Dir,SourceLocation ExternModuleLoc)2321 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2322 const DirectoryEntry *Dir,
2323 SourceLocation ExternModuleLoc) {
2324 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2325 = ParsedModuleMap.find(File);
2326 if (Known != ParsedModuleMap.end())
2327 return Known->second;
2328
2329 assert(Target && "Missing target information");
2330 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2331 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2332 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2333 if (!Buffer)
2334 return ParsedModuleMap[File] = true;
2335
2336 // Parse this module map file.
2337 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2338 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
2339 BuiltinIncludeDir, IsSystem);
2340 bool Result = Parser.parseModuleMapFile();
2341 ParsedModuleMap[File] = Result;
2342 return Result;
2343 }
2344