clang API Documentation
00001 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the ModuleMap implementation, which describes the layout 00011 // of a module as it relates to headers. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #include "clang/Lex/ModuleMap.h" 00015 #include "clang/Lex/Lexer.h" 00016 #include "clang/Lex/LiteralSupport.h" 00017 #include "clang/Lex/LexDiagnostic.h" 00018 #include "clang/Basic/Diagnostic.h" 00019 #include "clang/Basic/FileManager.h" 00020 #include "clang/Basic/TargetInfo.h" 00021 #include "clang/Basic/TargetOptions.h" 00022 #include "llvm/Support/Allocator.h" 00023 #include "llvm/Support/FileSystem.h" 00024 #include "llvm/Support/Host.h" 00025 #include "llvm/Support/PathV2.h" 00026 #include "llvm/Support/raw_ostream.h" 00027 #include "llvm/ADT/StringRef.h" 00028 #include "llvm/ADT/StringSwitch.h" 00029 using namespace clang; 00030 00031 Module::ExportDecl 00032 ModuleMap::resolveExport(Module *Mod, 00033 const Module::UnresolvedExportDecl &Unresolved, 00034 bool Complain) { 00035 // We may have just a wildcard. 00036 if (Unresolved.Id.empty()) { 00037 assert(Unresolved.Wildcard && "Invalid unresolved export"); 00038 return Module::ExportDecl(0, true); 00039 } 00040 00041 // Find the starting module. 00042 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 00043 if (!Context) { 00044 if (Complain) 00045 Diags->Report(Unresolved.Id[0].second, 00046 diag::err_mmap_missing_module_unqualified) 00047 << Unresolved.Id[0].first << Mod->getFullModuleName(); 00048 00049 return Module::ExportDecl(); 00050 } 00051 00052 // Dig into the module path. 00053 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 00054 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 00055 Context); 00056 if (!Sub) { 00057 if (Complain) 00058 Diags->Report(Unresolved.Id[I].second, 00059 diag::err_mmap_missing_module_qualified) 00060 << Unresolved.Id[I].first << Context->getFullModuleName() 00061 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 00062 00063 return Module::ExportDecl(); 00064 } 00065 00066 Context = Sub; 00067 } 00068 00069 return Module::ExportDecl(Context, Unresolved.Wildcard); 00070 } 00071 00072 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, 00073 const LangOptions &LangOpts, const TargetInfo *Target) 00074 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0) 00075 { 00076 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 00077 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( 00078 new DiagnosticsEngine(DiagIDs)); 00079 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 00080 SourceMgr = new SourceManager(*Diags, FileMgr); 00081 } 00082 00083 ModuleMap::~ModuleMap() { 00084 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 00085 IEnd = Modules.end(); 00086 I != IEnd; ++I) { 00087 delete I->getValue(); 00088 } 00089 00090 delete SourceMgr; 00091 } 00092 00093 void ModuleMap::setTarget(const TargetInfo &Target) { 00094 assert((!this->Target || this->Target == &Target) && 00095 "Improper target override"); 00096 this->Target = &Target; 00097 } 00098 00099 Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 00100 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 00101 = Headers.find(File); 00102 if (Known != Headers.end()) { 00103 // If a header corresponds to an unavailable module, don't report 00104 // that it maps to anything. 00105 if (!Known->second->isAvailable()) 00106 return 0; 00107 00108 return Known->second; 00109 } 00110 00111 const DirectoryEntry *Dir = File->getDir(); 00112 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 00113 StringRef DirName = Dir->getName(); 00114 00115 // Keep walking up the directory hierarchy, looking for a directory with 00116 // an umbrella header. 00117 do { 00118 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 00119 = UmbrellaDirs.find(Dir); 00120 if (KnownDir != UmbrellaDirs.end()) { 00121 Module *Result = KnownDir->second; 00122 00123 // Search up the module stack until we find a module with an umbrella 00124 // directory. 00125 Module *UmbrellaModule = Result; 00126 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 00127 UmbrellaModule = UmbrellaModule->Parent; 00128 00129 if (UmbrellaModule->InferSubmodules) { 00130 // Infer submodules for each of the directories we found between 00131 // the directory of the umbrella header and the directory where 00132 // the actual header is located. 00133 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 00134 00135 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 00136 // Find or create the module that corresponds to this directory name. 00137 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 00138 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 00139 Explicit).first; 00140 00141 // Associate the module and the directory. 00142 UmbrellaDirs[SkippedDirs[I-1]] = Result; 00143 00144 // If inferred submodules export everything they import, add a 00145 // wildcard to the set of exports. 00146 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 00147 Result->Exports.push_back(Module::ExportDecl(0, true)); 00148 } 00149 00150 // Infer a submodule with the same name as this header file. 00151 StringRef Name = llvm::sys::path::stem(File->getName()); 00152 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 00153 Explicit).first; 00154 00155 // If inferred submodules export everything they import, add a 00156 // wildcard to the set of exports. 00157 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 00158 Result->Exports.push_back(Module::ExportDecl(0, true)); 00159 } else { 00160 // Record each of the directories we stepped through as being part of 00161 // the module we found, since the umbrella header covers them all. 00162 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 00163 UmbrellaDirs[SkippedDirs[I]] = Result; 00164 } 00165 00166 Headers[File] = Result; 00167 00168 // If a header corresponds to an unavailable module, don't report 00169 // that it maps to anything. 00170 if (!Result->isAvailable()) 00171 return 0; 00172 00173 return Result; 00174 } 00175 00176 SkippedDirs.push_back(Dir); 00177 00178 // Retrieve our parent path. 00179 DirName = llvm::sys::path::parent_path(DirName); 00180 if (DirName.empty()) 00181 break; 00182 00183 // Resolve the parent path to a directory entry. 00184 Dir = SourceMgr->getFileManager().getDirectory(DirName); 00185 } while (Dir); 00186 00187 return 0; 00188 } 00189 00190 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) { 00191 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 00192 = Headers.find(Header); 00193 if (Known != Headers.end()) 00194 return !Known->second->isAvailable(); 00195 00196 const DirectoryEntry *Dir = Header->getDir(); 00197 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 00198 StringRef DirName = Dir->getName(); 00199 00200 // Keep walking up the directory hierarchy, looking for a directory with 00201 // an umbrella header. 00202 do { 00203 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 00204 = UmbrellaDirs.find(Dir); 00205 if (KnownDir != UmbrellaDirs.end()) { 00206 Module *Found = KnownDir->second; 00207 if (!Found->isAvailable()) 00208 return true; 00209 00210 // Search up the module stack until we find a module with an umbrella 00211 // directory. 00212 Module *UmbrellaModule = Found; 00213 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 00214 UmbrellaModule = UmbrellaModule->Parent; 00215 00216 if (UmbrellaModule->InferSubmodules) { 00217 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 00218 // Find or create the module that corresponds to this directory name. 00219 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 00220 Found = lookupModuleQualified(Name, Found); 00221 if (!Found) 00222 return false; 00223 if (!Found->isAvailable()) 00224 return true; 00225 } 00226 00227 // Infer a submodule with the same name as this header file. 00228 StringRef Name = llvm::sys::path::stem(Header->getName()); 00229 Found = lookupModuleQualified(Name, Found); 00230 if (!Found) 00231 return false; 00232 } 00233 00234 return !Found->isAvailable(); 00235 } 00236 00237 SkippedDirs.push_back(Dir); 00238 00239 // Retrieve our parent path. 00240 DirName = llvm::sys::path::parent_path(DirName); 00241 if (DirName.empty()) 00242 break; 00243 00244 // Resolve the parent path to a directory entry. 00245 Dir = SourceMgr->getFileManager().getDirectory(DirName); 00246 } while (Dir); 00247 00248 return false; 00249 } 00250 00251 Module *ModuleMap::findModule(StringRef Name) { 00252 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 00253 if (Known != Modules.end()) 00254 return Known->getValue(); 00255 00256 return 0; 00257 } 00258 00259 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 00260 for(; Context; Context = Context->Parent) { 00261 if (Module *Sub = lookupModuleQualified(Name, Context)) 00262 return Sub; 00263 } 00264 00265 return findModule(Name); 00266 } 00267 00268 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 00269 if (!Context) 00270 return findModule(Name); 00271 00272 return Context->findSubmodule(Name); 00273 } 00274 00275 std::pair<Module *, bool> 00276 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 00277 bool IsExplicit) { 00278 // Try to find an existing module with this name. 00279 if (Module *Sub = lookupModuleQualified(Name, Parent)) 00280 return std::make_pair(Sub, false); 00281 00282 // Create a new module with this name. 00283 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 00284 IsExplicit); 00285 if (!Parent) 00286 Modules[Name] = Result; 00287 return std::make_pair(Result, true); 00288 } 00289 00290 Module * 00291 ModuleMap::inferFrameworkModule(StringRef ModuleName, 00292 const DirectoryEntry *FrameworkDir, 00293 bool IsSystem, 00294 Module *Parent) { 00295 // Check whether we've already found this module. 00296 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 00297 return Mod; 00298 00299 FileManager &FileMgr = SourceMgr->getFileManager(); 00300 00301 // Look for an umbrella header. 00302 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 00303 llvm::sys::path::append(UmbrellaName, "Headers"); 00304 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 00305 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 00306 00307 // FIXME: If there's no umbrella header, we could probably scan the 00308 // framework to load *everything*. But, it's not clear that this is a good 00309 // idea. 00310 if (!UmbrellaHeader) 00311 return 0; 00312 00313 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 00314 /*IsFramework=*/true, /*IsExplicit=*/false); 00315 if (IsSystem) 00316 Result->IsSystem = IsSystem; 00317 00318 if (!Parent) 00319 Modules[ModuleName] = Result; 00320 00321 // umbrella header "umbrella-header-name" 00322 Result->Umbrella = UmbrellaHeader; 00323 Headers[UmbrellaHeader] = Result; 00324 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 00325 00326 // export * 00327 Result->Exports.push_back(Module::ExportDecl(0, true)); 00328 00329 // module * { export * } 00330 Result->InferSubmodules = true; 00331 Result->InferExportWildcard = true; 00332 00333 // Look for subframeworks. 00334 llvm::error_code EC; 00335 SmallString<128> SubframeworksDirName 00336 = StringRef(FrameworkDir->getName()); 00337 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 00338 SmallString<128> SubframeworksDirNameNative; 00339 llvm::sys::path::native(SubframeworksDirName.str(), 00340 SubframeworksDirNameNative); 00341 for (llvm::sys::fs::directory_iterator 00342 Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 00343 Dir != DirEnd && !EC; Dir.increment(EC)) { 00344 if (!StringRef(Dir->path()).endswith(".framework")) 00345 continue; 00346 00347 if (const DirectoryEntry *SubframeworkDir 00348 = FileMgr.getDirectory(Dir->path())) { 00349 // FIXME: Do we want to warn about subframeworks without umbrella headers? 00350 inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, 00351 IsSystem, Result); 00352 } 00353 } 00354 00355 return Result; 00356 } 00357 00358 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 00359 Headers[UmbrellaHeader] = Mod; 00360 Mod->Umbrella = UmbrellaHeader; 00361 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 00362 } 00363 00364 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 00365 Mod->Umbrella = UmbrellaDir; 00366 UmbrellaDirs[UmbrellaDir] = Mod; 00367 } 00368 00369 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) { 00370 Mod->Headers.push_back(Header); 00371 Headers[Header] = Mod; 00372 } 00373 00374 const FileEntry * 00375 ModuleMap::getContainingModuleMapFile(Module *Module) { 00376 if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 00377 return 0; 00378 00379 return SourceMgr->getFileEntryForID( 00380 SourceMgr->getFileID(Module->DefinitionLoc)); 00381 } 00382 00383 void ModuleMap::dump() { 00384 llvm::errs() << "Modules:"; 00385 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 00386 MEnd = Modules.end(); 00387 M != MEnd; ++M) 00388 M->getValue()->print(llvm::errs(), 2); 00389 00390 llvm::errs() << "Headers:"; 00391 for (llvm::DenseMap<const FileEntry *, Module *>::iterator 00392 H = Headers.begin(), 00393 HEnd = Headers.end(); 00394 H != HEnd; ++H) { 00395 llvm::errs() << " \"" << H->first->getName() << "\" -> " 00396 << H->second->getFullModuleName() << "\n"; 00397 } 00398 } 00399 00400 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 00401 bool HadError = false; 00402 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 00403 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 00404 Complain); 00405 if (Export.getPointer() || Export.getInt()) 00406 Mod->Exports.push_back(Export); 00407 else 00408 HadError = true; 00409 } 00410 Mod->UnresolvedExports.clear(); 00411 return HadError; 00412 } 00413 00414 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 00415 if (Loc.isInvalid()) 00416 return 0; 00417 00418 // Use the expansion location to determine which module we're in. 00419 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 00420 if (!ExpansionLoc.isFileID()) 00421 return 0; 00422 00423 00424 const SourceManager &SrcMgr = Loc.getManager(); 00425 FileID ExpansionFileID = ExpansionLoc.getFileID(); 00426 00427 while (const FileEntry *ExpansionFile 00428 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 00429 // Find the module that owns this header (if any). 00430 if (Module *Mod = findModuleForHeader(ExpansionFile)) 00431 return Mod; 00432 00433 // No module owns this header, so look up the inclusion chain to see if 00434 // any included header has an associated module. 00435 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 00436 if (IncludeLoc.isInvalid()) 00437 return 0; 00438 00439 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 00440 } 00441 00442 return 0; 00443 } 00444 00445 //----------------------------------------------------------------------------// 00446 // Module map file parser 00447 //----------------------------------------------------------------------------// 00448 00449 namespace clang { 00450 /// \brief A token in a module map file. 00451 struct MMToken { 00452 enum TokenKind { 00453 Comma, 00454 EndOfFile, 00455 HeaderKeyword, 00456 Identifier, 00457 ExplicitKeyword, 00458 ExportKeyword, 00459 FrameworkKeyword, 00460 ModuleKeyword, 00461 Period, 00462 UmbrellaKeyword, 00463 RequiresKeyword, 00464 Star, 00465 StringLiteral, 00466 LBrace, 00467 RBrace, 00468 LSquare, 00469 RSquare 00470 } Kind; 00471 00472 unsigned Location; 00473 unsigned StringLength; 00474 const char *StringData; 00475 00476 void clear() { 00477 Kind = EndOfFile; 00478 Location = 0; 00479 StringLength = 0; 00480 StringData = 0; 00481 } 00482 00483 bool is(TokenKind K) const { return Kind == K; } 00484 00485 SourceLocation getLocation() const { 00486 return SourceLocation::getFromRawEncoding(Location); 00487 } 00488 00489 StringRef getString() const { 00490 return StringRef(StringData, StringLength); 00491 } 00492 }; 00493 00494 class ModuleMapParser { 00495 Lexer &L; 00496 SourceManager &SourceMgr; 00497 DiagnosticsEngine &Diags; 00498 ModuleMap ⤅ 00499 00500 /// \brief The directory that this module map resides in. 00501 const DirectoryEntry *Directory; 00502 00503 /// \brief The directory containing Clang-supplied headers. 00504 const DirectoryEntry *BuiltinIncludeDir; 00505 00506 /// \brief Whether an error occurred. 00507 bool HadError; 00508 00509 /// \brief Default target information, used only for string literal 00510 /// parsing. 00511 OwningPtr<TargetInfo> Target; 00512 00513 /// \brief Stores string data for the various string literals referenced 00514 /// during parsing. 00515 llvm::BumpPtrAllocator StringData; 00516 00517 /// \brief The current token. 00518 MMToken Tok; 00519 00520 /// \brief The active module. 00521 Module *ActiveModule; 00522 00523 /// \brief Consume the current token and return its location. 00524 SourceLocation consumeToken(); 00525 00526 /// \brief Skip tokens until we reach the a token with the given kind 00527 /// (or the end of the file). 00528 void skipUntil(MMToken::TokenKind K); 00529 00530 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 00531 ModuleId; 00532 bool parseModuleId(ModuleId &Id); 00533 void parseModuleDecl(); 00534 void parseRequiresDecl(); 00535 void parseHeaderDecl(SourceLocation UmbrellaLoc); 00536 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 00537 void parseExportDecl(); 00538 void parseInferredSubmoduleDecl(bool Explicit); 00539 00540 const DirectoryEntry *getOverriddenHeaderSearchDir(); 00541 00542 public: 00543 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 00544 DiagnosticsEngine &Diags, 00545 ModuleMap &Map, 00546 const DirectoryEntry *Directory, 00547 const DirectoryEntry *BuiltinIncludeDir) 00548 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 00549 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 00550 HadError(false), ActiveModule(0) 00551 { 00552 TargetOptions TargetOpts; 00553 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 00554 Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts)); 00555 00556 Tok.clear(); 00557 consumeToken(); 00558 } 00559 00560 bool parseModuleMapFile(); 00561 }; 00562 } 00563 00564 SourceLocation ModuleMapParser::consumeToken() { 00565 retry: 00566 SourceLocation Result = Tok.getLocation(); 00567 Tok.clear(); 00568 00569 Token LToken; 00570 L.LexFromRawLexer(LToken); 00571 Tok.Location = LToken.getLocation().getRawEncoding(); 00572 switch (LToken.getKind()) { 00573 case tok::raw_identifier: 00574 Tok.StringData = LToken.getRawIdentifierData(); 00575 Tok.StringLength = LToken.getLength(); 00576 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 00577 .Case("header", MMToken::HeaderKeyword) 00578 .Case("explicit", MMToken::ExplicitKeyword) 00579 .Case("export", MMToken::ExportKeyword) 00580 .Case("framework", MMToken::FrameworkKeyword) 00581 .Case("module", MMToken::ModuleKeyword) 00582 .Case("requires", MMToken::RequiresKeyword) 00583 .Case("umbrella", MMToken::UmbrellaKeyword) 00584 .Default(MMToken::Identifier); 00585 break; 00586 00587 case tok::comma: 00588 Tok.Kind = MMToken::Comma; 00589 break; 00590 00591 case tok::eof: 00592 Tok.Kind = MMToken::EndOfFile; 00593 break; 00594 00595 case tok::l_brace: 00596 Tok.Kind = MMToken::LBrace; 00597 break; 00598 00599 case tok::l_square: 00600 Tok.Kind = MMToken::LSquare; 00601 break; 00602 00603 case tok::period: 00604 Tok.Kind = MMToken::Period; 00605 break; 00606 00607 case tok::r_brace: 00608 Tok.Kind = MMToken::RBrace; 00609 break; 00610 00611 case tok::r_square: 00612 Tok.Kind = MMToken::RSquare; 00613 break; 00614 00615 case tok::star: 00616 Tok.Kind = MMToken::Star; 00617 break; 00618 00619 case tok::string_literal: { 00620 if (LToken.hasUDSuffix()) { 00621 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 00622 HadError = true; 00623 goto retry; 00624 } 00625 00626 // Parse the string literal. 00627 LangOptions LangOpts; 00628 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 00629 if (StringLiteral.hadError) 00630 goto retry; 00631 00632 // Copy the string literal into our string data allocator. 00633 unsigned Length = StringLiteral.GetStringLength(); 00634 char *Saved = StringData.Allocate<char>(Length + 1); 00635 memcpy(Saved, StringLiteral.GetString().data(), Length); 00636 Saved[Length] = 0; 00637 00638 // Form the token. 00639 Tok.Kind = MMToken::StringLiteral; 00640 Tok.StringData = Saved; 00641 Tok.StringLength = Length; 00642 break; 00643 } 00644 00645 case tok::comment: 00646 goto retry; 00647 00648 default: 00649 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 00650 HadError = true; 00651 goto retry; 00652 } 00653 00654 return Result; 00655 } 00656 00657 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 00658 unsigned braceDepth = 0; 00659 unsigned squareDepth = 0; 00660 do { 00661 switch (Tok.Kind) { 00662 case MMToken::EndOfFile: 00663 return; 00664 00665 case MMToken::LBrace: 00666 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 00667 return; 00668 00669 ++braceDepth; 00670 break; 00671 00672 case MMToken::LSquare: 00673 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 00674 return; 00675 00676 ++squareDepth; 00677 break; 00678 00679 case MMToken::RBrace: 00680 if (braceDepth > 0) 00681 --braceDepth; 00682 else if (Tok.is(K)) 00683 return; 00684 break; 00685 00686 case MMToken::RSquare: 00687 if (squareDepth > 0) 00688 --squareDepth; 00689 else if (Tok.is(K)) 00690 return; 00691 break; 00692 00693 default: 00694 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 00695 return; 00696 break; 00697 } 00698 00699 consumeToken(); 00700 } while (true); 00701 } 00702 00703 /// \brief Parse a module-id. 00704 /// 00705 /// module-id: 00706 /// identifier 00707 /// identifier '.' module-id 00708 /// 00709 /// \returns true if an error occurred, false otherwise. 00710 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 00711 Id.clear(); 00712 do { 00713 if (Tok.is(MMToken::Identifier)) { 00714 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 00715 consumeToken(); 00716 } else { 00717 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 00718 return true; 00719 } 00720 00721 if (!Tok.is(MMToken::Period)) 00722 break; 00723 00724 consumeToken(); 00725 } while (true); 00726 00727 return false; 00728 } 00729 00730 namespace { 00731 /// \brief Enumerates the known attributes. 00732 enum AttributeKind { 00733 /// \brief An unknown attribute. 00734 AT_unknown, 00735 /// \brief The 'system' attribute. 00736 AT_system 00737 }; 00738 } 00739 00740 /// \brief Parse a module declaration. 00741 /// 00742 /// module-declaration: 00743 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 00744 /// { module-member* } 00745 /// 00746 /// attributes: 00747 /// attribute attributes 00748 /// attribute 00749 /// 00750 /// attribute: 00751 /// [ identifier ] 00752 /// 00753 /// module-member: 00754 /// requires-declaration 00755 /// header-declaration 00756 /// submodule-declaration 00757 /// export-declaration 00758 /// 00759 /// submodule-declaration: 00760 /// module-declaration 00761 /// inferred-submodule-declaration 00762 void ModuleMapParser::parseModuleDecl() { 00763 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 00764 Tok.is(MMToken::FrameworkKeyword)); 00765 // Parse 'explicit' or 'framework' keyword, if present. 00766 SourceLocation ExplicitLoc; 00767 bool Explicit = false; 00768 bool Framework = false; 00769 00770 // Parse 'explicit' keyword, if present. 00771 if (Tok.is(MMToken::ExplicitKeyword)) { 00772 ExplicitLoc = consumeToken(); 00773 Explicit = true; 00774 } 00775 00776 // Parse 'framework' keyword, if present. 00777 if (Tok.is(MMToken::FrameworkKeyword)) { 00778 consumeToken(); 00779 Framework = true; 00780 } 00781 00782 // Parse 'module' keyword. 00783 if (!Tok.is(MMToken::ModuleKeyword)) { 00784 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 00785 consumeToken(); 00786 HadError = true; 00787 return; 00788 } 00789 consumeToken(); // 'module' keyword 00790 00791 // If we have a wildcard for the module name, this is an inferred submodule. 00792 // Parse it. 00793 if (Tok.is(MMToken::Star)) 00794 return parseInferredSubmoduleDecl(Explicit); 00795 00796 // Parse the module name. 00797 ModuleId Id; 00798 if (parseModuleId(Id)) { 00799 HadError = true; 00800 return; 00801 } 00802 00803 if (ActiveModule) { 00804 if (Id.size() > 1) { 00805 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 00806 << SourceRange(Id.front().second, Id.back().second); 00807 00808 HadError = true; 00809 return; 00810 } 00811 } else if (Id.size() == 1 && Explicit) { 00812 // Top-level modules can't be explicit. 00813 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 00814 Explicit = false; 00815 ExplicitLoc = SourceLocation(); 00816 HadError = true; 00817 } 00818 00819 Module *PreviousActiveModule = ActiveModule; 00820 if (Id.size() > 1) { 00821 // This module map defines a submodule. Go find the module of which it 00822 // is a submodule. 00823 ActiveModule = 0; 00824 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 00825 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 00826 ActiveModule = Next; 00827 continue; 00828 } 00829 00830 if (ActiveModule) { 00831 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 00832 << Id[I].first << ActiveModule->getTopLevelModule(); 00833 } else { 00834 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 00835 } 00836 HadError = true; 00837 return; 00838 } 00839 } 00840 00841 StringRef ModuleName = Id.back().first; 00842 SourceLocation ModuleNameLoc = Id.back().second; 00843 00844 // Parse the optional attribute list. 00845 bool IsSystem = false; 00846 while (Tok.is(MMToken::LSquare)) { 00847 // Consume the '['. 00848 SourceLocation LSquareLoc = consumeToken(); 00849 00850 // Check whether we have an attribute name here. 00851 if (!Tok.is(MMToken::Identifier)) { 00852 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 00853 skipUntil(MMToken::RSquare); 00854 if (Tok.is(MMToken::RSquare)) 00855 consumeToken(); 00856 continue; 00857 } 00858 00859 // Decode the attribute name. 00860 AttributeKind Attribute 00861 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 00862 .Case("system", AT_system) 00863 .Default(AT_unknown); 00864 switch (Attribute) { 00865 case AT_unknown: 00866 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 00867 << Tok.getString(); 00868 break; 00869 00870 case AT_system: 00871 IsSystem = true; 00872 break; 00873 } 00874 consumeToken(); 00875 00876 // Consume the ']'. 00877 if (!Tok.is(MMToken::RSquare)) { 00878 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 00879 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 00880 skipUntil(MMToken::RSquare); 00881 } 00882 00883 if (Tok.is(MMToken::RSquare)) 00884 consumeToken(); 00885 } 00886 00887 // Parse the opening brace. 00888 if (!Tok.is(MMToken::LBrace)) { 00889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 00890 << ModuleName; 00891 HadError = true; 00892 return; 00893 } 00894 SourceLocation LBraceLoc = consumeToken(); 00895 00896 // Determine whether this (sub)module has already been defined. 00897 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 00898 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 00899 // Skip the module definition. 00900 skipUntil(MMToken::RBrace); 00901 if (Tok.is(MMToken::RBrace)) 00902 consumeToken(); 00903 else { 00904 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 00905 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 00906 HadError = true; 00907 } 00908 return; 00909 } 00910 00911 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 00912 << ModuleName; 00913 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 00914 00915 // Skip the module definition. 00916 skipUntil(MMToken::RBrace); 00917 if (Tok.is(MMToken::RBrace)) 00918 consumeToken(); 00919 00920 HadError = true; 00921 return; 00922 } 00923 00924 // Start defining this module. 00925 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 00926 Explicit).first; 00927 ActiveModule->DefinitionLoc = ModuleNameLoc; 00928 if (IsSystem) 00929 ActiveModule->IsSystem = true; 00930 00931 bool Done = false; 00932 do { 00933 switch (Tok.Kind) { 00934 case MMToken::EndOfFile: 00935 case MMToken::RBrace: 00936 Done = true; 00937 break; 00938 00939 case MMToken::ExplicitKeyword: 00940 case MMToken::FrameworkKeyword: 00941 case MMToken::ModuleKeyword: 00942 parseModuleDecl(); 00943 break; 00944 00945 case MMToken::ExportKeyword: 00946 parseExportDecl(); 00947 break; 00948 00949 case MMToken::RequiresKeyword: 00950 parseRequiresDecl(); 00951 break; 00952 00953 case MMToken::UmbrellaKeyword: { 00954 SourceLocation UmbrellaLoc = consumeToken(); 00955 if (Tok.is(MMToken::HeaderKeyword)) 00956 parseHeaderDecl(UmbrellaLoc); 00957 else 00958 parseUmbrellaDirDecl(UmbrellaLoc); 00959 break; 00960 } 00961 00962 case MMToken::HeaderKeyword: 00963 parseHeaderDecl(SourceLocation()); 00964 break; 00965 00966 default: 00967 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 00968 consumeToken(); 00969 break; 00970 } 00971 } while (!Done); 00972 00973 if (Tok.is(MMToken::RBrace)) 00974 consumeToken(); 00975 else { 00976 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 00977 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 00978 HadError = true; 00979 } 00980 00981 // We're done parsing this module. Pop back to the previous module. 00982 ActiveModule = PreviousActiveModule; 00983 } 00984 00985 /// \brief Parse a requires declaration. 00986 /// 00987 /// requires-declaration: 00988 /// 'requires' feature-list 00989 /// 00990 /// feature-list: 00991 /// identifier ',' feature-list 00992 /// identifier 00993 void ModuleMapParser::parseRequiresDecl() { 00994 assert(Tok.is(MMToken::RequiresKeyword)); 00995 00996 // Parse 'requires' keyword. 00997 consumeToken(); 00998 00999 // Parse the feature-list. 01000 do { 01001 if (!Tok.is(MMToken::Identifier)) { 01002 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 01003 HadError = true; 01004 return; 01005 } 01006 01007 // Consume the feature name. 01008 std::string Feature = Tok.getString(); 01009 consumeToken(); 01010 01011 // Add this feature. 01012 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 01013 01014 if (!Tok.is(MMToken::Comma)) 01015 break; 01016 01017 // Consume the comma. 01018 consumeToken(); 01019 } while (true); 01020 } 01021 01022 /// \brief Append to \p Paths the set of paths needed to get to the 01023 /// subframework in which the given module lives. 01024 static void appendSubframeworkPaths(Module *Mod, 01025 llvm::SmallVectorImpl<char> &Path) { 01026 // Collect the framework names from the given module to the top-level module. 01027 llvm::SmallVector<StringRef, 2> Paths; 01028 for (; Mod; Mod = Mod->Parent) { 01029 if (Mod->IsFramework) 01030 Paths.push_back(Mod->Name); 01031 } 01032 01033 if (Paths.empty()) 01034 return; 01035 01036 // Add Frameworks/Name.framework for each subframework. 01037 for (unsigned I = Paths.size() - 1; I != 0; --I) { 01038 llvm::sys::path::append(Path, "Frameworks"); 01039 llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 01040 } 01041 } 01042 01043 /// \brief Determine whether the given file name is the name of a builtin 01044 /// header, supplied by Clang to replace, override, or augment existing system 01045 /// headers. 01046 static bool isBuiltinHeader(StringRef FileName) { 01047 return llvm::StringSwitch<bool>(FileName) 01048 .Case("float.h", true) 01049 .Case("iso646.h", true) 01050 .Case("limits.h", true) 01051 .Case("stdalign.h", true) 01052 .Case("stdarg.h", true) 01053 .Case("stdbool.h", true) 01054 .Case("stddef.h", true) 01055 .Case("stdint.h", true) 01056 .Case("tgmath.h", true) 01057 .Case("unwind.h", true) 01058 .Default(false); 01059 } 01060 01061 /// \brief Parse a header declaration. 01062 /// 01063 /// header-declaration: 01064 /// 'umbrella'[opt] 'header' string-literal 01065 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) { 01066 assert(Tok.is(MMToken::HeaderKeyword)); 01067 consumeToken(); 01068 01069 bool Umbrella = UmbrellaLoc.isValid(); 01070 01071 // Parse the header name. 01072 if (!Tok.is(MMToken::StringLiteral)) { 01073 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 01074 << "header"; 01075 HadError = true; 01076 return; 01077 } 01078 std::string FileName = Tok.getString(); 01079 SourceLocation FileNameLoc = consumeToken(); 01080 01081 // Check whether we already have an umbrella. 01082 if (Umbrella && ActiveModule->Umbrella) { 01083 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 01084 << ActiveModule->getFullModuleName(); 01085 HadError = true; 01086 return; 01087 } 01088 01089 // Look for this file. 01090 const FileEntry *File = 0; 01091 const FileEntry *BuiltinFile = 0; 01092 SmallString<128> PathName; 01093 if (llvm::sys::path::is_absolute(FileName)) { 01094 PathName = FileName; 01095 File = SourceMgr.getFileManager().getFile(PathName); 01096 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 01097 PathName = Dir->getName(); 01098 llvm::sys::path::append(PathName, FileName); 01099 File = SourceMgr.getFileManager().getFile(PathName); 01100 } else { 01101 // Search for the header file within the search directory. 01102 PathName = Directory->getName(); 01103 unsigned PathLength = PathName.size(); 01104 01105 if (ActiveModule->isPartOfFramework()) { 01106 appendSubframeworkPaths(ActiveModule, PathName); 01107 01108 // Check whether this file is in the public headers. 01109 llvm::sys::path::append(PathName, "Headers"); 01110 llvm::sys::path::append(PathName, FileName); 01111 File = SourceMgr.getFileManager().getFile(PathName); 01112 01113 if (!File) { 01114 // Check whether this file is in the private headers. 01115 PathName.resize(PathLength); 01116 llvm::sys::path::append(PathName, "PrivateHeaders"); 01117 llvm::sys::path::append(PathName, FileName); 01118 File = SourceMgr.getFileManager().getFile(PathName); 01119 } 01120 } else { 01121 // Lookup for normal headers. 01122 llvm::sys::path::append(PathName, FileName); 01123 File = SourceMgr.getFileManager().getFile(PathName); 01124 01125 // If this is a system module with a top-level header, this header 01126 // may have a counterpart (or replacement) in the set of headers 01127 // supplied by Clang. Find that builtin header. 01128 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir && 01129 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) { 01130 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 01131 llvm::sys::path::append(BuiltinPathName, FileName); 01132 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 01133 01134 // If Clang supplies this header but the underlying system does not, 01135 // just silently swap in our builtin version. Otherwise, we'll end 01136 // up adding both (later). 01137 if (!File && BuiltinFile) { 01138 File = BuiltinFile; 01139 BuiltinFile = 0; 01140 } 01141 } 01142 } 01143 } 01144 01145 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 01146 // Come up with a lazy way to do this. 01147 if (File) { 01148 if (const Module *OwningModule = Map.Headers[File]) { 01149 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 01150 << FileName << OwningModule->getFullModuleName(); 01151 HadError = true; 01152 } else if (Umbrella) { 01153 const DirectoryEntry *UmbrellaDir = File->getDir(); 01154 if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 01155 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 01156 << OwningModule->getFullModuleName(); 01157 HadError = true; 01158 } else { 01159 // Record this umbrella header. 01160 Map.setUmbrellaHeader(ActiveModule, File); 01161 } 01162 } else { 01163 // Record this header. 01164 Map.addHeader(ActiveModule, File); 01165 01166 // If there is a builtin counterpart to this file, add it now. 01167 if (BuiltinFile) 01168 Map.addHeader(ActiveModule, BuiltinFile); 01169 } 01170 } else { 01171 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 01172 << Umbrella << FileName; 01173 HadError = true; 01174 } 01175 } 01176 01177 /// \brief Parse an umbrella directory declaration. 01178 /// 01179 /// umbrella-dir-declaration: 01180 /// umbrella string-literal 01181 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 01182 // Parse the directory name. 01183 if (!Tok.is(MMToken::StringLiteral)) { 01184 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 01185 << "umbrella"; 01186 HadError = true; 01187 return; 01188 } 01189 01190 std::string DirName = Tok.getString(); 01191 SourceLocation DirNameLoc = consumeToken(); 01192 01193 // Check whether we already have an umbrella. 01194 if (ActiveModule->Umbrella) { 01195 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 01196 << ActiveModule->getFullModuleName(); 01197 HadError = true; 01198 return; 01199 } 01200 01201 // Look for this file. 01202 const DirectoryEntry *Dir = 0; 01203 if (llvm::sys::path::is_absolute(DirName)) 01204 Dir = SourceMgr.getFileManager().getDirectory(DirName); 01205 else { 01206 SmallString<128> PathName; 01207 PathName = Directory->getName(); 01208 llvm::sys::path::append(PathName, DirName); 01209 Dir = SourceMgr.getFileManager().getDirectory(PathName); 01210 } 01211 01212 if (!Dir) { 01213 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 01214 << DirName; 01215 HadError = true; 01216 return; 01217 } 01218 01219 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 01220 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 01221 << OwningModule->getFullModuleName(); 01222 HadError = true; 01223 return; 01224 } 01225 01226 // Record this umbrella directory. 01227 Map.setUmbrellaDir(ActiveModule, Dir); 01228 } 01229 01230 /// \brief Parse a module export declaration. 01231 /// 01232 /// export-declaration: 01233 /// 'export' wildcard-module-id 01234 /// 01235 /// wildcard-module-id: 01236 /// identifier 01237 /// '*' 01238 /// identifier '.' wildcard-module-id 01239 void ModuleMapParser::parseExportDecl() { 01240 assert(Tok.is(MMToken::ExportKeyword)); 01241 SourceLocation ExportLoc = consumeToken(); 01242 01243 // Parse the module-id with an optional wildcard at the end. 01244 ModuleId ParsedModuleId; 01245 bool Wildcard = false; 01246 do { 01247 if (Tok.is(MMToken::Identifier)) { 01248 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 01249 Tok.getLocation())); 01250 consumeToken(); 01251 01252 if (Tok.is(MMToken::Period)) { 01253 consumeToken(); 01254 continue; 01255 } 01256 01257 break; 01258 } 01259 01260 if(Tok.is(MMToken::Star)) { 01261 Wildcard = true; 01262 consumeToken(); 01263 break; 01264 } 01265 01266 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 01267 HadError = true; 01268 return; 01269 } while (true); 01270 01271 Module::UnresolvedExportDecl Unresolved = { 01272 ExportLoc, ParsedModuleId, Wildcard 01273 }; 01274 ActiveModule->UnresolvedExports.push_back(Unresolved); 01275 } 01276 01277 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 01278 assert(Tok.is(MMToken::Star)); 01279 SourceLocation StarLoc = consumeToken(); 01280 bool Failed = false; 01281 01282 // Inferred modules must be submodules. 01283 if (!ActiveModule) { 01284 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 01285 Failed = true; 01286 } 01287 01288 // Inferred modules must have umbrella directories. 01289 if (!Failed && !ActiveModule->getUmbrellaDir()) { 01290 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 01291 Failed = true; 01292 } 01293 01294 // Check for redefinition of an inferred module. 01295 if (!Failed && ActiveModule->InferSubmodules) { 01296 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 01297 if (ActiveModule->InferredSubmoduleLoc.isValid()) 01298 Diags.Report(ActiveModule->InferredSubmoduleLoc, 01299 diag::note_mmap_prev_definition); 01300 Failed = true; 01301 } 01302 01303 // If there were any problems with this inferred submodule, skip its body. 01304 if (Failed) { 01305 if (Tok.is(MMToken::LBrace)) { 01306 consumeToken(); 01307 skipUntil(MMToken::RBrace); 01308 if (Tok.is(MMToken::RBrace)) 01309 consumeToken(); 01310 } 01311 HadError = true; 01312 return; 01313 } 01314 01315 // Note that we have an inferred submodule. 01316 ActiveModule->InferSubmodules = true; 01317 ActiveModule->InferredSubmoduleLoc = StarLoc; 01318 ActiveModule->InferExplicitSubmodules = Explicit; 01319 01320 // Parse the opening brace. 01321 if (!Tok.is(MMToken::LBrace)) { 01322 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 01323 HadError = true; 01324 return; 01325 } 01326 SourceLocation LBraceLoc = consumeToken(); 01327 01328 // Parse the body of the inferred submodule. 01329 bool Done = false; 01330 do { 01331 switch (Tok.Kind) { 01332 case MMToken::EndOfFile: 01333 case MMToken::RBrace: 01334 Done = true; 01335 break; 01336 01337 case MMToken::ExportKeyword: { 01338 consumeToken(); 01339 if (Tok.is(MMToken::Star)) 01340 ActiveModule->InferExportWildcard = true; 01341 else 01342 Diags.Report(Tok.getLocation(), 01343 diag::err_mmap_expected_export_wildcard); 01344 consumeToken(); 01345 break; 01346 } 01347 01348 case MMToken::ExplicitKeyword: 01349 case MMToken::ModuleKeyword: 01350 case MMToken::HeaderKeyword: 01351 case MMToken::UmbrellaKeyword: 01352 default: 01353 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 01354 consumeToken(); 01355 break; 01356 } 01357 } while (!Done); 01358 01359 if (Tok.is(MMToken::RBrace)) 01360 consumeToken(); 01361 else { 01362 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 01363 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 01364 HadError = true; 01365 } 01366 } 01367 01368 /// \brief If there is a specific header search directory due the presence 01369 /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 01370 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 01371 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 01372 // If we have an umbrella directory, use that. 01373 if (Mod->hasUmbrellaDir()) 01374 return Mod->getUmbrellaDir(); 01375 01376 // If we have a framework directory, stop looking. 01377 if (Mod->IsFramework) 01378 return 0; 01379 } 01380 01381 return 0; 01382 } 01383 01384 /// \brief Parse a module map file. 01385 /// 01386 /// module-map-file: 01387 /// module-declaration* 01388 bool ModuleMapParser::parseModuleMapFile() { 01389 do { 01390 switch (Tok.Kind) { 01391 case MMToken::EndOfFile: 01392 return HadError; 01393 01394 case MMToken::ExplicitKeyword: 01395 case MMToken::ModuleKeyword: 01396 case MMToken::FrameworkKeyword: 01397 parseModuleDecl(); 01398 break; 01399 01400 case MMToken::Comma: 01401 case MMToken::ExportKeyword: 01402 case MMToken::HeaderKeyword: 01403 case MMToken::Identifier: 01404 case MMToken::LBrace: 01405 case MMToken::LSquare: 01406 case MMToken::Period: 01407 case MMToken::RBrace: 01408 case MMToken::RSquare: 01409 case MMToken::RequiresKeyword: 01410 case MMToken::Star: 01411 case MMToken::StringLiteral: 01412 case MMToken::UmbrellaKeyword: 01413 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 01414 HadError = true; 01415 consumeToken(); 01416 break; 01417 } 01418 } while (true); 01419 } 01420 01421 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 01422 assert(Target != 0 && "Missing target information"); 01423 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 01424 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 01425 if (!Buffer) 01426 return true; 01427 01428 // Parse this module map file. 01429 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 01430 Diags->getClient()->BeginSourceFile(MMapLangOpts); 01431 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir(), 01432 BuiltinIncludeDir); 01433 bool Result = Parser.parseModuleMapFile(); 01434 Diags->getClient()->EndSourceFile(); 01435 01436 return Result; 01437 }