clang API Documentation

ModuleMap.cpp
Go to the documentation of this file.
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 &Map;
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(&LToken, 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 }