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