1718292f2SDouglas Gregor //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2718292f2SDouglas Gregor // 3718292f2SDouglas Gregor // The LLVM Compiler Infrastructure 4718292f2SDouglas Gregor // 5718292f2SDouglas Gregor // This file is distributed under the University of Illinois Open Source 6718292f2SDouglas Gregor // License. See LICENSE.TXT for details. 7718292f2SDouglas Gregor // 8718292f2SDouglas Gregor //===----------------------------------------------------------------------===// 9718292f2SDouglas Gregor // 10718292f2SDouglas Gregor // This file defines the ModuleMap implementation, which describes the layout 11718292f2SDouglas Gregor // of a module as it relates to headers. 12718292f2SDouglas Gregor // 13718292f2SDouglas Gregor //===----------------------------------------------------------------------===// 14718292f2SDouglas Gregor #include "clang/Lex/ModuleMap.h" 15718292f2SDouglas Gregor #include "clang/Lex/Lexer.h" 16718292f2SDouglas Gregor #include "clang/Lex/LiteralSupport.h" 17718292f2SDouglas Gregor #include "clang/Lex/LexDiagnostic.h" 18718292f2SDouglas Gregor #include "clang/Basic/Diagnostic.h" 19718292f2SDouglas Gregor #include "clang/Basic/FileManager.h" 20718292f2SDouglas Gregor #include "clang/Basic/TargetInfo.h" 21718292f2SDouglas Gregor #include "clang/Basic/TargetOptions.h" 22718292f2SDouglas Gregor #include "llvm/Support/Allocator.h" 23e89dbc1dSDouglas Gregor #include "llvm/Support/FileSystem.h" 24718292f2SDouglas Gregor #include "llvm/Support/Host.h" 255257fc63SDouglas Gregor #include "llvm/Support/PathV2.h" 26718292f2SDouglas Gregor #include "llvm/Support/raw_ostream.h" 27718292f2SDouglas Gregor #include "llvm/ADT/StringRef.h" 28718292f2SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 29718292f2SDouglas Gregor using namespace clang; 30718292f2SDouglas Gregor 312b82c2a5SDouglas Gregor Module::ExportDecl 322b82c2a5SDouglas Gregor ModuleMap::resolveExport(Module *Mod, 332b82c2a5SDouglas Gregor const Module::UnresolvedExportDecl &Unresolved, 342b82c2a5SDouglas Gregor bool Complain) { 35f5eedd05SDouglas Gregor // We may have just a wildcard. 36f5eedd05SDouglas Gregor if (Unresolved.Id.empty()) { 37f5eedd05SDouglas Gregor assert(Unresolved.Wildcard && "Invalid unresolved export"); 38f5eedd05SDouglas Gregor return Module::ExportDecl(0, true); 39f5eedd05SDouglas Gregor } 40f5eedd05SDouglas Gregor 412b82c2a5SDouglas Gregor // Find the starting module. 422b82c2a5SDouglas Gregor Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 432b82c2a5SDouglas Gregor if (!Context) { 442b82c2a5SDouglas Gregor if (Complain) 452b82c2a5SDouglas Gregor Diags->Report(Unresolved.Id[0].second, 462b82c2a5SDouglas Gregor diag::err_mmap_missing_module_unqualified) 472b82c2a5SDouglas Gregor << Unresolved.Id[0].first << Mod->getFullModuleName(); 482b82c2a5SDouglas Gregor 492b82c2a5SDouglas Gregor return Module::ExportDecl(); 502b82c2a5SDouglas Gregor } 512b82c2a5SDouglas Gregor 522b82c2a5SDouglas Gregor // Dig into the module path. 532b82c2a5SDouglas Gregor for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 542b82c2a5SDouglas Gregor Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 552b82c2a5SDouglas Gregor Context); 562b82c2a5SDouglas Gregor if (!Sub) { 572b82c2a5SDouglas Gregor if (Complain) 582b82c2a5SDouglas Gregor Diags->Report(Unresolved.Id[I].second, 592b82c2a5SDouglas Gregor diag::err_mmap_missing_module_qualified) 602b82c2a5SDouglas Gregor << Unresolved.Id[I].first << Context->getFullModuleName() 612b82c2a5SDouglas Gregor << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 622b82c2a5SDouglas Gregor 632b82c2a5SDouglas Gregor return Module::ExportDecl(); 642b82c2a5SDouglas Gregor } 652b82c2a5SDouglas Gregor 662b82c2a5SDouglas Gregor Context = Sub; 672b82c2a5SDouglas Gregor } 682b82c2a5SDouglas Gregor 692b82c2a5SDouglas Gregor return Module::ExportDecl(Context, Unresolved.Wildcard); 702b82c2a5SDouglas Gregor } 712b82c2a5SDouglas Gregor 72718292f2SDouglas Gregor ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) { 73718292f2SDouglas Gregor llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 74718292f2SDouglas Gregor Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 75718292f2SDouglas Gregor new DiagnosticsEngine(DiagIDs)); 76718292f2SDouglas Gregor Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 77718292f2SDouglas Gregor SourceMgr = new SourceManager(*Diags, FileMgr); 78718292f2SDouglas Gregor } 79718292f2SDouglas Gregor 80718292f2SDouglas Gregor ModuleMap::~ModuleMap() { 815acdf59eSDouglas Gregor for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 825acdf59eSDouglas Gregor IEnd = Modules.end(); 835acdf59eSDouglas Gregor I != IEnd; ++I) { 845acdf59eSDouglas Gregor delete I->getValue(); 855acdf59eSDouglas Gregor } 865acdf59eSDouglas Gregor 87718292f2SDouglas Gregor delete SourceMgr; 88718292f2SDouglas Gregor } 89718292f2SDouglas Gregor 90de3ef502SDouglas Gregor Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 91ab0c8a84SDouglas Gregor llvm::DenseMap<const FileEntry *, Module *>::iterator Known 92ab0c8a84SDouglas Gregor = Headers.find(File); 93ab0c8a84SDouglas Gregor if (Known != Headers.end()) 94ab0c8a84SDouglas Gregor return Known->second; 95ab0c8a84SDouglas Gregor 96b65dbfffSDouglas Gregor const DirectoryEntry *Dir = File->getDir(); 97b65dbfffSDouglas Gregor llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 98b65dbfffSDouglas Gregor StringRef DirName = Dir->getName(); 99a89c5ac4SDouglas Gregor 100a89c5ac4SDouglas Gregor // Keep walking up the directory hierarchy, looking for a directory with 101a89c5ac4SDouglas Gregor // an umbrella header. 102b65dbfffSDouglas Gregor do { 103a89c5ac4SDouglas Gregor llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 104a89c5ac4SDouglas Gregor = UmbrellaDirs.find(Dir); 105a89c5ac4SDouglas Gregor if (KnownDir != UmbrellaDirs.end()) { 106a89c5ac4SDouglas Gregor Module *Result = KnownDir->second; 107930a85ccSDouglas Gregor 108930a85ccSDouglas Gregor // Search up the module stack until we find a module with an umbrella 10973141fa9SDouglas Gregor // directory. 110930a85ccSDouglas Gregor Module *UmbrellaModule = Result; 11173141fa9SDouglas Gregor while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 112930a85ccSDouglas Gregor UmbrellaModule = UmbrellaModule->Parent; 113930a85ccSDouglas Gregor 114930a85ccSDouglas Gregor if (UmbrellaModule->InferSubmodules) { 115a89c5ac4SDouglas Gregor // Infer submodules for each of the directories we found between 116a89c5ac4SDouglas Gregor // the directory of the umbrella header and the directory where 117a89c5ac4SDouglas Gregor // the actual header is located. 1189458f82dSDouglas Gregor bool Explicit = UmbrellaModule->InferExplicitSubmodules; 1199458f82dSDouglas Gregor 1207033127bSDouglas Gregor for (unsigned I = SkippedDirs.size(); I != 0; --I) { 121a89c5ac4SDouglas Gregor // Find or create the module that corresponds to this directory name. 122a89c5ac4SDouglas Gregor StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 123a89c5ac4SDouglas Gregor Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 1249458f82dSDouglas Gregor Explicit).first; 125a89c5ac4SDouglas Gregor 126a89c5ac4SDouglas Gregor // Associate the module and the directory. 127a89c5ac4SDouglas Gregor UmbrellaDirs[SkippedDirs[I-1]] = Result; 128a89c5ac4SDouglas Gregor 129a89c5ac4SDouglas Gregor // If inferred submodules export everything they import, add a 130a89c5ac4SDouglas Gregor // wildcard to the set of exports. 131930a85ccSDouglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 132a89c5ac4SDouglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 133a89c5ac4SDouglas Gregor } 134a89c5ac4SDouglas Gregor 135a89c5ac4SDouglas Gregor // Infer a submodule with the same name as this header file. 136a89c5ac4SDouglas Gregor StringRef Name = llvm::sys::path::stem(File->getName()); 137a89c5ac4SDouglas Gregor Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 1389458f82dSDouglas Gregor Explicit).first; 139a89c5ac4SDouglas Gregor 140a89c5ac4SDouglas Gregor // If inferred submodules export everything they import, add a 141a89c5ac4SDouglas Gregor // wildcard to the set of exports. 142930a85ccSDouglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 143a89c5ac4SDouglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 144a89c5ac4SDouglas Gregor } else { 145a89c5ac4SDouglas Gregor // Record each of the directories we stepped through as being part of 146a89c5ac4SDouglas Gregor // the module we found, since the umbrella header covers them all. 147a89c5ac4SDouglas Gregor for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 148a89c5ac4SDouglas Gregor UmbrellaDirs[SkippedDirs[I]] = Result; 149a89c5ac4SDouglas Gregor } 150a89c5ac4SDouglas Gregor 151a89c5ac4SDouglas Gregor Headers[File] = Result; 152a89c5ac4SDouglas Gregor return Result; 153a89c5ac4SDouglas Gregor } 154a89c5ac4SDouglas Gregor 155a89c5ac4SDouglas Gregor SkippedDirs.push_back(Dir); 156a89c5ac4SDouglas Gregor 157b65dbfffSDouglas Gregor // Retrieve our parent path. 158b65dbfffSDouglas Gregor DirName = llvm::sys::path::parent_path(DirName); 159b65dbfffSDouglas Gregor if (DirName.empty()) 160b65dbfffSDouglas Gregor break; 161b65dbfffSDouglas Gregor 162b65dbfffSDouglas Gregor // Resolve the parent path to a directory entry. 163b65dbfffSDouglas Gregor Dir = SourceMgr->getFileManager().getDirectory(DirName); 164a89c5ac4SDouglas Gregor } while (Dir); 165b65dbfffSDouglas Gregor 166ab0c8a84SDouglas Gregor return 0; 167ab0c8a84SDouglas Gregor } 168ab0c8a84SDouglas Gregor 169de3ef502SDouglas Gregor Module *ModuleMap::findModule(StringRef Name) { 17088bdfb0eSDouglas Gregor llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 17188bdfb0eSDouglas Gregor if (Known != Modules.end()) 17288bdfb0eSDouglas Gregor return Known->getValue(); 17388bdfb0eSDouglas Gregor 17488bdfb0eSDouglas Gregor return 0; 17588bdfb0eSDouglas Gregor } 17688bdfb0eSDouglas Gregor 1772b82c2a5SDouglas Gregor Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 1782b82c2a5SDouglas Gregor for(; Context; Context = Context->Parent) { 1792b82c2a5SDouglas Gregor if (Module *Sub = lookupModuleQualified(Name, Context)) 1802b82c2a5SDouglas Gregor return Sub; 1812b82c2a5SDouglas Gregor } 1822b82c2a5SDouglas Gregor 1832b82c2a5SDouglas Gregor return findModule(Name); 1842b82c2a5SDouglas Gregor } 1852b82c2a5SDouglas Gregor 1862b82c2a5SDouglas Gregor Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 1872b82c2a5SDouglas Gregor if (!Context) 1882b82c2a5SDouglas Gregor return findModule(Name); 1892b82c2a5SDouglas Gregor 1902b82c2a5SDouglas Gregor llvm::StringMap<Module *>::iterator Sub = Context->SubModules.find(Name); 1912b82c2a5SDouglas Gregor if (Sub != Context->SubModules.end()) 1922b82c2a5SDouglas Gregor return Sub->getValue(); 1932b82c2a5SDouglas Gregor 1942b82c2a5SDouglas Gregor return 0; 1952b82c2a5SDouglas Gregor } 1962b82c2a5SDouglas Gregor 197de3ef502SDouglas Gregor std::pair<Module *, bool> 19869021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 19969021974SDouglas Gregor bool IsExplicit) { 20069021974SDouglas Gregor // Try to find an existing module with this name. 20169021974SDouglas Gregor if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name]) 20269021974SDouglas Gregor return std::make_pair(Found, false); 20369021974SDouglas Gregor 20469021974SDouglas Gregor // Create a new module with this name. 20569021974SDouglas Gregor Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 20669021974SDouglas Gregor IsExplicit); 20769021974SDouglas Gregor if (Parent) 20869021974SDouglas Gregor Parent->SubModules[Name] = Result; 20969021974SDouglas Gregor else 21069021974SDouglas Gregor Modules[Name] = Result; 21169021974SDouglas Gregor return std::make_pair(Result, true); 21269021974SDouglas Gregor } 21369021974SDouglas Gregor 214de3ef502SDouglas Gregor Module * 21556c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName, 216e89dbc1dSDouglas Gregor const DirectoryEntry *FrameworkDir, 217e89dbc1dSDouglas Gregor Module *Parent) { 21856c64013SDouglas Gregor // Check whether we've already found this module. 219e89dbc1dSDouglas Gregor if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 220e89dbc1dSDouglas Gregor return Mod; 221e89dbc1dSDouglas Gregor 222e89dbc1dSDouglas Gregor FileManager &FileMgr = SourceMgr->getFileManager(); 22356c64013SDouglas Gregor 22456c64013SDouglas Gregor // Look for an umbrella header. 22556c64013SDouglas Gregor llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 22656c64013SDouglas Gregor llvm::sys::path::append(UmbrellaName, "Headers"); 22756c64013SDouglas Gregor llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 228e89dbc1dSDouglas Gregor const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 22956c64013SDouglas Gregor 23056c64013SDouglas Gregor // FIXME: If there's no umbrella header, we could probably scan the 23156c64013SDouglas Gregor // framework to load *everything*. But, it's not clear that this is a good 23256c64013SDouglas Gregor // idea. 23356c64013SDouglas Gregor if (!UmbrellaHeader) 23456c64013SDouglas Gregor return 0; 23556c64013SDouglas Gregor 236e89dbc1dSDouglas Gregor Module *Result = new Module(ModuleName, SourceLocation(), Parent, 237e89dbc1dSDouglas Gregor /*IsFramework=*/true, /*IsExplicit=*/false); 238e89dbc1dSDouglas Gregor 239e89dbc1dSDouglas Gregor if (Parent) 240e89dbc1dSDouglas Gregor Parent->SubModules[ModuleName] = Result; 241e89dbc1dSDouglas Gregor else 242e89dbc1dSDouglas Gregor Modules[ModuleName] = Result; 243e89dbc1dSDouglas Gregor 244322f633cSDouglas Gregor // umbrella header "umbrella-header-name" 24573141fa9SDouglas Gregor Result->Umbrella = UmbrellaHeader; 24656c64013SDouglas Gregor Headers[UmbrellaHeader] = Result; 247*4dc71835SDouglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 248d8bd7537SDouglas Gregor 249d8bd7537SDouglas Gregor // export * 250d8bd7537SDouglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 251d8bd7537SDouglas Gregor 252a89c5ac4SDouglas Gregor // module * { export * } 253a89c5ac4SDouglas Gregor Result->InferSubmodules = true; 254a89c5ac4SDouglas Gregor Result->InferExportWildcard = true; 255a89c5ac4SDouglas Gregor 256e89dbc1dSDouglas Gregor // Look for subframeworks. 257e89dbc1dSDouglas Gregor llvm::error_code EC; 258ddaa69cbSDouglas Gregor llvm::SmallString<128> SubframeworksDirName 259ddaa69cbSDouglas Gregor = StringRef(FrameworkDir->getName()); 260e89dbc1dSDouglas Gregor llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 261ddaa69cbSDouglas Gregor llvm::SmallString<128> SubframeworksDirNameNative; 262ddaa69cbSDouglas Gregor llvm::sys::path::native(SubframeworksDirName.str(), 263ddaa69cbSDouglas Gregor SubframeworksDirNameNative); 264ddaa69cbSDouglas Gregor for (llvm::sys::fs::directory_iterator 265ddaa69cbSDouglas Gregor Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 266e89dbc1dSDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 267e89dbc1dSDouglas Gregor if (!StringRef(Dir->path()).endswith(".framework")) 268e89dbc1dSDouglas Gregor continue; 269f2161a70SDouglas Gregor 270e89dbc1dSDouglas Gregor if (const DirectoryEntry *SubframeworkDir 271e89dbc1dSDouglas Gregor = FileMgr.getDirectory(Dir->path())) { 272e89dbc1dSDouglas Gregor // FIXME: Do we want to warn about subframeworks without umbrella headers? 273e89dbc1dSDouglas Gregor inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, 274e89dbc1dSDouglas Gregor Result); 275e89dbc1dSDouglas Gregor } 276e89dbc1dSDouglas Gregor } 277e89dbc1dSDouglas Gregor 2789458f82dSDouglas Gregor // Look for private headers. 2799458f82dSDouglas Gregor llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName()); 2809458f82dSDouglas Gregor llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders"); 2817033127bSDouglas Gregor if (const DirectoryEntry *Dir = FileMgr.getDirectory(PrivateHeadersDirName)) { 2827033127bSDouglas Gregor Module *Private = findOrCreateModule("Private", Result, 2839458f82dSDouglas Gregor /*IsFramework=*/false, 2849458f82dSDouglas Gregor /*IsExplicit=*/true).first; 2857033127bSDouglas Gregor setUmbrellaDir(Private, Dir); 2867033127bSDouglas Gregor Private->InferSubmodules = true; 2877033127bSDouglas Gregor Private->InferExplicitSubmodules = true; 2887033127bSDouglas Gregor Private->InferExportWildcard = true; 2899458f82dSDouglas Gregor } 2909458f82dSDouglas Gregor 29156c64013SDouglas Gregor return Result; 29256c64013SDouglas Gregor } 29356c64013SDouglas Gregor 294a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 295a89c5ac4SDouglas Gregor Headers[UmbrellaHeader] = Mod; 29673141fa9SDouglas Gregor Mod->Umbrella = UmbrellaHeader; 2977033127bSDouglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 298a89c5ac4SDouglas Gregor } 299a89c5ac4SDouglas Gregor 300524e33e1SDouglas Gregor void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 301524e33e1SDouglas Gregor Mod->Umbrella = UmbrellaDir; 302524e33e1SDouglas Gregor UmbrellaDirs[UmbrellaDir] = Mod; 303524e33e1SDouglas Gregor } 304524e33e1SDouglas Gregor 305a89c5ac4SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) { 306a89c5ac4SDouglas Gregor Mod->Headers.push_back(Header); 307a89c5ac4SDouglas Gregor Headers[Header] = Mod; 308a89c5ac4SDouglas Gregor } 309a89c5ac4SDouglas Gregor 310514b636aSDouglas Gregor const FileEntry * 311de3ef502SDouglas Gregor ModuleMap::getContainingModuleMapFile(Module *Module) { 312514b636aSDouglas Gregor if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 313514b636aSDouglas Gregor return 0; 314514b636aSDouglas Gregor 315514b636aSDouglas Gregor return SourceMgr->getFileEntryForID( 316514b636aSDouglas Gregor SourceMgr->getFileID(Module->DefinitionLoc)); 317514b636aSDouglas Gregor } 318514b636aSDouglas Gregor 319718292f2SDouglas Gregor void ModuleMap::dump() { 320718292f2SDouglas Gregor llvm::errs() << "Modules:"; 321718292f2SDouglas Gregor for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 322718292f2SDouglas Gregor MEnd = Modules.end(); 323718292f2SDouglas Gregor M != MEnd; ++M) 324d28d1b8dSDouglas Gregor M->getValue()->print(llvm::errs(), 2); 325718292f2SDouglas Gregor 326718292f2SDouglas Gregor llvm::errs() << "Headers:"; 327718292f2SDouglas Gregor for (llvm::DenseMap<const FileEntry *, Module *>::iterator 328718292f2SDouglas Gregor H = Headers.begin(), 329718292f2SDouglas Gregor HEnd = Headers.end(); 330718292f2SDouglas Gregor H != HEnd; ++H) { 331718292f2SDouglas Gregor llvm::errs() << " \"" << H->first->getName() << "\" -> " 332718292f2SDouglas Gregor << H->second->getFullModuleName() << "\n"; 333718292f2SDouglas Gregor } 334718292f2SDouglas Gregor } 335718292f2SDouglas Gregor 3362b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 3372b82c2a5SDouglas Gregor bool HadError = false; 3382b82c2a5SDouglas Gregor for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 3392b82c2a5SDouglas Gregor Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 3402b82c2a5SDouglas Gregor Complain); 341f5eedd05SDouglas Gregor if (Export.getPointer() || Export.getInt()) 3422b82c2a5SDouglas Gregor Mod->Exports.push_back(Export); 3432b82c2a5SDouglas Gregor else 3442b82c2a5SDouglas Gregor HadError = true; 3452b82c2a5SDouglas Gregor } 3462b82c2a5SDouglas Gregor Mod->UnresolvedExports.clear(); 3472b82c2a5SDouglas Gregor return HadError; 3482b82c2a5SDouglas Gregor } 3492b82c2a5SDouglas Gregor 3500093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 3510093b3c7SDouglas Gregor if (Loc.isInvalid()) 3520093b3c7SDouglas Gregor return 0; 3530093b3c7SDouglas Gregor 3540093b3c7SDouglas Gregor // Use the expansion location to determine which module we're in. 3550093b3c7SDouglas Gregor FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 3560093b3c7SDouglas Gregor if (!ExpansionLoc.isFileID()) 3570093b3c7SDouglas Gregor return 0; 3580093b3c7SDouglas Gregor 3590093b3c7SDouglas Gregor 3600093b3c7SDouglas Gregor const SourceManager &SrcMgr = Loc.getManager(); 3610093b3c7SDouglas Gregor FileID ExpansionFileID = ExpansionLoc.getFileID(); 3620093b3c7SDouglas Gregor const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID); 3630093b3c7SDouglas Gregor if (!ExpansionFile) 3640093b3c7SDouglas Gregor return 0; 3650093b3c7SDouglas Gregor 3660093b3c7SDouglas Gregor // Find the module that owns this header. 3670093b3c7SDouglas Gregor return findModuleForHeader(ExpansionFile); 3680093b3c7SDouglas Gregor } 3690093b3c7SDouglas Gregor 370718292f2SDouglas Gregor //----------------------------------------------------------------------------// 371718292f2SDouglas Gregor // Module map file parser 372718292f2SDouglas Gregor //----------------------------------------------------------------------------// 373718292f2SDouglas Gregor 374718292f2SDouglas Gregor namespace clang { 375718292f2SDouglas Gregor /// \brief A token in a module map file. 376718292f2SDouglas Gregor struct MMToken { 377718292f2SDouglas Gregor enum TokenKind { 378718292f2SDouglas Gregor EndOfFile, 379718292f2SDouglas Gregor HeaderKeyword, 380718292f2SDouglas Gregor Identifier, 381718292f2SDouglas Gregor ExplicitKeyword, 3822b82c2a5SDouglas Gregor ExportKeyword, 383755b2055SDouglas Gregor FrameworkKeyword, 384718292f2SDouglas Gregor ModuleKeyword, 3852b82c2a5SDouglas Gregor Period, 386718292f2SDouglas Gregor UmbrellaKeyword, 3872b82c2a5SDouglas Gregor Star, 388718292f2SDouglas Gregor StringLiteral, 389718292f2SDouglas Gregor LBrace, 390718292f2SDouglas Gregor RBrace 391718292f2SDouglas Gregor } Kind; 392718292f2SDouglas Gregor 393718292f2SDouglas Gregor unsigned Location; 394718292f2SDouglas Gregor unsigned StringLength; 395718292f2SDouglas Gregor const char *StringData; 396718292f2SDouglas Gregor 397718292f2SDouglas Gregor void clear() { 398718292f2SDouglas Gregor Kind = EndOfFile; 399718292f2SDouglas Gregor Location = 0; 400718292f2SDouglas Gregor StringLength = 0; 401718292f2SDouglas Gregor StringData = 0; 402718292f2SDouglas Gregor } 403718292f2SDouglas Gregor 404718292f2SDouglas Gregor bool is(TokenKind K) const { return Kind == K; } 405718292f2SDouglas Gregor 406718292f2SDouglas Gregor SourceLocation getLocation() const { 407718292f2SDouglas Gregor return SourceLocation::getFromRawEncoding(Location); 408718292f2SDouglas Gregor } 409718292f2SDouglas Gregor 410718292f2SDouglas Gregor StringRef getString() const { 411718292f2SDouglas Gregor return StringRef(StringData, StringLength); 412718292f2SDouglas Gregor } 413718292f2SDouglas Gregor }; 414718292f2SDouglas Gregor 415718292f2SDouglas Gregor class ModuleMapParser { 416718292f2SDouglas Gregor Lexer &L; 417718292f2SDouglas Gregor SourceManager &SourceMgr; 418718292f2SDouglas Gregor DiagnosticsEngine &Diags; 419718292f2SDouglas Gregor ModuleMap ⤅ 420718292f2SDouglas Gregor 4215257fc63SDouglas Gregor /// \brief The directory that this module map resides in. 4225257fc63SDouglas Gregor const DirectoryEntry *Directory; 4235257fc63SDouglas Gregor 424718292f2SDouglas Gregor /// \brief Whether an error occurred. 425718292f2SDouglas Gregor bool HadError; 426718292f2SDouglas Gregor 427718292f2SDouglas Gregor /// \brief Default target information, used only for string literal 428718292f2SDouglas Gregor /// parsing. 429718292f2SDouglas Gregor TargetInfo *Target; 430718292f2SDouglas Gregor 431718292f2SDouglas Gregor /// \brief Stores string data for the various string literals referenced 432718292f2SDouglas Gregor /// during parsing. 433718292f2SDouglas Gregor llvm::BumpPtrAllocator StringData; 434718292f2SDouglas Gregor 435718292f2SDouglas Gregor /// \brief The current token. 436718292f2SDouglas Gregor MMToken Tok; 437718292f2SDouglas Gregor 438718292f2SDouglas Gregor /// \brief The active module. 439de3ef502SDouglas Gregor Module *ActiveModule; 440718292f2SDouglas Gregor 441718292f2SDouglas Gregor /// \brief Consume the current token and return its location. 442718292f2SDouglas Gregor SourceLocation consumeToken(); 443718292f2SDouglas Gregor 444718292f2SDouglas Gregor /// \brief Skip tokens until we reach the a token with the given kind 445718292f2SDouglas Gregor /// (or the end of the file). 446718292f2SDouglas Gregor void skipUntil(MMToken::TokenKind K); 447718292f2SDouglas Gregor 448e7ab3669SDouglas Gregor typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 449e7ab3669SDouglas Gregor ModuleId; 450e7ab3669SDouglas Gregor bool parseModuleId(ModuleId &Id); 451718292f2SDouglas Gregor void parseModuleDecl(); 452322f633cSDouglas Gregor void parseHeaderDecl(SourceLocation UmbrellaLoc); 453524e33e1SDouglas Gregor void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 4542b82c2a5SDouglas Gregor void parseExportDecl(); 45573441091SDouglas Gregor void parseInferredSubmoduleDecl(bool Explicit); 456718292f2SDouglas Gregor 4577033127bSDouglas Gregor const DirectoryEntry *getOverriddenHeaderSearchDir(); 4587033127bSDouglas Gregor 459718292f2SDouglas Gregor public: 460718292f2SDouglas Gregor explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 461718292f2SDouglas Gregor DiagnosticsEngine &Diags, 4625257fc63SDouglas Gregor ModuleMap &Map, 4635257fc63SDouglas Gregor const DirectoryEntry *Directory) 4645257fc63SDouglas Gregor : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 4655257fc63SDouglas Gregor Directory(Directory), HadError(false), ActiveModule(0) 466718292f2SDouglas Gregor { 467718292f2SDouglas Gregor TargetOptions TargetOpts; 468718292f2SDouglas Gregor TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 469718292f2SDouglas Gregor Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 470718292f2SDouglas Gregor 471718292f2SDouglas Gregor Tok.clear(); 472718292f2SDouglas Gregor consumeToken(); 473718292f2SDouglas Gregor } 474718292f2SDouglas Gregor 475718292f2SDouglas Gregor bool parseModuleMapFile(); 476718292f2SDouglas Gregor }; 477718292f2SDouglas Gregor } 478718292f2SDouglas Gregor 479718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() { 480718292f2SDouglas Gregor retry: 481718292f2SDouglas Gregor SourceLocation Result = Tok.getLocation(); 482718292f2SDouglas Gregor Tok.clear(); 483718292f2SDouglas Gregor 484718292f2SDouglas Gregor Token LToken; 485718292f2SDouglas Gregor L.LexFromRawLexer(LToken); 486718292f2SDouglas Gregor Tok.Location = LToken.getLocation().getRawEncoding(); 487718292f2SDouglas Gregor switch (LToken.getKind()) { 488718292f2SDouglas Gregor case tok::raw_identifier: 489718292f2SDouglas Gregor Tok.StringData = LToken.getRawIdentifierData(); 490718292f2SDouglas Gregor Tok.StringLength = LToken.getLength(); 491718292f2SDouglas Gregor Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 492718292f2SDouglas Gregor .Case("header", MMToken::HeaderKeyword) 493718292f2SDouglas Gregor .Case("explicit", MMToken::ExplicitKeyword) 4942b82c2a5SDouglas Gregor .Case("export", MMToken::ExportKeyword) 495755b2055SDouglas Gregor .Case("framework", MMToken::FrameworkKeyword) 496718292f2SDouglas Gregor .Case("module", MMToken::ModuleKeyword) 497718292f2SDouglas Gregor .Case("umbrella", MMToken::UmbrellaKeyword) 498718292f2SDouglas Gregor .Default(MMToken::Identifier); 499718292f2SDouglas Gregor break; 500718292f2SDouglas Gregor 501718292f2SDouglas Gregor case tok::eof: 502718292f2SDouglas Gregor Tok.Kind = MMToken::EndOfFile; 503718292f2SDouglas Gregor break; 504718292f2SDouglas Gregor 505718292f2SDouglas Gregor case tok::l_brace: 506718292f2SDouglas Gregor Tok.Kind = MMToken::LBrace; 507718292f2SDouglas Gregor break; 508718292f2SDouglas Gregor 5092b82c2a5SDouglas Gregor case tok::period: 5102b82c2a5SDouglas Gregor Tok.Kind = MMToken::Period; 5112b82c2a5SDouglas Gregor break; 5122b82c2a5SDouglas Gregor 513718292f2SDouglas Gregor case tok::r_brace: 514718292f2SDouglas Gregor Tok.Kind = MMToken::RBrace; 515718292f2SDouglas Gregor break; 516718292f2SDouglas Gregor 5172b82c2a5SDouglas Gregor case tok::star: 5182b82c2a5SDouglas Gregor Tok.Kind = MMToken::Star; 5192b82c2a5SDouglas Gregor break; 5202b82c2a5SDouglas Gregor 521718292f2SDouglas Gregor case tok::string_literal: { 522718292f2SDouglas Gregor // Parse the string literal. 523718292f2SDouglas Gregor LangOptions LangOpts; 524718292f2SDouglas Gregor StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 525718292f2SDouglas Gregor if (StringLiteral.hadError) 526718292f2SDouglas Gregor goto retry; 527718292f2SDouglas Gregor 528718292f2SDouglas Gregor // Copy the string literal into our string data allocator. 529718292f2SDouglas Gregor unsigned Length = StringLiteral.GetStringLength(); 530718292f2SDouglas Gregor char *Saved = StringData.Allocate<char>(Length + 1); 531718292f2SDouglas Gregor memcpy(Saved, StringLiteral.GetString().data(), Length); 532718292f2SDouglas Gregor Saved[Length] = 0; 533718292f2SDouglas Gregor 534718292f2SDouglas Gregor // Form the token. 535718292f2SDouglas Gregor Tok.Kind = MMToken::StringLiteral; 536718292f2SDouglas Gregor Tok.StringData = Saved; 537718292f2SDouglas Gregor Tok.StringLength = Length; 538718292f2SDouglas Gregor break; 539718292f2SDouglas Gregor } 540718292f2SDouglas Gregor 541718292f2SDouglas Gregor case tok::comment: 542718292f2SDouglas Gregor goto retry; 543718292f2SDouglas Gregor 544718292f2SDouglas Gregor default: 545718292f2SDouglas Gregor Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 546718292f2SDouglas Gregor HadError = true; 547718292f2SDouglas Gregor goto retry; 548718292f2SDouglas Gregor } 549718292f2SDouglas Gregor 550718292f2SDouglas Gregor return Result; 551718292f2SDouglas Gregor } 552718292f2SDouglas Gregor 553718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 554718292f2SDouglas Gregor unsigned braceDepth = 0; 555718292f2SDouglas Gregor do { 556718292f2SDouglas Gregor switch (Tok.Kind) { 557718292f2SDouglas Gregor case MMToken::EndOfFile: 558718292f2SDouglas Gregor return; 559718292f2SDouglas Gregor 560718292f2SDouglas Gregor case MMToken::LBrace: 561718292f2SDouglas Gregor if (Tok.is(K) && braceDepth == 0) 562718292f2SDouglas Gregor return; 563718292f2SDouglas Gregor 564718292f2SDouglas Gregor ++braceDepth; 565718292f2SDouglas Gregor break; 566718292f2SDouglas Gregor 567718292f2SDouglas Gregor case MMToken::RBrace: 568718292f2SDouglas Gregor if (braceDepth > 0) 569718292f2SDouglas Gregor --braceDepth; 570718292f2SDouglas Gregor else if (Tok.is(K)) 571718292f2SDouglas Gregor return; 572718292f2SDouglas Gregor break; 573718292f2SDouglas Gregor 574718292f2SDouglas Gregor default: 575718292f2SDouglas Gregor if (braceDepth == 0 && Tok.is(K)) 576718292f2SDouglas Gregor return; 577718292f2SDouglas Gregor break; 578718292f2SDouglas Gregor } 579718292f2SDouglas Gregor 580718292f2SDouglas Gregor consumeToken(); 581718292f2SDouglas Gregor } while (true); 582718292f2SDouglas Gregor } 583718292f2SDouglas Gregor 584e7ab3669SDouglas Gregor /// \brief Parse a module-id. 585e7ab3669SDouglas Gregor /// 586e7ab3669SDouglas Gregor /// module-id: 587e7ab3669SDouglas Gregor /// identifier 588e7ab3669SDouglas Gregor /// identifier '.' module-id 589e7ab3669SDouglas Gregor /// 590e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise. 591e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) { 592e7ab3669SDouglas Gregor Id.clear(); 593e7ab3669SDouglas Gregor do { 594e7ab3669SDouglas Gregor if (Tok.is(MMToken::Identifier)) { 595e7ab3669SDouglas Gregor Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 596e7ab3669SDouglas Gregor consumeToken(); 597e7ab3669SDouglas Gregor } else { 598e7ab3669SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 599e7ab3669SDouglas Gregor return true; 600e7ab3669SDouglas Gregor } 601e7ab3669SDouglas Gregor 602e7ab3669SDouglas Gregor if (!Tok.is(MMToken::Period)) 603e7ab3669SDouglas Gregor break; 604e7ab3669SDouglas Gregor 605e7ab3669SDouglas Gregor consumeToken(); 606e7ab3669SDouglas Gregor } while (true); 607e7ab3669SDouglas Gregor 608e7ab3669SDouglas Gregor return false; 609e7ab3669SDouglas Gregor } 610e7ab3669SDouglas Gregor 611718292f2SDouglas Gregor /// \brief Parse a module declaration. 612718292f2SDouglas Gregor /// 613718292f2SDouglas Gregor /// module-declaration: 614e7ab3669SDouglas Gregor /// 'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* } 615718292f2SDouglas Gregor /// 616718292f2SDouglas Gregor /// module-member: 617718292f2SDouglas Gregor /// header-declaration 618e7ab3669SDouglas Gregor /// submodule-declaration 6192b82c2a5SDouglas Gregor /// export-declaration 62073441091SDouglas Gregor /// 62173441091SDouglas Gregor /// submodule-declaration: 62273441091SDouglas Gregor /// module-declaration 62373441091SDouglas Gregor /// inferred-submodule-declaration 624718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() { 625755b2055SDouglas Gregor assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 626755b2055SDouglas Gregor Tok.is(MMToken::FrameworkKeyword)); 627f2161a70SDouglas Gregor // Parse 'explicit' or 'framework' keyword, if present. 628e7ab3669SDouglas Gregor SourceLocation ExplicitLoc; 629718292f2SDouglas Gregor bool Explicit = false; 630f2161a70SDouglas Gregor bool Framework = false; 631755b2055SDouglas Gregor 632f2161a70SDouglas Gregor // Parse 'explicit' keyword, if present. 633f2161a70SDouglas Gregor if (Tok.is(MMToken::ExplicitKeyword)) { 634e7ab3669SDouglas Gregor ExplicitLoc = consumeToken(); 635f2161a70SDouglas Gregor Explicit = true; 636f2161a70SDouglas Gregor } 637f2161a70SDouglas Gregor 638f2161a70SDouglas Gregor // Parse 'framework' keyword, if present. 639755b2055SDouglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 640755b2055SDouglas Gregor consumeToken(); 641755b2055SDouglas Gregor Framework = true; 642755b2055SDouglas Gregor } 643718292f2SDouglas Gregor 644718292f2SDouglas Gregor // Parse 'module' keyword. 645718292f2SDouglas Gregor if (!Tok.is(MMToken::ModuleKeyword)) { 646d6343c99SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 647718292f2SDouglas Gregor consumeToken(); 648718292f2SDouglas Gregor HadError = true; 649718292f2SDouglas Gregor return; 650718292f2SDouglas Gregor } 651718292f2SDouglas Gregor consumeToken(); // 'module' keyword 652718292f2SDouglas Gregor 65373441091SDouglas Gregor // If we have a wildcard for the module name, this is an inferred submodule. 65473441091SDouglas Gregor // Parse it. 65573441091SDouglas Gregor if (Tok.is(MMToken::Star)) 65673441091SDouglas Gregor return parseInferredSubmoduleDecl(Explicit); 65773441091SDouglas Gregor 658718292f2SDouglas Gregor // Parse the module name. 659e7ab3669SDouglas Gregor ModuleId Id; 660e7ab3669SDouglas Gregor if (parseModuleId(Id)) { 661718292f2SDouglas Gregor HadError = true; 662718292f2SDouglas Gregor return; 663718292f2SDouglas Gregor } 664e7ab3669SDouglas Gregor 665e7ab3669SDouglas Gregor if (ActiveModule) { 666e7ab3669SDouglas Gregor if (Id.size() > 1) { 667e7ab3669SDouglas Gregor Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 668e7ab3669SDouglas Gregor << SourceRange(Id.front().second, Id.back().second); 669e7ab3669SDouglas Gregor 670e7ab3669SDouglas Gregor HadError = true; 671e7ab3669SDouglas Gregor return; 672e7ab3669SDouglas Gregor } 673e7ab3669SDouglas Gregor } else if (Id.size() == 1 && Explicit) { 674e7ab3669SDouglas Gregor // Top-level modules can't be explicit. 675e7ab3669SDouglas Gregor Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 676e7ab3669SDouglas Gregor Explicit = false; 677e7ab3669SDouglas Gregor ExplicitLoc = SourceLocation(); 678e7ab3669SDouglas Gregor HadError = true; 679e7ab3669SDouglas Gregor } 680e7ab3669SDouglas Gregor 681e7ab3669SDouglas Gregor Module *PreviousActiveModule = ActiveModule; 682e7ab3669SDouglas Gregor if (Id.size() > 1) { 683e7ab3669SDouglas Gregor // This module map defines a submodule. Go find the module of which it 684e7ab3669SDouglas Gregor // is a submodule. 685e7ab3669SDouglas Gregor ActiveModule = 0; 686e7ab3669SDouglas Gregor for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 687e7ab3669SDouglas Gregor if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 688e7ab3669SDouglas Gregor ActiveModule = Next; 689e7ab3669SDouglas Gregor continue; 690e7ab3669SDouglas Gregor } 691e7ab3669SDouglas Gregor 692e7ab3669SDouglas Gregor if (ActiveModule) { 693e7ab3669SDouglas Gregor Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 694e7ab3669SDouglas Gregor << Id[I].first << ActiveModule->getTopLevelModule(); 695e7ab3669SDouglas Gregor } else { 696e7ab3669SDouglas Gregor Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 697e7ab3669SDouglas Gregor } 698e7ab3669SDouglas Gregor HadError = true; 699e7ab3669SDouglas Gregor return; 700e7ab3669SDouglas Gregor } 701e7ab3669SDouglas Gregor } 702e7ab3669SDouglas Gregor 703e7ab3669SDouglas Gregor StringRef ModuleName = Id.back().first; 704e7ab3669SDouglas Gregor SourceLocation ModuleNameLoc = Id.back().second; 705718292f2SDouglas Gregor 706718292f2SDouglas Gregor // Parse the opening brace. 707718292f2SDouglas Gregor if (!Tok.is(MMToken::LBrace)) { 708718292f2SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 709718292f2SDouglas Gregor << ModuleName; 710718292f2SDouglas Gregor HadError = true; 711718292f2SDouglas Gregor return; 712718292f2SDouglas Gregor } 713718292f2SDouglas Gregor SourceLocation LBraceLoc = consumeToken(); 714718292f2SDouglas Gregor 715718292f2SDouglas Gregor // Determine whether this (sub)module has already been defined. 716718292f2SDouglas Gregor llvm::StringMap<Module *> &ModuleSpace 717718292f2SDouglas Gregor = ActiveModule? ActiveModule->SubModules : Map.Modules; 718718292f2SDouglas Gregor llvm::StringMap<Module *>::iterator ExistingModule 719718292f2SDouglas Gregor = ModuleSpace.find(ModuleName); 720718292f2SDouglas Gregor if (ExistingModule != ModuleSpace.end()) { 721718292f2SDouglas Gregor Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 722718292f2SDouglas Gregor << ModuleName; 723718292f2SDouglas Gregor Diags.Report(ExistingModule->getValue()->DefinitionLoc, 724718292f2SDouglas Gregor diag::note_mmap_prev_definition); 725718292f2SDouglas Gregor 726718292f2SDouglas Gregor // Skip the module definition. 727718292f2SDouglas Gregor skipUntil(MMToken::RBrace); 728718292f2SDouglas Gregor if (Tok.is(MMToken::RBrace)) 729718292f2SDouglas Gregor consumeToken(); 730718292f2SDouglas Gregor 731718292f2SDouglas Gregor HadError = true; 732718292f2SDouglas Gregor return; 733718292f2SDouglas Gregor } 734718292f2SDouglas Gregor 735718292f2SDouglas Gregor // Start defining this module. 736755b2055SDouglas Gregor ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 737755b2055SDouglas Gregor Explicit); 738718292f2SDouglas Gregor ModuleSpace[ModuleName] = ActiveModule; 739718292f2SDouglas Gregor 740718292f2SDouglas Gregor bool Done = false; 741718292f2SDouglas Gregor do { 742718292f2SDouglas Gregor switch (Tok.Kind) { 743718292f2SDouglas Gregor case MMToken::EndOfFile: 744718292f2SDouglas Gregor case MMToken::RBrace: 745718292f2SDouglas Gregor Done = true; 746718292f2SDouglas Gregor break; 747718292f2SDouglas Gregor 748718292f2SDouglas Gregor case MMToken::ExplicitKeyword: 749f2161a70SDouglas Gregor case MMToken::FrameworkKeyword: 750718292f2SDouglas Gregor case MMToken::ModuleKeyword: 751718292f2SDouglas Gregor parseModuleDecl(); 752718292f2SDouglas Gregor break; 753718292f2SDouglas Gregor 7542b82c2a5SDouglas Gregor case MMToken::ExportKeyword: 7552b82c2a5SDouglas Gregor parseExportDecl(); 7562b82c2a5SDouglas Gregor break; 7572b82c2a5SDouglas Gregor 758524e33e1SDouglas Gregor case MMToken::UmbrellaKeyword: { 759524e33e1SDouglas Gregor SourceLocation UmbrellaLoc = consumeToken(); 760524e33e1SDouglas Gregor if (Tok.is(MMToken::HeaderKeyword)) 761524e33e1SDouglas Gregor parseHeaderDecl(UmbrellaLoc); 762524e33e1SDouglas Gregor else 763524e33e1SDouglas Gregor parseUmbrellaDirDecl(UmbrellaLoc); 764718292f2SDouglas Gregor break; 765524e33e1SDouglas Gregor } 766718292f2SDouglas Gregor 767322f633cSDouglas Gregor case MMToken::HeaderKeyword: 768322f633cSDouglas Gregor parseHeaderDecl(SourceLocation()); 769718292f2SDouglas Gregor break; 770718292f2SDouglas Gregor 771718292f2SDouglas Gregor default: 772718292f2SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 773718292f2SDouglas Gregor consumeToken(); 774718292f2SDouglas Gregor break; 775718292f2SDouglas Gregor } 776718292f2SDouglas Gregor } while (!Done); 777718292f2SDouglas Gregor 778718292f2SDouglas Gregor if (Tok.is(MMToken::RBrace)) 779718292f2SDouglas Gregor consumeToken(); 780718292f2SDouglas Gregor else { 781718292f2SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 782718292f2SDouglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 783718292f2SDouglas Gregor HadError = true; 784718292f2SDouglas Gregor } 785718292f2SDouglas Gregor 786e7ab3669SDouglas Gregor // We're done parsing this module. Pop back to the previous module. 787e7ab3669SDouglas Gregor ActiveModule = PreviousActiveModule; 788718292f2SDouglas Gregor } 789718292f2SDouglas Gregor 790f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the 791f2161a70SDouglas Gregor /// subframework in which the given module lives. 792f2161a70SDouglas Gregor void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) { 793f2161a70SDouglas Gregor // Collect the framework names from the given module to the top-level module. 794f2161a70SDouglas Gregor llvm::SmallVector<StringRef, 2> Paths; 795f2161a70SDouglas Gregor for (; Mod; Mod = Mod->Parent) { 796f2161a70SDouglas Gregor if (Mod->IsFramework) 797f2161a70SDouglas Gregor Paths.push_back(Mod->Name); 798f2161a70SDouglas Gregor } 799f2161a70SDouglas Gregor 800f2161a70SDouglas Gregor if (Paths.empty()) 801f2161a70SDouglas Gregor return; 802f2161a70SDouglas Gregor 803f2161a70SDouglas Gregor // Add Frameworks/Name.framework for each subframework. 804f2161a70SDouglas Gregor for (unsigned I = Paths.size() - 1; I != 0; --I) { 805f2161a70SDouglas Gregor llvm::sys::path::append(Path, "Frameworks"); 806f2161a70SDouglas Gregor llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 807f2161a70SDouglas Gregor } 808f2161a70SDouglas Gregor } 809f2161a70SDouglas Gregor 810718292f2SDouglas Gregor /// \brief Parse a header declaration. 811718292f2SDouglas Gregor /// 812718292f2SDouglas Gregor /// header-declaration: 813322f633cSDouglas Gregor /// 'umbrella'[opt] 'header' string-literal 814322f633cSDouglas Gregor void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) { 815718292f2SDouglas Gregor assert(Tok.is(MMToken::HeaderKeyword)); 8161871ed3dSBenjamin Kramer consumeToken(); 817718292f2SDouglas Gregor 818322f633cSDouglas Gregor bool Umbrella = UmbrellaLoc.isValid(); 819322f633cSDouglas Gregor 820718292f2SDouglas Gregor // Parse the header name. 821718292f2SDouglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 822718292f2SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 823718292f2SDouglas Gregor << "header"; 824718292f2SDouglas Gregor HadError = true; 825718292f2SDouglas Gregor return; 826718292f2SDouglas Gregor } 827e7ab3669SDouglas Gregor std::string FileName = Tok.getString(); 828718292f2SDouglas Gregor SourceLocation FileNameLoc = consumeToken(); 829718292f2SDouglas Gregor 830524e33e1SDouglas Gregor // Check whether we already have an umbrella. 831524e33e1SDouglas Gregor if (Umbrella && ActiveModule->Umbrella) { 832524e33e1SDouglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 833524e33e1SDouglas Gregor << ActiveModule->getFullModuleName(); 834322f633cSDouglas Gregor HadError = true; 835322f633cSDouglas Gregor return; 836322f633cSDouglas Gregor } 837322f633cSDouglas Gregor 8385257fc63SDouglas Gregor // Look for this file. 839e7ab3669SDouglas Gregor const FileEntry *File = 0; 8405257fc63SDouglas Gregor llvm::SmallString<128> PathName; 841e7ab3669SDouglas Gregor if (llvm::sys::path::is_absolute(FileName)) { 842e7ab3669SDouglas Gregor PathName = FileName; 843e7ab3669SDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 8447033127bSDouglas Gregor } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 8457033127bSDouglas Gregor PathName = Dir->getName(); 8467033127bSDouglas Gregor llvm::sys::path::append(PathName, FileName); 8477033127bSDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 848e7ab3669SDouglas Gregor } else { 849e7ab3669SDouglas Gregor // Search for the header file within the search directory. 8507033127bSDouglas Gregor PathName = Directory->getName(); 851e7ab3669SDouglas Gregor unsigned PathLength = PathName.size(); 852755b2055SDouglas Gregor 853f2161a70SDouglas Gregor if (ActiveModule->isPartOfFramework()) { 854f2161a70SDouglas Gregor appendSubframeworkPaths(ActiveModule, PathName); 855755b2055SDouglas Gregor 856e7ab3669SDouglas Gregor // Check whether this file is in the public headers. 857e7ab3669SDouglas Gregor llvm::sys::path::append(PathName, "Headers"); 8585257fc63SDouglas Gregor llvm::sys::path::append(PathName, FileName); 859e7ab3669SDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 860e7ab3669SDouglas Gregor 861e7ab3669SDouglas Gregor if (!File) { 862e7ab3669SDouglas Gregor // Check whether this file is in the private headers. 863e7ab3669SDouglas Gregor PathName.resize(PathLength); 864e7ab3669SDouglas Gregor llvm::sys::path::append(PathName, "PrivateHeaders"); 865e7ab3669SDouglas Gregor llvm::sys::path::append(PathName, FileName); 866e7ab3669SDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 867e7ab3669SDouglas Gregor } 868e7ab3669SDouglas Gregor } else { 869e7ab3669SDouglas Gregor // Lookup for normal headers. 870e7ab3669SDouglas Gregor llvm::sys::path::append(PathName, FileName); 871e7ab3669SDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 872e7ab3669SDouglas Gregor } 873e7ab3669SDouglas Gregor } 8745257fc63SDouglas Gregor 8755257fc63SDouglas Gregor // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 8765257fc63SDouglas Gregor // Come up with a lazy way to do this. 877e7ab3669SDouglas Gregor if (File) { 8785257fc63SDouglas Gregor if (const Module *OwningModule = Map.Headers[File]) { 8795257fc63SDouglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 8805257fc63SDouglas Gregor << FileName << OwningModule->getFullModuleName(); 8815257fc63SDouglas Gregor HadError = true; 882322f633cSDouglas Gregor } else if (Umbrella) { 883322f633cSDouglas Gregor const DirectoryEntry *UmbrellaDir = File->getDir(); 884322f633cSDouglas Gregor if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 885322f633cSDouglas Gregor Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 886322f633cSDouglas Gregor << OwningModule->getFullModuleName(); 887322f633cSDouglas Gregor HadError = true; 8885257fc63SDouglas Gregor } else { 889322f633cSDouglas Gregor // Record this umbrella header. 890322f633cSDouglas Gregor Map.setUmbrellaHeader(ActiveModule, File); 891322f633cSDouglas Gregor } 892322f633cSDouglas Gregor } else { 893322f633cSDouglas Gregor // Record this header. 894a89c5ac4SDouglas Gregor Map.addHeader(ActiveModule, File); 8955257fc63SDouglas Gregor } 8965257fc63SDouglas Gregor } else { 8975257fc63SDouglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 898524e33e1SDouglas Gregor << Umbrella << FileName; 8995257fc63SDouglas Gregor HadError = true; 9005257fc63SDouglas Gregor } 901718292f2SDouglas Gregor } 902718292f2SDouglas Gregor 903524e33e1SDouglas Gregor /// \brief Parse an umbrella directory declaration. 904524e33e1SDouglas Gregor /// 905524e33e1SDouglas Gregor /// umbrella-dir-declaration: 906524e33e1SDouglas Gregor /// umbrella string-literal 907524e33e1SDouglas Gregor void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 908524e33e1SDouglas Gregor // Parse the directory name. 909524e33e1SDouglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 910524e33e1SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 911524e33e1SDouglas Gregor << "umbrella"; 912524e33e1SDouglas Gregor HadError = true; 913524e33e1SDouglas Gregor return; 914524e33e1SDouglas Gregor } 915524e33e1SDouglas Gregor 916524e33e1SDouglas Gregor std::string DirName = Tok.getString(); 917524e33e1SDouglas Gregor SourceLocation DirNameLoc = consumeToken(); 918524e33e1SDouglas Gregor 919524e33e1SDouglas Gregor // Check whether we already have an umbrella. 920524e33e1SDouglas Gregor if (ActiveModule->Umbrella) { 921524e33e1SDouglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 922524e33e1SDouglas Gregor << ActiveModule->getFullModuleName(); 923524e33e1SDouglas Gregor HadError = true; 924524e33e1SDouglas Gregor return; 925524e33e1SDouglas Gregor } 926524e33e1SDouglas Gregor 927524e33e1SDouglas Gregor // Look for this file. 928524e33e1SDouglas Gregor const DirectoryEntry *Dir = 0; 929524e33e1SDouglas Gregor if (llvm::sys::path::is_absolute(DirName)) 930524e33e1SDouglas Gregor Dir = SourceMgr.getFileManager().getDirectory(DirName); 931524e33e1SDouglas Gregor else { 932524e33e1SDouglas Gregor llvm::SmallString<128> PathName; 933524e33e1SDouglas Gregor PathName = Directory->getName(); 934524e33e1SDouglas Gregor llvm::sys::path::append(PathName, DirName); 935524e33e1SDouglas Gregor Dir = SourceMgr.getFileManager().getDirectory(PathName); 936524e33e1SDouglas Gregor } 937524e33e1SDouglas Gregor 938524e33e1SDouglas Gregor if (!Dir) { 939524e33e1SDouglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 940524e33e1SDouglas Gregor << DirName; 941524e33e1SDouglas Gregor HadError = true; 942524e33e1SDouglas Gregor return; 943524e33e1SDouglas Gregor } 944524e33e1SDouglas Gregor 945524e33e1SDouglas Gregor if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 946524e33e1SDouglas Gregor Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 947524e33e1SDouglas Gregor << OwningModule->getFullModuleName(); 948524e33e1SDouglas Gregor HadError = true; 949524e33e1SDouglas Gregor return; 950524e33e1SDouglas Gregor } 951524e33e1SDouglas Gregor 952524e33e1SDouglas Gregor // Record this umbrella directory. 953524e33e1SDouglas Gregor Map.setUmbrellaDir(ActiveModule, Dir); 954524e33e1SDouglas Gregor } 955524e33e1SDouglas Gregor 9562b82c2a5SDouglas Gregor /// \brief Parse a module export declaration. 9572b82c2a5SDouglas Gregor /// 9582b82c2a5SDouglas Gregor /// export-declaration: 9592b82c2a5SDouglas Gregor /// 'export' wildcard-module-id 9602b82c2a5SDouglas Gregor /// 9612b82c2a5SDouglas Gregor /// wildcard-module-id: 9622b82c2a5SDouglas Gregor /// identifier 9632b82c2a5SDouglas Gregor /// '*' 9642b82c2a5SDouglas Gregor /// identifier '.' wildcard-module-id 9652b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() { 9662b82c2a5SDouglas Gregor assert(Tok.is(MMToken::ExportKeyword)); 9672b82c2a5SDouglas Gregor SourceLocation ExportLoc = consumeToken(); 9682b82c2a5SDouglas Gregor 9692b82c2a5SDouglas Gregor // Parse the module-id with an optional wildcard at the end. 9702b82c2a5SDouglas Gregor ModuleId ParsedModuleId; 9712b82c2a5SDouglas Gregor bool Wildcard = false; 9722b82c2a5SDouglas Gregor do { 9732b82c2a5SDouglas Gregor if (Tok.is(MMToken::Identifier)) { 9742b82c2a5SDouglas Gregor ParsedModuleId.push_back(std::make_pair(Tok.getString(), 9752b82c2a5SDouglas Gregor Tok.getLocation())); 9762b82c2a5SDouglas Gregor consumeToken(); 9772b82c2a5SDouglas Gregor 9782b82c2a5SDouglas Gregor if (Tok.is(MMToken::Period)) { 9792b82c2a5SDouglas Gregor consumeToken(); 9802b82c2a5SDouglas Gregor continue; 9812b82c2a5SDouglas Gregor } 9822b82c2a5SDouglas Gregor 9832b82c2a5SDouglas Gregor break; 9842b82c2a5SDouglas Gregor } 9852b82c2a5SDouglas Gregor 9862b82c2a5SDouglas Gregor if(Tok.is(MMToken::Star)) { 9872b82c2a5SDouglas Gregor Wildcard = true; 988f5eedd05SDouglas Gregor consumeToken(); 9892b82c2a5SDouglas Gregor break; 9902b82c2a5SDouglas Gregor } 9912b82c2a5SDouglas Gregor 9922b82c2a5SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 9932b82c2a5SDouglas Gregor HadError = true; 9942b82c2a5SDouglas Gregor return; 9952b82c2a5SDouglas Gregor } while (true); 9962b82c2a5SDouglas Gregor 9972b82c2a5SDouglas Gregor Module::UnresolvedExportDecl Unresolved = { 9982b82c2a5SDouglas Gregor ExportLoc, ParsedModuleId, Wildcard 9992b82c2a5SDouglas Gregor }; 10002b82c2a5SDouglas Gregor ActiveModule->UnresolvedExports.push_back(Unresolved); 10012b82c2a5SDouglas Gregor } 10022b82c2a5SDouglas Gregor 100373441091SDouglas Gregor void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 100473441091SDouglas Gregor assert(Tok.is(MMToken::Star)); 100573441091SDouglas Gregor SourceLocation StarLoc = consumeToken(); 100673441091SDouglas Gregor bool Failed = false; 100773441091SDouglas Gregor 100873441091SDouglas Gregor // Inferred modules must be submodules. 100973441091SDouglas Gregor if (!ActiveModule) { 101073441091SDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 101173441091SDouglas Gregor Failed = true; 101273441091SDouglas Gregor } 101373441091SDouglas Gregor 1014524e33e1SDouglas Gregor // Inferred modules must have umbrella directories. 1015524e33e1SDouglas Gregor if (!Failed && !ActiveModule->getUmbrellaDir()) { 101673441091SDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 101773441091SDouglas Gregor Failed = true; 101873441091SDouglas Gregor } 101973441091SDouglas Gregor 102073441091SDouglas Gregor // Check for redefinition of an inferred module. 1021dd005f69SDouglas Gregor if (!Failed && ActiveModule->InferSubmodules) { 102273441091SDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1023dd005f69SDouglas Gregor if (ActiveModule->InferredSubmoduleLoc.isValid()) 1024dd005f69SDouglas Gregor Diags.Report(ActiveModule->InferredSubmoduleLoc, 102573441091SDouglas Gregor diag::note_mmap_prev_definition); 102673441091SDouglas Gregor Failed = true; 102773441091SDouglas Gregor } 102873441091SDouglas Gregor 102973441091SDouglas Gregor // If there were any problems with this inferred submodule, skip its body. 103073441091SDouglas Gregor if (Failed) { 103173441091SDouglas Gregor if (Tok.is(MMToken::LBrace)) { 103273441091SDouglas Gregor consumeToken(); 103373441091SDouglas Gregor skipUntil(MMToken::RBrace); 103473441091SDouglas Gregor if (Tok.is(MMToken::RBrace)) 103573441091SDouglas Gregor consumeToken(); 103673441091SDouglas Gregor } 103773441091SDouglas Gregor HadError = true; 103873441091SDouglas Gregor return; 103973441091SDouglas Gregor } 104073441091SDouglas Gregor 104173441091SDouglas Gregor // Note that we have an inferred submodule. 1042dd005f69SDouglas Gregor ActiveModule->InferSubmodules = true; 1043dd005f69SDouglas Gregor ActiveModule->InferredSubmoduleLoc = StarLoc; 1044dd005f69SDouglas Gregor ActiveModule->InferExplicitSubmodules = Explicit; 104573441091SDouglas Gregor 104673441091SDouglas Gregor // Parse the opening brace. 104773441091SDouglas Gregor if (!Tok.is(MMToken::LBrace)) { 104873441091SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 104973441091SDouglas Gregor HadError = true; 105073441091SDouglas Gregor return; 105173441091SDouglas Gregor } 105273441091SDouglas Gregor SourceLocation LBraceLoc = consumeToken(); 105373441091SDouglas Gregor 105473441091SDouglas Gregor // Parse the body of the inferred submodule. 105573441091SDouglas Gregor bool Done = false; 105673441091SDouglas Gregor do { 105773441091SDouglas Gregor switch (Tok.Kind) { 105873441091SDouglas Gregor case MMToken::EndOfFile: 105973441091SDouglas Gregor case MMToken::RBrace: 106073441091SDouglas Gregor Done = true; 106173441091SDouglas Gregor break; 106273441091SDouglas Gregor 106373441091SDouglas Gregor case MMToken::ExportKeyword: { 106473441091SDouglas Gregor consumeToken(); 106573441091SDouglas Gregor if (Tok.is(MMToken::Star)) 1066dd005f69SDouglas Gregor ActiveModule->InferExportWildcard = true; 106773441091SDouglas Gregor else 106873441091SDouglas Gregor Diags.Report(Tok.getLocation(), 106973441091SDouglas Gregor diag::err_mmap_expected_export_wildcard); 107073441091SDouglas Gregor consumeToken(); 107173441091SDouglas Gregor break; 107273441091SDouglas Gregor } 107373441091SDouglas Gregor 107473441091SDouglas Gregor case MMToken::ExplicitKeyword: 107573441091SDouglas Gregor case MMToken::ModuleKeyword: 107673441091SDouglas Gregor case MMToken::HeaderKeyword: 107773441091SDouglas Gregor case MMToken::UmbrellaKeyword: 107873441091SDouglas Gregor default: 107973441091SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 108073441091SDouglas Gregor consumeToken(); 108173441091SDouglas Gregor break; 108273441091SDouglas Gregor } 108373441091SDouglas Gregor } while (!Done); 108473441091SDouglas Gregor 108573441091SDouglas Gregor if (Tok.is(MMToken::RBrace)) 108673441091SDouglas Gregor consumeToken(); 108773441091SDouglas Gregor else { 108873441091SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 108973441091SDouglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 109073441091SDouglas Gregor HadError = true; 109173441091SDouglas Gregor } 109273441091SDouglas Gregor } 109373441091SDouglas Gregor 10947033127bSDouglas Gregor /// \brief If there is a specific header search directory due the presence 10957033127bSDouglas Gregor /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 10967033127bSDouglas Gregor const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 10977033127bSDouglas Gregor for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 10987033127bSDouglas Gregor // If we have an umbrella directory, use that. 10997033127bSDouglas Gregor if (Mod->hasUmbrellaDir()) 11007033127bSDouglas Gregor return Mod->getUmbrellaDir(); 11017033127bSDouglas Gregor 11027033127bSDouglas Gregor // If we have a framework directory, stop looking. 11037033127bSDouglas Gregor if (Mod->IsFramework) 11047033127bSDouglas Gregor return 0; 11057033127bSDouglas Gregor } 11067033127bSDouglas Gregor 11077033127bSDouglas Gregor return 0; 11087033127bSDouglas Gregor } 11097033127bSDouglas Gregor 1110718292f2SDouglas Gregor /// \brief Parse a module map file. 1111718292f2SDouglas Gregor /// 1112718292f2SDouglas Gregor /// module-map-file: 1113718292f2SDouglas Gregor /// module-declaration* 1114718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() { 1115718292f2SDouglas Gregor do { 1116718292f2SDouglas Gregor switch (Tok.Kind) { 1117718292f2SDouglas Gregor case MMToken::EndOfFile: 1118718292f2SDouglas Gregor return HadError; 1119718292f2SDouglas Gregor 1120e7ab3669SDouglas Gregor case MMToken::ExplicitKeyword: 1121718292f2SDouglas Gregor case MMToken::ModuleKeyword: 1122755b2055SDouglas Gregor case MMToken::FrameworkKeyword: 1123718292f2SDouglas Gregor parseModuleDecl(); 1124718292f2SDouglas Gregor break; 1125718292f2SDouglas Gregor 11262b82c2a5SDouglas Gregor case MMToken::ExportKeyword: 1127718292f2SDouglas Gregor case MMToken::HeaderKeyword: 1128718292f2SDouglas Gregor case MMToken::Identifier: 1129718292f2SDouglas Gregor case MMToken::LBrace: 11302b82c2a5SDouglas Gregor case MMToken::Period: 1131718292f2SDouglas Gregor case MMToken::RBrace: 11322b82c2a5SDouglas Gregor case MMToken::Star: 1133718292f2SDouglas Gregor case MMToken::StringLiteral: 1134718292f2SDouglas Gregor case MMToken::UmbrellaKeyword: 1135718292f2SDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1136718292f2SDouglas Gregor HadError = true; 1137718292f2SDouglas Gregor consumeToken(); 1138718292f2SDouglas Gregor break; 1139718292f2SDouglas Gregor } 1140718292f2SDouglas Gregor } while (true); 1141718292f2SDouglas Gregor 1142718292f2SDouglas Gregor return HadError; 1143718292f2SDouglas Gregor } 1144718292f2SDouglas Gregor 1145718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1146718292f2SDouglas Gregor FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1147718292f2SDouglas Gregor const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1148718292f2SDouglas Gregor if (!Buffer) 1149718292f2SDouglas Gregor return true; 1150718292f2SDouglas Gregor 1151718292f2SDouglas Gregor // Parse this module map file. 1152718292f2SDouglas Gregor Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 1153718292f2SDouglas Gregor Diags->getClient()->BeginSourceFile(LangOpts); 11545257fc63SDouglas Gregor ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 1155718292f2SDouglas Gregor bool Result = Parser.parseModuleMapFile(); 1156718292f2SDouglas Gregor Diags->getClient()->EndSourceFile(); 1157718292f2SDouglas Gregor 1158718292f2SDouglas Gregor return Result; 1159718292f2SDouglas Gregor } 1160