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/Lex/Lexer.h"
16 #include "clang/Lex/LiteralSupport.h"
17 #include "clang/Lex/LexDiagnostic.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/TargetOptions.h"
22 #include "llvm/Support/Allocator.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Host.h"
25 #include "llvm/Support/PathV2.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/StringSwitch.h"
29 using namespace clang;
30
31 Module::ExportDecl
resolveExport(Module * Mod,const Module::UnresolvedExportDecl & Unresolved,bool Complain)32 ModuleMap::resolveExport(Module *Mod,
33 const Module::UnresolvedExportDecl &Unresolved,
34 bool Complain) {
35 // We may have just a wildcard.
36 if (Unresolved.Id.empty()) {
37 assert(Unresolved.Wildcard && "Invalid unresolved export");
38 return Module::ExportDecl(0, true);
39 }
40
41 // Find the starting module.
42 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
43 if (!Context) {
44 if (Complain)
45 Diags->Report(Unresolved.Id[0].second,
46 diag::err_mmap_missing_module_unqualified)
47 << Unresolved.Id[0].first << Mod->getFullModuleName();
48
49 return Module::ExportDecl();
50 }
51
52 // Dig into the module path.
53 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
54 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
55 Context);
56 if (!Sub) {
57 if (Complain)
58 Diags->Report(Unresolved.Id[I].second,
59 diag::err_mmap_missing_module_qualified)
60 << Unresolved.Id[I].first << Context->getFullModuleName()
61 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
62
63 return Module::ExportDecl();
64 }
65
66 Context = Sub;
67 }
68
69 return Module::ExportDecl(Context, Unresolved.Wildcard);
70 }
71
ModuleMap(FileManager & FileMgr,const DiagnosticConsumer & DC,const LangOptions & LangOpts,const TargetInfo * Target)72 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
73 const LangOptions &LangOpts, const TargetInfo *Target)
74 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
75 {
76 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
77 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
78 new DiagnosticsEngine(DiagIDs));
79 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
80 SourceMgr = new SourceManager(*Diags, FileMgr);
81 }
82
~ModuleMap()83 ModuleMap::~ModuleMap() {
84 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
85 IEnd = Modules.end();
86 I != IEnd; ++I) {
87 delete I->getValue();
88 }
89
90 delete SourceMgr;
91 }
92
setTarget(const TargetInfo & Target)93 void ModuleMap::setTarget(const TargetInfo &Target) {
94 assert((!this->Target || this->Target == &Target) &&
95 "Improper target override");
96 this->Target = &Target;
97 }
98
findModuleForHeader(const FileEntry * File)99 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
100 llvm::DenseMap<const FileEntry *, Module *>::iterator Known
101 = Headers.find(File);
102 if (Known != Headers.end()) {
103 // If a header corresponds to an unavailable module, don't report
104 // that it maps to anything.
105 if (!Known->second->isAvailable())
106 return 0;
107
108 return Known->second;
109 }
110
111 const DirectoryEntry *Dir = File->getDir();
112 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
113 StringRef DirName = Dir->getName();
114
115 // Keep walking up the directory hierarchy, looking for a directory with
116 // an umbrella header.
117 do {
118 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
119 = UmbrellaDirs.find(Dir);
120 if (KnownDir != UmbrellaDirs.end()) {
121 Module *Result = KnownDir->second;
122
123 // Search up the module stack until we find a module with an umbrella
124 // directory.
125 Module *UmbrellaModule = Result;
126 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
127 UmbrellaModule = UmbrellaModule->Parent;
128
129 if (UmbrellaModule->InferSubmodules) {
130 // Infer submodules for each of the directories we found between
131 // the directory of the umbrella header and the directory where
132 // the actual header is located.
133 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
134
135 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
136 // Find or create the module that corresponds to this directory name.
137 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
138 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
139 Explicit).first;
140
141 // Associate the module and the directory.
142 UmbrellaDirs[SkippedDirs[I-1]] = Result;
143
144 // If inferred submodules export everything they import, add a
145 // wildcard to the set of exports.
146 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
147 Result->Exports.push_back(Module::ExportDecl(0, true));
148 }
149
150 // Infer a submodule with the same name as this header file.
151 StringRef Name = llvm::sys::path::stem(File->getName());
152 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
153 Explicit).first;
154
155 // If inferred submodules export everything they import, add a
156 // wildcard to the set of exports.
157 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
158 Result->Exports.push_back(Module::ExportDecl(0, true));
159 } else {
160 // Record each of the directories we stepped through as being part of
161 // the module we found, since the umbrella header covers them all.
162 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
163 UmbrellaDirs[SkippedDirs[I]] = Result;
164 }
165
166 Headers[File] = Result;
167
168 // If a header corresponds to an unavailable module, don't report
169 // that it maps to anything.
170 if (!Result->isAvailable())
171 return 0;
172
173 return Result;
174 }
175
176 SkippedDirs.push_back(Dir);
177
178 // Retrieve our parent path.
179 DirName = llvm::sys::path::parent_path(DirName);
180 if (DirName.empty())
181 break;
182
183 // Resolve the parent path to a directory entry.
184 Dir = SourceMgr->getFileManager().getDirectory(DirName);
185 } while (Dir);
186
187 return 0;
188 }
189
isHeaderInUnavailableModule(const FileEntry * Header)190 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
191 llvm::DenseMap<const FileEntry *, Module *>::iterator Known
192 = Headers.find(Header);
193 if (Known != Headers.end())
194 return !Known->second->isAvailable();
195
196 const DirectoryEntry *Dir = Header->getDir();
197 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
198 StringRef DirName = Dir->getName();
199
200 // Keep walking up the directory hierarchy, looking for a directory with
201 // an umbrella header.
202 do {
203 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
204 = UmbrellaDirs.find(Dir);
205 if (KnownDir != UmbrellaDirs.end()) {
206 Module *Found = KnownDir->second;
207 if (!Found->isAvailable())
208 return true;
209
210 // Search up the module stack until we find a module with an umbrella
211 // directory.
212 Module *UmbrellaModule = Found;
213 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
214 UmbrellaModule = UmbrellaModule->Parent;
215
216 if (UmbrellaModule->InferSubmodules) {
217 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
218 // Find or create the module that corresponds to this directory name.
219 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
220 Found = lookupModuleQualified(Name, Found);
221 if (!Found)
222 return false;
223 if (!Found->isAvailable())
224 return true;
225 }
226
227 // Infer a submodule with the same name as this header file.
228 StringRef Name = llvm::sys::path::stem(Header->getName());
229 Found = lookupModuleQualified(Name, Found);
230 if (!Found)
231 return false;
232 }
233
234 return !Found->isAvailable();
235 }
236
237 SkippedDirs.push_back(Dir);
238
239 // Retrieve our parent path.
240 DirName = llvm::sys::path::parent_path(DirName);
241 if (DirName.empty())
242 break;
243
244 // Resolve the parent path to a directory entry.
245 Dir = SourceMgr->getFileManager().getDirectory(DirName);
246 } while (Dir);
247
248 return false;
249 }
250
findModule(StringRef Name)251 Module *ModuleMap::findModule(StringRef Name) {
252 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
253 if (Known != Modules.end())
254 return Known->getValue();
255
256 return 0;
257 }
258
lookupModuleUnqualified(StringRef Name,Module * Context)259 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
260 for(; Context; Context = Context->Parent) {
261 if (Module *Sub = lookupModuleQualified(Name, Context))
262 return Sub;
263 }
264
265 return findModule(Name);
266 }
267
lookupModuleQualified(StringRef Name,Module * Context)268 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
269 if (!Context)
270 return findModule(Name);
271
272 return Context->findSubmodule(Name);
273 }
274
275 std::pair<Module *, bool>
findOrCreateModule(StringRef Name,Module * Parent,bool IsFramework,bool IsExplicit)276 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
277 bool IsExplicit) {
278 // Try to find an existing module with this name.
279 if (Module *Sub = lookupModuleQualified(Name, Parent))
280 return std::make_pair(Sub, false);
281
282 // Create a new module with this name.
283 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
284 IsExplicit);
285 if (!Parent)
286 Modules[Name] = Result;
287 return std::make_pair(Result, true);
288 }
289
290 Module *
inferFrameworkModule(StringRef ModuleName,const DirectoryEntry * FrameworkDir,bool IsSystem,Module * Parent)291 ModuleMap::inferFrameworkModule(StringRef ModuleName,
292 const DirectoryEntry *FrameworkDir,
293 bool IsSystem,
294 Module *Parent) {
295 // Check whether we've already found this module.
296 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
297 return Mod;
298
299 FileManager &FileMgr = SourceMgr->getFileManager();
300
301 // Look for an umbrella header.
302 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
303 llvm::sys::path::append(UmbrellaName, "Headers");
304 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
305 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
306
307 // FIXME: If there's no umbrella header, we could probably scan the
308 // framework to load *everything*. But, it's not clear that this is a good
309 // idea.
310 if (!UmbrellaHeader)
311 return 0;
312
313 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
314 /*IsFramework=*/true, /*IsExplicit=*/false);
315 if (IsSystem)
316 Result->IsSystem = IsSystem;
317
318 if (!Parent)
319 Modules[ModuleName] = Result;
320
321 // umbrella header "umbrella-header-name"
322 Result->Umbrella = UmbrellaHeader;
323 Headers[UmbrellaHeader] = Result;
324 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
325
326 // export *
327 Result->Exports.push_back(Module::ExportDecl(0, true));
328
329 // module * { export * }
330 Result->InferSubmodules = true;
331 Result->InferExportWildcard = true;
332
333 // Look for subframeworks.
334 llvm::error_code EC;
335 SmallString<128> SubframeworksDirName
336 = StringRef(FrameworkDir->getName());
337 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
338 SmallString<128> SubframeworksDirNameNative;
339 llvm::sys::path::native(SubframeworksDirName.str(),
340 SubframeworksDirNameNative);
341 for (llvm::sys::fs::directory_iterator
342 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
343 Dir != DirEnd && !EC; Dir.increment(EC)) {
344 if (!StringRef(Dir->path()).endswith(".framework"))
345 continue;
346
347 if (const DirectoryEntry *SubframeworkDir
348 = FileMgr.getDirectory(Dir->path())) {
349 // FIXME: Do we want to warn about subframeworks without umbrella headers?
350 inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
351 IsSystem, Result);
352 }
353 }
354
355 return Result;
356 }
357
setUmbrellaHeader(Module * Mod,const FileEntry * UmbrellaHeader)358 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
359 Headers[UmbrellaHeader] = Mod;
360 Mod->Umbrella = UmbrellaHeader;
361 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
362 }
363
setUmbrellaDir(Module * Mod,const DirectoryEntry * UmbrellaDir)364 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
365 Mod->Umbrella = UmbrellaDir;
366 UmbrellaDirs[UmbrellaDir] = Mod;
367 }
368
addHeader(Module * Mod,const FileEntry * Header)369 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
370 Mod->Headers.push_back(Header);
371 Headers[Header] = Mod;
372 }
373
374 const FileEntry *
getContainingModuleMapFile(Module * Module)375 ModuleMap::getContainingModuleMapFile(Module *Module) {
376 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
377 return 0;
378
379 return SourceMgr->getFileEntryForID(
380 SourceMgr->getFileID(Module->DefinitionLoc));
381 }
382
dump()383 void ModuleMap::dump() {
384 llvm::errs() << "Modules:";
385 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
386 MEnd = Modules.end();
387 M != MEnd; ++M)
388 M->getValue()->print(llvm::errs(), 2);
389
390 llvm::errs() << "Headers:";
391 for (llvm::DenseMap<const FileEntry *, Module *>::iterator
392 H = Headers.begin(),
393 HEnd = Headers.end();
394 H != HEnd; ++H) {
395 llvm::errs() << " \"" << H->first->getName() << "\" -> "
396 << H->second->getFullModuleName() << "\n";
397 }
398 }
399
resolveExports(Module * Mod,bool Complain)400 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
401 bool HadError = false;
402 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
403 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
404 Complain);
405 if (Export.getPointer() || Export.getInt())
406 Mod->Exports.push_back(Export);
407 else
408 HadError = true;
409 }
410 Mod->UnresolvedExports.clear();
411 return HadError;
412 }
413
inferModuleFromLocation(FullSourceLoc Loc)414 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
415 if (Loc.isInvalid())
416 return 0;
417
418 // Use the expansion location to determine which module we're in.
419 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
420 if (!ExpansionLoc.isFileID())
421 return 0;
422
423
424 const SourceManager &SrcMgr = Loc.getManager();
425 FileID ExpansionFileID = ExpansionLoc.getFileID();
426
427 while (const FileEntry *ExpansionFile
428 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
429 // Find the module that owns this header (if any).
430 if (Module *Mod = findModuleForHeader(ExpansionFile))
431 return Mod;
432
433 // No module owns this header, so look up the inclusion chain to see if
434 // any included header has an associated module.
435 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
436 if (IncludeLoc.isInvalid())
437 return 0;
438
439 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
440 }
441
442 return 0;
443 }
444
445 //----------------------------------------------------------------------------//
446 // Module map file parser
447 //----------------------------------------------------------------------------//
448
449 namespace clang {
450 /// \brief A token in a module map file.
451 struct MMToken {
452 enum TokenKind {
453 Comma,
454 EndOfFile,
455 HeaderKeyword,
456 Identifier,
457 ExplicitKeyword,
458 ExportKeyword,
459 FrameworkKeyword,
460 ModuleKeyword,
461 Period,
462 UmbrellaKeyword,
463 RequiresKeyword,
464 Star,
465 StringLiteral,
466 LBrace,
467 RBrace,
468 LSquare,
469 RSquare
470 } Kind;
471
472 unsigned Location;
473 unsigned StringLength;
474 const char *StringData;
475
clearclang::MMToken476 void clear() {
477 Kind = EndOfFile;
478 Location = 0;
479 StringLength = 0;
480 StringData = 0;
481 }
482
isclang::MMToken483 bool is(TokenKind K) const { return Kind == K; }
484
getLocationclang::MMToken485 SourceLocation getLocation() const {
486 return SourceLocation::getFromRawEncoding(Location);
487 }
488
getStringclang::MMToken489 StringRef getString() const {
490 return StringRef(StringData, StringLength);
491 }
492 };
493
494 class ModuleMapParser {
495 Lexer &L;
496 SourceManager &SourceMgr;
497 DiagnosticsEngine &Diags;
498 ModuleMap ⤅
499
500 /// \brief The directory that this module map resides in.
501 const DirectoryEntry *Directory;
502
503 /// \brief The directory containing Clang-supplied headers.
504 const DirectoryEntry *BuiltinIncludeDir;
505
506 /// \brief Whether an error occurred.
507 bool HadError;
508
509 /// \brief Default target information, used only for string literal
510 /// parsing.
511 OwningPtr<TargetInfo> Target;
512
513 /// \brief Stores string data for the various string literals referenced
514 /// during parsing.
515 llvm::BumpPtrAllocator StringData;
516
517 /// \brief The current token.
518 MMToken Tok;
519
520 /// \brief The active module.
521 Module *ActiveModule;
522
523 /// \brief Consume the current token and return its location.
524 SourceLocation consumeToken();
525
526 /// \brief Skip tokens until we reach the a token with the given kind
527 /// (or the end of the file).
528 void skipUntil(MMToken::TokenKind K);
529
530 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
531 ModuleId;
532 bool parseModuleId(ModuleId &Id);
533 void parseModuleDecl();
534 void parseRequiresDecl();
535 void parseHeaderDecl(SourceLocation UmbrellaLoc);
536 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
537 void parseExportDecl();
538 void parseInferredSubmoduleDecl(bool Explicit);
539
540 const DirectoryEntry *getOverriddenHeaderSearchDir();
541
542 public:
ModuleMapParser(Lexer & L,SourceManager & SourceMgr,DiagnosticsEngine & Diags,ModuleMap & Map,const DirectoryEntry * Directory,const DirectoryEntry * BuiltinIncludeDir)543 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
544 DiagnosticsEngine &Diags,
545 ModuleMap &Map,
546 const DirectoryEntry *Directory,
547 const DirectoryEntry *BuiltinIncludeDir)
548 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
549 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
550 HadError(false), ActiveModule(0)
551 {
552 TargetOptions TargetOpts;
553 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
554 Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts));
555
556 Tok.clear();
557 consumeToken();
558 }
559
560 bool parseModuleMapFile();
561 };
562 }
563
consumeToken()564 SourceLocation ModuleMapParser::consumeToken() {
565 retry:
566 SourceLocation Result = Tok.getLocation();
567 Tok.clear();
568
569 Token LToken;
570 L.LexFromRawLexer(LToken);
571 Tok.Location = LToken.getLocation().getRawEncoding();
572 switch (LToken.getKind()) {
573 case tok::raw_identifier:
574 Tok.StringData = LToken.getRawIdentifierData();
575 Tok.StringLength = LToken.getLength();
576 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
577 .Case("header", MMToken::HeaderKeyword)
578 .Case("explicit", MMToken::ExplicitKeyword)
579 .Case("export", MMToken::ExportKeyword)
580 .Case("framework", MMToken::FrameworkKeyword)
581 .Case("module", MMToken::ModuleKeyword)
582 .Case("requires", MMToken::RequiresKeyword)
583 .Case("umbrella", MMToken::UmbrellaKeyword)
584 .Default(MMToken::Identifier);
585 break;
586
587 case tok::comma:
588 Tok.Kind = MMToken::Comma;
589 break;
590
591 case tok::eof:
592 Tok.Kind = MMToken::EndOfFile;
593 break;
594
595 case tok::l_brace:
596 Tok.Kind = MMToken::LBrace;
597 break;
598
599 case tok::l_square:
600 Tok.Kind = MMToken::LSquare;
601 break;
602
603 case tok::period:
604 Tok.Kind = MMToken::Period;
605 break;
606
607 case tok::r_brace:
608 Tok.Kind = MMToken::RBrace;
609 break;
610
611 case tok::r_square:
612 Tok.Kind = MMToken::RSquare;
613 break;
614
615 case tok::star:
616 Tok.Kind = MMToken::Star;
617 break;
618
619 case tok::string_literal: {
620 if (LToken.hasUDSuffix()) {
621 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
622 HadError = true;
623 goto retry;
624 }
625
626 // Parse the string literal.
627 LangOptions LangOpts;
628 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target);
629 if (StringLiteral.hadError)
630 goto retry;
631
632 // Copy the string literal into our string data allocator.
633 unsigned Length = StringLiteral.GetStringLength();
634 char *Saved = StringData.Allocate<char>(Length + 1);
635 memcpy(Saved, StringLiteral.GetString().data(), Length);
636 Saved[Length] = 0;
637
638 // Form the token.
639 Tok.Kind = MMToken::StringLiteral;
640 Tok.StringData = Saved;
641 Tok.StringLength = Length;
642 break;
643 }
644
645 case tok::comment:
646 goto retry;
647
648 default:
649 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
650 HadError = true;
651 goto retry;
652 }
653
654 return Result;
655 }
656
skipUntil(MMToken::TokenKind K)657 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
658 unsigned braceDepth = 0;
659 unsigned squareDepth = 0;
660 do {
661 switch (Tok.Kind) {
662 case MMToken::EndOfFile:
663 return;
664
665 case MMToken::LBrace:
666 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
667 return;
668
669 ++braceDepth;
670 break;
671
672 case MMToken::LSquare:
673 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
674 return;
675
676 ++squareDepth;
677 break;
678
679 case MMToken::RBrace:
680 if (braceDepth > 0)
681 --braceDepth;
682 else if (Tok.is(K))
683 return;
684 break;
685
686 case MMToken::RSquare:
687 if (squareDepth > 0)
688 --squareDepth;
689 else if (Tok.is(K))
690 return;
691 break;
692
693 default:
694 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
695 return;
696 break;
697 }
698
699 consumeToken();
700 } while (true);
701 }
702
703 /// \brief Parse a module-id.
704 ///
705 /// module-id:
706 /// identifier
707 /// identifier '.' module-id
708 ///
709 /// \returns true if an error occurred, false otherwise.
parseModuleId(ModuleId & Id)710 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
711 Id.clear();
712 do {
713 if (Tok.is(MMToken::Identifier)) {
714 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
715 consumeToken();
716 } else {
717 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
718 return true;
719 }
720
721 if (!Tok.is(MMToken::Period))
722 break;
723
724 consumeToken();
725 } while (true);
726
727 return false;
728 }
729
730 namespace {
731 /// \brief Enumerates the known attributes.
732 enum AttributeKind {
733 /// \brief An unknown attribute.
734 AT_unknown,
735 /// \brief The 'system' attribute.
736 AT_system
737 };
738 }
739
740 /// \brief Parse a module declaration.
741 ///
742 /// module-declaration:
743 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
744 /// { module-member* }
745 ///
746 /// attributes:
747 /// attribute attributes
748 /// attribute
749 ///
750 /// attribute:
751 /// [ identifier ]
752 ///
753 /// module-member:
754 /// requires-declaration
755 /// header-declaration
756 /// submodule-declaration
757 /// export-declaration
758 ///
759 /// submodule-declaration:
760 /// module-declaration
761 /// inferred-submodule-declaration
parseModuleDecl()762 void ModuleMapParser::parseModuleDecl() {
763 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
764 Tok.is(MMToken::FrameworkKeyword));
765 // Parse 'explicit' or 'framework' keyword, if present.
766 SourceLocation ExplicitLoc;
767 bool Explicit = false;
768 bool Framework = false;
769
770 // Parse 'explicit' keyword, if present.
771 if (Tok.is(MMToken::ExplicitKeyword)) {
772 ExplicitLoc = consumeToken();
773 Explicit = true;
774 }
775
776 // Parse 'framework' keyword, if present.
777 if (Tok.is(MMToken::FrameworkKeyword)) {
778 consumeToken();
779 Framework = true;
780 }
781
782 // Parse 'module' keyword.
783 if (!Tok.is(MMToken::ModuleKeyword)) {
784 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
785 consumeToken();
786 HadError = true;
787 return;
788 }
789 consumeToken(); // 'module' keyword
790
791 // If we have a wildcard for the module name, this is an inferred submodule.
792 // Parse it.
793 if (Tok.is(MMToken::Star))
794 return parseInferredSubmoduleDecl(Explicit);
795
796 // Parse the module name.
797 ModuleId Id;
798 if (parseModuleId(Id)) {
799 HadError = true;
800 return;
801 }
802
803 if (ActiveModule) {
804 if (Id.size() > 1) {
805 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
806 << SourceRange(Id.front().second, Id.back().second);
807
808 HadError = true;
809 return;
810 }
811 } else if (Id.size() == 1 && Explicit) {
812 // Top-level modules can't be explicit.
813 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
814 Explicit = false;
815 ExplicitLoc = SourceLocation();
816 HadError = true;
817 }
818
819 Module *PreviousActiveModule = ActiveModule;
820 if (Id.size() > 1) {
821 // This module map defines a submodule. Go find the module of which it
822 // is a submodule.
823 ActiveModule = 0;
824 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
825 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
826 ActiveModule = Next;
827 continue;
828 }
829
830 if (ActiveModule) {
831 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
832 << Id[I].first << ActiveModule->getTopLevelModule();
833 } else {
834 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
835 }
836 HadError = true;
837 return;
838 }
839 }
840
841 StringRef ModuleName = Id.back().first;
842 SourceLocation ModuleNameLoc = Id.back().second;
843
844 // Parse the optional attribute list.
845 bool IsSystem = false;
846 while (Tok.is(MMToken::LSquare)) {
847 // Consume the '['.
848 SourceLocation LSquareLoc = consumeToken();
849
850 // Check whether we have an attribute name here.
851 if (!Tok.is(MMToken::Identifier)) {
852 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
853 skipUntil(MMToken::RSquare);
854 if (Tok.is(MMToken::RSquare))
855 consumeToken();
856 continue;
857 }
858
859 // Decode the attribute name.
860 AttributeKind Attribute
861 = llvm::StringSwitch<AttributeKind>(Tok.getString())
862 .Case("system", AT_system)
863 .Default(AT_unknown);
864 switch (Attribute) {
865 case AT_unknown:
866 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
867 << Tok.getString();
868 break;
869
870 case AT_system:
871 IsSystem = true;
872 break;
873 }
874 consumeToken();
875
876 // Consume the ']'.
877 if (!Tok.is(MMToken::RSquare)) {
878 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
879 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
880 skipUntil(MMToken::RSquare);
881 }
882
883 if (Tok.is(MMToken::RSquare))
884 consumeToken();
885 }
886
887 // Parse the opening brace.
888 if (!Tok.is(MMToken::LBrace)) {
889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
890 << ModuleName;
891 HadError = true;
892 return;
893 }
894 SourceLocation LBraceLoc = consumeToken();
895
896 // Determine whether this (sub)module has already been defined.
897 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
898 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
899 // Skip the module definition.
900 skipUntil(MMToken::RBrace);
901 if (Tok.is(MMToken::RBrace))
902 consumeToken();
903 else {
904 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
905 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
906 HadError = true;
907 }
908 return;
909 }
910
911 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
912 << ModuleName;
913 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
914
915 // Skip the module definition.
916 skipUntil(MMToken::RBrace);
917 if (Tok.is(MMToken::RBrace))
918 consumeToken();
919
920 HadError = true;
921 return;
922 }
923
924 // Start defining this module.
925 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
926 Explicit).first;
927 ActiveModule->DefinitionLoc = ModuleNameLoc;
928 if (IsSystem)
929 ActiveModule->IsSystem = true;
930
931 bool Done = false;
932 do {
933 switch (Tok.Kind) {
934 case MMToken::EndOfFile:
935 case MMToken::RBrace:
936 Done = true;
937 break;
938
939 case MMToken::ExplicitKeyword:
940 case MMToken::FrameworkKeyword:
941 case MMToken::ModuleKeyword:
942 parseModuleDecl();
943 break;
944
945 case MMToken::ExportKeyword:
946 parseExportDecl();
947 break;
948
949 case MMToken::RequiresKeyword:
950 parseRequiresDecl();
951 break;
952
953 case MMToken::UmbrellaKeyword: {
954 SourceLocation UmbrellaLoc = consumeToken();
955 if (Tok.is(MMToken::HeaderKeyword))
956 parseHeaderDecl(UmbrellaLoc);
957 else
958 parseUmbrellaDirDecl(UmbrellaLoc);
959 break;
960 }
961
962 case MMToken::HeaderKeyword:
963 parseHeaderDecl(SourceLocation());
964 break;
965
966 default:
967 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
968 consumeToken();
969 break;
970 }
971 } while (!Done);
972
973 if (Tok.is(MMToken::RBrace))
974 consumeToken();
975 else {
976 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
977 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
978 HadError = true;
979 }
980
981 // We're done parsing this module. Pop back to the previous module.
982 ActiveModule = PreviousActiveModule;
983 }
984
985 /// \brief Parse a requires declaration.
986 ///
987 /// requires-declaration:
988 /// 'requires' feature-list
989 ///
990 /// feature-list:
991 /// identifier ',' feature-list
992 /// identifier
parseRequiresDecl()993 void ModuleMapParser::parseRequiresDecl() {
994 assert(Tok.is(MMToken::RequiresKeyword));
995
996 // Parse 'requires' keyword.
997 consumeToken();
998
999 // Parse the feature-list.
1000 do {
1001 if (!Tok.is(MMToken::Identifier)) {
1002 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1003 HadError = true;
1004 return;
1005 }
1006
1007 // Consume the feature name.
1008 std::string Feature = Tok.getString();
1009 consumeToken();
1010
1011 // Add this feature.
1012 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
1013
1014 if (!Tok.is(MMToken::Comma))
1015 break;
1016
1017 // Consume the comma.
1018 consumeToken();
1019 } while (true);
1020 }
1021
1022 /// \brief Append to \p Paths the set of paths needed to get to the
1023 /// subframework in which the given module lives.
appendSubframeworkPaths(Module * Mod,llvm::SmallVectorImpl<char> & Path)1024 static void appendSubframeworkPaths(Module *Mod,
1025 llvm::SmallVectorImpl<char> &Path) {
1026 // Collect the framework names from the given module to the top-level module.
1027 llvm::SmallVector<StringRef, 2> Paths;
1028 for (; Mod; Mod = Mod->Parent) {
1029 if (Mod->IsFramework)
1030 Paths.push_back(Mod->Name);
1031 }
1032
1033 if (Paths.empty())
1034 return;
1035
1036 // Add Frameworks/Name.framework for each subframework.
1037 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1038 llvm::sys::path::append(Path, "Frameworks");
1039 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1040 }
1041 }
1042
1043 /// \brief Determine whether the given file name is the name of a builtin
1044 /// header, supplied by Clang to replace, override, or augment existing system
1045 /// headers.
isBuiltinHeader(StringRef FileName)1046 static bool isBuiltinHeader(StringRef FileName) {
1047 return llvm::StringSwitch<bool>(FileName)
1048 .Case("float.h", true)
1049 .Case("iso646.h", true)
1050 .Case("limits.h", true)
1051 .Case("stdalign.h", true)
1052 .Case("stdarg.h", true)
1053 .Case("stdbool.h", true)
1054 .Case("stddef.h", true)
1055 .Case("stdint.h", true)
1056 .Case("tgmath.h", true)
1057 .Case("unwind.h", true)
1058 .Default(false);
1059 }
1060
1061 /// \brief Parse a header declaration.
1062 ///
1063 /// header-declaration:
1064 /// 'umbrella'[opt] 'header' string-literal
parseHeaderDecl(SourceLocation UmbrellaLoc)1065 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
1066 assert(Tok.is(MMToken::HeaderKeyword));
1067 consumeToken();
1068
1069 bool Umbrella = UmbrellaLoc.isValid();
1070
1071 // Parse the header name.
1072 if (!Tok.is(MMToken::StringLiteral)) {
1073 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1074 << "header";
1075 HadError = true;
1076 return;
1077 }
1078 std::string FileName = Tok.getString();
1079 SourceLocation FileNameLoc = consumeToken();
1080
1081 // Check whether we already have an umbrella.
1082 if (Umbrella && ActiveModule->Umbrella) {
1083 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1084 << ActiveModule->getFullModuleName();
1085 HadError = true;
1086 return;
1087 }
1088
1089 // Look for this file.
1090 const FileEntry *File = 0;
1091 const FileEntry *BuiltinFile = 0;
1092 SmallString<128> PathName;
1093 if (llvm::sys::path::is_absolute(FileName)) {
1094 PathName = FileName;
1095 File = SourceMgr.getFileManager().getFile(PathName);
1096 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1097 PathName = Dir->getName();
1098 llvm::sys::path::append(PathName, FileName);
1099 File = SourceMgr.getFileManager().getFile(PathName);
1100 } else {
1101 // Search for the header file within the search directory.
1102 PathName = Directory->getName();
1103 unsigned PathLength = PathName.size();
1104
1105 if (ActiveModule->isPartOfFramework()) {
1106 appendSubframeworkPaths(ActiveModule, PathName);
1107
1108 // Check whether this file is in the public headers.
1109 llvm::sys::path::append(PathName, "Headers");
1110 llvm::sys::path::append(PathName, FileName);
1111 File = SourceMgr.getFileManager().getFile(PathName);
1112
1113 if (!File) {
1114 // Check whether this file is in the private headers.
1115 PathName.resize(PathLength);
1116 llvm::sys::path::append(PathName, "PrivateHeaders");
1117 llvm::sys::path::append(PathName, FileName);
1118 File = SourceMgr.getFileManager().getFile(PathName);
1119 }
1120 } else {
1121 // Lookup for normal headers.
1122 llvm::sys::path::append(PathName, FileName);
1123 File = SourceMgr.getFileManager().getFile(PathName);
1124
1125 // If this is a system module with a top-level header, this header
1126 // may have a counterpart (or replacement) in the set of headers
1127 // supplied by Clang. Find that builtin header.
1128 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1129 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
1130 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1131 llvm::sys::path::append(BuiltinPathName, FileName);
1132 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1133
1134 // If Clang supplies this header but the underlying system does not,
1135 // just silently swap in our builtin version. Otherwise, we'll end
1136 // up adding both (later).
1137 if (!File && BuiltinFile) {
1138 File = BuiltinFile;
1139 BuiltinFile = 0;
1140 }
1141 }
1142 }
1143 }
1144
1145 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1146 // Come up with a lazy way to do this.
1147 if (File) {
1148 if (const Module *OwningModule = Map.Headers[File]) {
1149 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1150 << FileName << OwningModule->getFullModuleName();
1151 HadError = true;
1152 } else if (Umbrella) {
1153 const DirectoryEntry *UmbrellaDir = File->getDir();
1154 if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
1155 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1156 << OwningModule->getFullModuleName();
1157 HadError = true;
1158 } else {
1159 // Record this umbrella header.
1160 Map.setUmbrellaHeader(ActiveModule, File);
1161 }
1162 } else {
1163 // Record this header.
1164 Map.addHeader(ActiveModule, File);
1165
1166 // If there is a builtin counterpart to this file, add it now.
1167 if (BuiltinFile)
1168 Map.addHeader(ActiveModule, BuiltinFile);
1169 }
1170 } else {
1171 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1172 << Umbrella << FileName;
1173 HadError = true;
1174 }
1175 }
1176
1177 /// \brief Parse an umbrella directory declaration.
1178 ///
1179 /// umbrella-dir-declaration:
1180 /// umbrella string-literal
parseUmbrellaDirDecl(SourceLocation UmbrellaLoc)1181 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1182 // Parse the directory name.
1183 if (!Tok.is(MMToken::StringLiteral)) {
1184 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1185 << "umbrella";
1186 HadError = true;
1187 return;
1188 }
1189
1190 std::string DirName = Tok.getString();
1191 SourceLocation DirNameLoc = consumeToken();
1192
1193 // Check whether we already have an umbrella.
1194 if (ActiveModule->Umbrella) {
1195 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1196 << ActiveModule->getFullModuleName();
1197 HadError = true;
1198 return;
1199 }
1200
1201 // Look for this file.
1202 const DirectoryEntry *Dir = 0;
1203 if (llvm::sys::path::is_absolute(DirName))
1204 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1205 else {
1206 SmallString<128> PathName;
1207 PathName = Directory->getName();
1208 llvm::sys::path::append(PathName, DirName);
1209 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1210 }
1211
1212 if (!Dir) {
1213 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1214 << DirName;
1215 HadError = true;
1216 return;
1217 }
1218
1219 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1220 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1221 << OwningModule->getFullModuleName();
1222 HadError = true;
1223 return;
1224 }
1225
1226 // Record this umbrella directory.
1227 Map.setUmbrellaDir(ActiveModule, Dir);
1228 }
1229
1230 /// \brief Parse a module export declaration.
1231 ///
1232 /// export-declaration:
1233 /// 'export' wildcard-module-id
1234 ///
1235 /// wildcard-module-id:
1236 /// identifier
1237 /// '*'
1238 /// identifier '.' wildcard-module-id
parseExportDecl()1239 void ModuleMapParser::parseExportDecl() {
1240 assert(Tok.is(MMToken::ExportKeyword));
1241 SourceLocation ExportLoc = consumeToken();
1242
1243 // Parse the module-id with an optional wildcard at the end.
1244 ModuleId ParsedModuleId;
1245 bool Wildcard = false;
1246 do {
1247 if (Tok.is(MMToken::Identifier)) {
1248 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1249 Tok.getLocation()));
1250 consumeToken();
1251
1252 if (Tok.is(MMToken::Period)) {
1253 consumeToken();
1254 continue;
1255 }
1256
1257 break;
1258 }
1259
1260 if(Tok.is(MMToken::Star)) {
1261 Wildcard = true;
1262 consumeToken();
1263 break;
1264 }
1265
1266 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1267 HadError = true;
1268 return;
1269 } while (true);
1270
1271 Module::UnresolvedExportDecl Unresolved = {
1272 ExportLoc, ParsedModuleId, Wildcard
1273 };
1274 ActiveModule->UnresolvedExports.push_back(Unresolved);
1275 }
1276
parseInferredSubmoduleDecl(bool Explicit)1277 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
1278 assert(Tok.is(MMToken::Star));
1279 SourceLocation StarLoc = consumeToken();
1280 bool Failed = false;
1281
1282 // Inferred modules must be submodules.
1283 if (!ActiveModule) {
1284 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1285 Failed = true;
1286 }
1287
1288 // Inferred modules must have umbrella directories.
1289 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1290 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1291 Failed = true;
1292 }
1293
1294 // Check for redefinition of an inferred module.
1295 if (!Failed && ActiveModule->InferSubmodules) {
1296 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1297 if (ActiveModule->InferredSubmoduleLoc.isValid())
1298 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1299 diag::note_mmap_prev_definition);
1300 Failed = true;
1301 }
1302
1303 // If there were any problems with this inferred submodule, skip its body.
1304 if (Failed) {
1305 if (Tok.is(MMToken::LBrace)) {
1306 consumeToken();
1307 skipUntil(MMToken::RBrace);
1308 if (Tok.is(MMToken::RBrace))
1309 consumeToken();
1310 }
1311 HadError = true;
1312 return;
1313 }
1314
1315 // Note that we have an inferred submodule.
1316 ActiveModule->InferSubmodules = true;
1317 ActiveModule->InferredSubmoduleLoc = StarLoc;
1318 ActiveModule->InferExplicitSubmodules = Explicit;
1319
1320 // Parse the opening brace.
1321 if (!Tok.is(MMToken::LBrace)) {
1322 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1323 HadError = true;
1324 return;
1325 }
1326 SourceLocation LBraceLoc = consumeToken();
1327
1328 // Parse the body of the inferred submodule.
1329 bool Done = false;
1330 do {
1331 switch (Tok.Kind) {
1332 case MMToken::EndOfFile:
1333 case MMToken::RBrace:
1334 Done = true;
1335 break;
1336
1337 case MMToken::ExportKeyword: {
1338 consumeToken();
1339 if (Tok.is(MMToken::Star))
1340 ActiveModule->InferExportWildcard = true;
1341 else
1342 Diags.Report(Tok.getLocation(),
1343 diag::err_mmap_expected_export_wildcard);
1344 consumeToken();
1345 break;
1346 }
1347
1348 case MMToken::ExplicitKeyword:
1349 case MMToken::ModuleKeyword:
1350 case MMToken::HeaderKeyword:
1351 case MMToken::UmbrellaKeyword:
1352 default:
1353 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
1354 consumeToken();
1355 break;
1356 }
1357 } while (!Done);
1358
1359 if (Tok.is(MMToken::RBrace))
1360 consumeToken();
1361 else {
1362 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1363 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1364 HadError = true;
1365 }
1366 }
1367
1368 /// \brief If there is a specific header search directory due the presence
1369 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
getOverriddenHeaderSearchDir()1370 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1371 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1372 // If we have an umbrella directory, use that.
1373 if (Mod->hasUmbrellaDir())
1374 return Mod->getUmbrellaDir();
1375
1376 // If we have a framework directory, stop looking.
1377 if (Mod->IsFramework)
1378 return 0;
1379 }
1380
1381 return 0;
1382 }
1383
1384 /// \brief Parse a module map file.
1385 ///
1386 /// module-map-file:
1387 /// module-declaration*
parseModuleMapFile()1388 bool ModuleMapParser::parseModuleMapFile() {
1389 do {
1390 switch (Tok.Kind) {
1391 case MMToken::EndOfFile:
1392 return HadError;
1393
1394 case MMToken::ExplicitKeyword:
1395 case MMToken::ModuleKeyword:
1396 case MMToken::FrameworkKeyword:
1397 parseModuleDecl();
1398 break;
1399
1400 case MMToken::Comma:
1401 case MMToken::ExportKeyword:
1402 case MMToken::HeaderKeyword:
1403 case MMToken::Identifier:
1404 case MMToken::LBrace:
1405 case MMToken::LSquare:
1406 case MMToken::Period:
1407 case MMToken::RBrace:
1408 case MMToken::RSquare:
1409 case MMToken::RequiresKeyword:
1410 case MMToken::Star:
1411 case MMToken::StringLiteral:
1412 case MMToken::UmbrellaKeyword:
1413 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1414 HadError = true;
1415 consumeToken();
1416 break;
1417 }
1418 } while (true);
1419 }
1420
parseModuleMapFile(const FileEntry * File)1421 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1422 assert(Target != 0 && "Missing target information");
1423 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1424 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1425 if (!Buffer)
1426 return true;
1427
1428 // Parse this module map file.
1429 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1430 Diags->getClient()->BeginSourceFile(MMapLangOpts);
1431 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir(),
1432 BuiltinIncludeDir);
1433 bool Result = Parser.parseModuleMapFile();
1434 Diags->getClient()->EndSourceFile();
1435
1436 return Result;
1437 }
1438