ModuleMap.cpp revision 52b1ed3685c80cb436f2a616c3c13a066f9d1e31
1a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 3a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// The LLVM Compiler Infrastructure 4a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 5a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// This file is distributed under the University of Illinois Open Source 6a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// License. See LICENSE.TXT for details. 7a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 8a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//===----------------------------------------------------------------------===// 9a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 10a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// This file defines the ModuleMap implementation, which describes the layout 11a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// of a module as it relates to headers. 12a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 13a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//===----------------------------------------------------------------------===// 14a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Lex/ModuleMap.h" 15a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Lex/Lexer.h" 16a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Lex/LiteralSupport.h" 17a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Lex/LexDiagnostic.h" 18a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/Diagnostic.h" 19a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/FileManager.h" 20a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/TargetInfo.h" 21a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/TargetOptions.h" 22a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/Allocator.h" 23ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor#include "llvm/Support/FileSystem.h" 24a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/Host.h" 258b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor#include "llvm/Support/PathV2.h" 26a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/raw_ostream.h" 27a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/ADT/StringRef.h" 28a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/ADT/StringSwitch.h" 29a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorusing namespace clang; 30a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 3190db26000aefe9335370013eec64c85232d80227Douglas GregorModule::ExportDecl 3290db26000aefe9335370013eec64c85232d80227Douglas GregorModuleMap::resolveExport(Module *Mod, 3390db26000aefe9335370013eec64c85232d80227Douglas Gregor const Module::UnresolvedExportDecl &Unresolved, 3490db26000aefe9335370013eec64c85232d80227Douglas Gregor bool Complain) { 350adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor // We may have just a wildcard. 360adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Unresolved.Id.empty()) { 370adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor assert(Unresolved.Wildcard && "Invalid unresolved export"); 380adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor return Module::ExportDecl(0, true); 390adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor } 400adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor 4190db26000aefe9335370013eec64c85232d80227Douglas Gregor // Find the starting module. 4290db26000aefe9335370013eec64c85232d80227Douglas Gregor Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod); 4390db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) { 4490db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Complain) 4590db26000aefe9335370013eec64c85232d80227Douglas Gregor Diags->Report(Unresolved.Id[0].second, 4690db26000aefe9335370013eec64c85232d80227Douglas Gregor diag::err_mmap_missing_module_unqualified) 4790db26000aefe9335370013eec64c85232d80227Douglas Gregor << Unresolved.Id[0].first << Mod->getFullModuleName(); 4890db26000aefe9335370013eec64c85232d80227Douglas Gregor 4990db26000aefe9335370013eec64c85232d80227Douglas Gregor return Module::ExportDecl(); 5090db26000aefe9335370013eec64c85232d80227Douglas Gregor } 5190db26000aefe9335370013eec64c85232d80227Douglas Gregor 5290db26000aefe9335370013eec64c85232d80227Douglas Gregor // Dig into the module path. 5390db26000aefe9335370013eec64c85232d80227Douglas Gregor for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) { 5490db26000aefe9335370013eec64c85232d80227Douglas Gregor Module *Sub = lookupModuleQualified(Unresolved.Id[I].first, 5590db26000aefe9335370013eec64c85232d80227Douglas Gregor Context); 5690db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Sub) { 5790db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Complain) 5890db26000aefe9335370013eec64c85232d80227Douglas Gregor Diags->Report(Unresolved.Id[I].second, 5990db26000aefe9335370013eec64c85232d80227Douglas Gregor diag::err_mmap_missing_module_qualified) 6090db26000aefe9335370013eec64c85232d80227Douglas Gregor << Unresolved.Id[I].first << Context->getFullModuleName() 6190db26000aefe9335370013eec64c85232d80227Douglas Gregor << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second); 6290db26000aefe9335370013eec64c85232d80227Douglas Gregor 6390db26000aefe9335370013eec64c85232d80227Douglas Gregor return Module::ExportDecl(); 6490db26000aefe9335370013eec64c85232d80227Douglas Gregor } 6590db26000aefe9335370013eec64c85232d80227Douglas Gregor 6690db26000aefe9335370013eec64c85232d80227Douglas Gregor Context = Sub; 6790db26000aefe9335370013eec64c85232d80227Douglas Gregor } 6890db26000aefe9335370013eec64c85232d80227Douglas Gregor 6990db26000aefe9335370013eec64c85232d80227Douglas Gregor return Module::ExportDecl(Context, Unresolved.Wildcard); 7090db26000aefe9335370013eec64c85232d80227Douglas Gregor} 7190db26000aefe9335370013eec64c85232d80227Douglas Gregor 72a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) { 73a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 74a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 75a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor new DiagnosticsEngine(DiagIDs)); 76a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 77a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceMgr = new SourceManager(*Diags, FileMgr); 78a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 79a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 80a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorModuleMap::~ModuleMap() { 8109fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 8209fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor IEnd = Modules.end(); 8309fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor I != IEnd; ++I) { 8409fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor delete I->getValue(); 8509fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor } 8609fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor 87a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor delete SourceMgr; 88a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 89a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 901a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule *ModuleMap::findModuleForHeader(const FileEntry *File) { 9165f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor llvm::DenseMap<const FileEntry *, Module *>::iterator Known 9265f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor = Headers.find(File); 9365f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor if (Known != Headers.end()) 9465f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor return Known->second; 9565f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 96adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor const DirectoryEntry *Dir = File->getDir(); 97adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 98adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor StringRef DirName = Dir->getName(); 99e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 100e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Keep walking up the directory hierarchy, looking for a directory with 101e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // an umbrella header. 102e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor do { 103e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 104e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor = UmbrellaDirs.find(Dir); 105adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor if (KnownDir != UmbrellaDirs.end()) { 106adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor Module *Result = KnownDir->second; 1079f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor 1089f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor // Search up the module stack until we find a module with an umbrella 1099f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor // header. 1109f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor Module *UmbrellaModule = Result; 1119f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor while (!UmbrellaModule->UmbrellaHeader && UmbrellaModule->Parent) 1129f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor UmbrellaModule = UmbrellaModule->Parent; 1139f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor 1149f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferSubmodules) { 115e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Infer submodules for each of the directories we found between 116e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // the directory of the umbrella header and the directory where 117e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // the actual header is located. 118e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 119e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // For a framework module, the umbrella directory is the framework 120e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // directory, so strip off the "Headers" or "PrivateHeaders". 12123af6d58e392e18ae2946b799264717f480e6596Douglas Gregor bool Explicit = UmbrellaModule->InferExplicitSubmodules; 122e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor unsigned LastSkippedDir = SkippedDirs.size(); 12323af6d58e392e18ae2946b799264717f480e6596Douglas Gregor if (LastSkippedDir && UmbrellaModule->IsFramework) { 12423af6d58e392e18ae2946b799264717f480e6596Douglas Gregor if (llvm::sys::path::filename(SkippedDirs.back()->getName()) 12523af6d58e392e18ae2946b799264717f480e6596Douglas Gregor == "PrivateHeaders") { 12623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // For private headers, add an explicit "Private" module. 12723af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // FIXME: This feels somewhat hackish. Do we want to introduce 12823af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // some kind of "umbrella directory" here? 12923af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Result = findOrCreateModule("Private", Result, 13023af6d58e392e18ae2946b799264717f480e6596Douglas Gregor /*IsFramework=*/false, 13123af6d58e392e18ae2946b799264717f480e6596Douglas Gregor /*IsExplicit=*/true).first; 13223af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Explicit = true; 13323af6d58e392e18ae2946b799264717f480e6596Douglas Gregor } 13423af6d58e392e18ae2946b799264717f480e6596Douglas Gregor 135e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor --LastSkippedDir; 13623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor } 137e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 138e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor for (unsigned I = LastSkippedDir; I != 0; --I) { 139e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Find or create the module that corresponds to this directory name. 140e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName()); 141e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 14223af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Explicit).first; 143e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 144e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Associate the module and the directory. 145e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDirs[SkippedDirs[I-1]] = Result; 146e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 147e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // If inferred submodules export everything they import, add a 148e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // wildcard to the set of exports. 1499f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 150e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 151e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 152e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 153e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Infer a submodule with the same name as this header file. 154e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor StringRef Name = llvm::sys::path::stem(File->getName()); 155e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 15623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Explicit).first; 157e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 158e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // If inferred submodules export everything they import, add a 159e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // wildcard to the set of exports. 1609f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 161e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 162e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } else { 163e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Record each of the directories we stepped through as being part of 164e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // the module we found, since the umbrella header covers them all. 165e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 166e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDirs[SkippedDirs[I]] = Result; 167e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 168adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 169e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Headers[File] = Result; 170adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor return Result; 171adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor } 172adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 173adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor SkippedDirs.push_back(Dir); 174e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 175e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Retrieve our parent path. 176e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 177e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor if (DirName.empty()) 178e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor break; 179e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 180e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Resolve the parent path to a directory entry. 181e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Dir = SourceMgr->getFileManager().getDirectory(DirName); 182e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } while (Dir); 183adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 18465f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor return 0; 18565f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor} 18665f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 1871a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule *ModuleMap::findModule(StringRef Name) { 188484535e45b4d301847a157e943c7823da5d40884Douglas Gregor llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 189484535e45b4d301847a157e943c7823da5d40884Douglas Gregor if (Known != Modules.end()) 190484535e45b4d301847a157e943c7823da5d40884Douglas Gregor return Known->getValue(); 191484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 192484535e45b4d301847a157e943c7823da5d40884Douglas Gregor return 0; 193484535e45b4d301847a157e943c7823da5d40884Douglas Gregor} 194484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 19590db26000aefe9335370013eec64c85232d80227Douglas GregorModule *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) { 19690db26000aefe9335370013eec64c85232d80227Douglas Gregor for(; Context; Context = Context->Parent) { 19790db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Context)) 19890db26000aefe9335370013eec64c85232d80227Douglas Gregor return Sub; 19990db26000aefe9335370013eec64c85232d80227Douglas Gregor } 20090db26000aefe9335370013eec64c85232d80227Douglas Gregor 20190db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 20290db26000aefe9335370013eec64c85232d80227Douglas Gregor} 20390db26000aefe9335370013eec64c85232d80227Douglas Gregor 20490db26000aefe9335370013eec64c85232d80227Douglas GregorModule *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) { 20590db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) 20690db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 20790db26000aefe9335370013eec64c85232d80227Douglas Gregor 20890db26000aefe9335370013eec64c85232d80227Douglas Gregor llvm::StringMap<Module *>::iterator Sub = Context->SubModules.find(Name); 20990db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Sub != Context->SubModules.end()) 21090db26000aefe9335370013eec64c85232d80227Douglas Gregor return Sub->getValue(); 21190db26000aefe9335370013eec64c85232d80227Douglas Gregor 21290db26000aefe9335370013eec64c85232d80227Douglas Gregor return 0; 21390db26000aefe9335370013eec64c85232d80227Douglas Gregor} 21490db26000aefe9335370013eec64c85232d80227Douglas Gregor 2151a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorstd::pair<Module *, bool> 216392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas GregorModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 217392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor bool IsExplicit) { 218392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Try to find an existing module with this name. 219392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name]) 220392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor return std::make_pair(Found, false); 221392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 222392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Create a new module with this name. 223392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 224392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor IsExplicit); 225392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor if (Parent) 226392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Parent->SubModules[Name] = Result; 227392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor else 228392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Modules[Name] = Result; 229392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor return std::make_pair(Result, true); 230392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor} 231392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 2321a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule * 2332821c7f8870629b56b9c41e1c50c7a091edd544dDouglas GregorModuleMap::inferFrameworkModule(StringRef ModuleName, 234ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const DirectoryEntry *FrameworkDir, 235ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Module *Parent) { 2362821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Check whether we've already found this module. 237ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 238ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor return Mod; 239ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 240ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor FileManager &FileMgr = SourceMgr->getFileManager(); 2412821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 2422821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Look for an umbrella header. 2432821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 2442821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor llvm::sys::path::append(UmbrellaName, "Headers"); 2452821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 246ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 2472821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 2482821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // FIXME: If there's no umbrella header, we could probably scan the 2492821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // framework to load *everything*. But, it's not clear that this is a good 2502821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // idea. 2512821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor if (!UmbrellaHeader) 2522821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return 0; 2532821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 254ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Module *Result = new Module(ModuleName, SourceLocation(), Parent, 255ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor /*IsFramework=*/true, /*IsExplicit=*/false); 256ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 257ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (Parent) 258ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Parent->SubModules[ModuleName] = Result; 259ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor else 260ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Modules[ModuleName] = Result; 261ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 262209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor // umbrella "umbrella-header-name" 2632821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor Result->UmbrellaHeader = UmbrellaHeader; 2642821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor Headers[UmbrellaHeader] = Result; 2652821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor UmbrellaDirs[FrameworkDir] = Result; 266209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor 267209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor // export * 268209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 269209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor 270e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // module * { export * } 271e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferSubmodules = true; 272e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferExportWildcard = true; 273e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 274ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // Look for subframeworks. 275ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor llvm::error_code EC; 27652b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor llvm::SmallString<128> SubframeworksDirName 27752b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor = StringRef(FrameworkDir->getName()); 278ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 27952b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor llvm::SmallString<128> SubframeworksDirNameNative; 28052b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor llvm::sys::path::native(SubframeworksDirName.str(), 28152b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor SubframeworksDirNameNative); 28252b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor for (llvm::sys::fs::directory_iterator 28352b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 284ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 285ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (!StringRef(Dir->path()).endswith(".framework")) 286ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor continue; 287ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 288ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (const DirectoryEntry *SubframeworkDir 289ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor = FileMgr.getDirectory(Dir->path())) { 290ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // FIXME: Do we want to warn about subframeworks without umbrella headers? 291ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, 292ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Result); 293ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 294ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 295d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 29623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // Look for private headers. 29723af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Module *ModulePrivate = 0; 29823af6d58e392e18ae2946b799264717f480e6596Douglas Gregor llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName()); 29923af6d58e392e18ae2946b799264717f480e6596Douglas Gregor llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders"); 30052b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor llvm::SmallString<128> PrivateHeadersDirNameNative; 30152b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor llvm::sys::path::native(PrivateHeadersDirName.str(), 30252b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor PrivateHeadersDirNameNative); 30352b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor for (llvm::sys::fs::directory_iterator 30452b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor Dir(PrivateHeadersDirNameNative.str(), EC), DirEnd; 30523af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 30623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // Check whether this entry has an extension typically associated with 30723af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // headers. 30823af6d58e392e18ae2946b799264717f480e6596Douglas Gregor if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path())) 30923af6d58e392e18ae2946b799264717f480e6596Douglas Gregor .Cases(".h", ".H", ".hh", ".hpp", true) 31023af6d58e392e18ae2946b799264717f480e6596Douglas Gregor .Default(false)) 31123af6d58e392e18ae2946b799264717f480e6596Douglas Gregor continue; 31223af6d58e392e18ae2946b799264717f480e6596Douglas Gregor 31323af6d58e392e18ae2946b799264717f480e6596Douglas Gregor if (const FileEntry *PrivateHeader = FileMgr.getFile(Dir->path())) { 31423af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // Create the "private" submodule, if we haven't done so already. 31523af6d58e392e18ae2946b799264717f480e6596Douglas Gregor if (!ModulePrivate) { 31623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor ModulePrivate = findOrCreateModule("Private", Result, 31723af6d58e392e18ae2946b799264717f480e6596Douglas Gregor /*IsFramework=*/false, 31823af6d58e392e18ae2946b799264717f480e6596Douglas Gregor /*IsExplicit=*/true).first; 31923af6d58e392e18ae2946b799264717f480e6596Douglas Gregor } 32023af6d58e392e18ae2946b799264717f480e6596Douglas Gregor 32123af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Module *Sub = findOrCreateModule(llvm::sys::path::stem(Dir->path()), 32223af6d58e392e18ae2946b799264717f480e6596Douglas Gregor ModulePrivate, /*IsFramework=*/false, 32323af6d58e392e18ae2946b799264717f480e6596Douglas Gregor /*IsExplicit=*/true).first; 32423af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // header "the private header" 32523af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Sub->Headers.push_back(PrivateHeader); 32623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor 32723af6d58e392e18ae2946b799264717f480e6596Douglas Gregor // export * 32823af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Sub->Exports.push_back(Module::ExportDecl(0, true)); 32923af6d58e392e18ae2946b799264717f480e6596Douglas Gregor 33023af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Headers[PrivateHeader] = Sub; 33123af6d58e392e18ae2946b799264717f480e6596Douglas Gregor } 33223af6d58e392e18ae2946b799264717f480e6596Douglas Gregor } 33323af6d58e392e18ae2946b799264717f480e6596Douglas Gregor 3342821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Result; 3352821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 3362821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 337e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregorvoid ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 338e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Headers[UmbrellaHeader] = Mod; 339e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Mod->UmbrellaHeader = UmbrellaHeader; 340e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 341e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor const DirectoryEntry *UmbrellaDir = UmbrellaHeader->getDir(); 342e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor if (Mod->IsFramework) 343e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDir = SourceMgr->getFileManager().getDirectory( 344e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor llvm::sys::path::parent_path(UmbrellaDir->getName())); 345e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 346e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDirs[UmbrellaDir] = Mod; 347e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 348e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 349e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregorvoid ModuleMap::addHeader(Module *Mod, const FileEntry *Header) { 350e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Mod->Headers.push_back(Header); 351e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Headers[Header] = Mod; 352e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 353e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 354f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregorconst FileEntry * 3551a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModuleMap::getContainingModuleMapFile(Module *Module) { 356f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 357f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor return 0; 358f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 359f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor return SourceMgr->getFileEntryForID( 360f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor SourceMgr->getFileID(Module->DefinitionLoc)); 361f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor} 362f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 363a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMap::dump() { 364a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Modules:"; 365a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 366a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MEnd = Modules.end(); 367a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor M != MEnd; ++M) 368804c3bfee22076f232dddf4839439119cfdee2b6Douglas Gregor M->getValue()->print(llvm::errs(), 2); 369a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 370a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Headers:"; 371a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (llvm::DenseMap<const FileEntry *, Module *>::iterator 372a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor H = Headers.begin(), 373a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HEnd = Headers.end(); 374a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor H != HEnd; ++H) { 375a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << " \"" << H->first->getName() << "\" -> " 376a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << H->second->getFullModuleName() << "\n"; 377a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 378a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 379a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 38090db26000aefe9335370013eec64c85232d80227Douglas Gregorbool ModuleMap::resolveExports(Module *Mod, bool Complain) { 38190db26000aefe9335370013eec64c85232d80227Douglas Gregor bool HadError = false; 38290db26000aefe9335370013eec64c85232d80227Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 38390db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 38490db26000aefe9335370013eec64c85232d80227Douglas Gregor Complain); 3850adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Export.getPointer() || Export.getInt()) 38690db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->Exports.push_back(Export); 38790db26000aefe9335370013eec64c85232d80227Douglas Gregor else 38890db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 38990db26000aefe9335370013eec64c85232d80227Douglas Gregor } 39090db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->UnresolvedExports.clear(); 39190db26000aefe9335370013eec64c85232d80227Douglas Gregor return HadError; 39290db26000aefe9335370013eec64c85232d80227Douglas Gregor} 39390db26000aefe9335370013eec64c85232d80227Douglas Gregor 39455988680ece66b8e505ee136b35e74fcb1173aeeDouglas GregorModule *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 39555988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (Loc.isInvalid()) 39655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return 0; 39755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 39855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Use the expansion location to determine which module we're in. 39955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 40055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (!ExpansionLoc.isFileID()) 40155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return 0; 40255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 40355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 40455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor const SourceManager &SrcMgr = Loc.getManager(); 40555988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FileID ExpansionFileID = ExpansionLoc.getFileID(); 40655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID); 40755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (!ExpansionFile) 40855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return 0; 40955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 41055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Find the module that owns this header. 41155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return findModuleForHeader(ExpansionFile); 41255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor} 41355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 414a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 415a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// Module map file parser 416a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 417a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 418a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregornamespace clang { 419a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief A token in a module map file. 420a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor struct MMToken { 421a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor enum TokenKind { 422a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor EndOfFile, 423a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HeaderKeyword, 424a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Identifier, 425a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ExplicitKeyword, 42690db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportKeyword, 427a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor FrameworkKeyword, 428a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleKeyword, 42990db26000aefe9335370013eec64c85232d80227Douglas Gregor Period, 430a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor UmbrellaKeyword, 43190db26000aefe9335370013eec64c85232d80227Douglas Gregor Star, 432a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLiteral, 433a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LBrace, 434a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor RBrace 435a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } Kind; 436a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 437a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Location; 438a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned StringLength; 439a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const char *StringData; 440a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 441a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void clear() { 442a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Kind = EndOfFile; 443a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Location = 0; 444a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLength = 0; 445a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringData = 0; 446a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 447a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 448a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool is(TokenKind K) const { return Kind == K; } 449a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 450a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation getLocation() const { 451a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return SourceLocation::getFromRawEncoding(Location); 452a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 453a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 454a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef getString() const { 455a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return StringRef(StringData, StringLength); 456a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 457a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 458a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 459a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor class ModuleMapParser { 460a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Lexer &L; 461a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceManager &SourceMgr; 462a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags; 463a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleMap ⤅ 464a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 4658b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor /// \brief The directory that this module map resides in. 4668b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor const DirectoryEntry *Directory; 4678b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor 468a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Whether an error occurred. 469a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool HadError; 470a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 471a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Default target information, used only for string literal 472a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// parsing. 473a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor TargetInfo *Target; 474a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 475a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Stores string data for the various string literals referenced 476a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// during parsing. 477a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::BumpPtrAllocator StringData; 478a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 479a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The current token. 480a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MMToken Tok; 481a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 482a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The active module. 4831a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Module *ActiveModule; 484a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 485a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Consume the current token and return its location. 486a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation consumeToken(); 487a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 488a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Skip tokens until we reach the a token with the given kind 489a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// (or the end of the file). 490a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void skipUntil(MMToken::TokenKind K); 491587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 492587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2> 493587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleId; 494587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor bool parseModuleId(ModuleId &Id); 495a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void parseModuleDecl(); 496a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void parseUmbrellaDecl(); 497a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void parseHeaderDecl(); 49890db26000aefe9335370013eec64c85232d80227Douglas Gregor void parseExportDecl(); 4991e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor void parseInferredSubmoduleDecl(bool Explicit); 500a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 501a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor public: 502a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 503a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags, 5048b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor ModuleMap &Map, 5058b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor const DirectoryEntry *Directory) 5068b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 5078b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Directory(Directory), HadError(false), ActiveModule(0) 508a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor { 509a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor TargetOptions TargetOpts; 510a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 511a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 512a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 513a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 514a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 515a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 516a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 517a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool parseModuleMapFile(); 518a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 519a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 520a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 521a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorSourceLocation ModuleMapParser::consumeToken() { 522a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorretry: 523a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation Result = Tok.getLocation(); 524a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 525a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 526a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Token LToken; 527a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor L.LexFromRawLexer(LToken); 528a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Location = LToken.getLocation().getRawEncoding(); 529a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (LToken.getKind()) { 530a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::raw_identifier: 531a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringData = LToken.getRawIdentifierData(); 532a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringLength = LToken.getLength(); 533a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 534a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("header", MMToken::HeaderKeyword) 535a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("explicit", MMToken::ExplicitKeyword) 53690db26000aefe9335370013eec64c85232d80227Douglas Gregor .Case("export", MMToken::ExportKeyword) 537a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor .Case("framework", MMToken::FrameworkKeyword) 538a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("module", MMToken::ModuleKeyword) 539a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("umbrella", MMToken::UmbrellaKeyword) 540a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Default(MMToken::Identifier); 541a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 542a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 543a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::eof: 544a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::EndOfFile; 545a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 546a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 547a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::l_brace: 548a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::LBrace; 549a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 550a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 55190db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::period: 55290db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Period; 55390db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 55490db26000aefe9335370013eec64c85232d80227Douglas Gregor 555a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::r_brace: 556a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::RBrace; 557a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 558a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 55990db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::star: 56090db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Star; 56190db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 56290db26000aefe9335370013eec64c85232d80227Douglas Gregor 563a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::string_literal: { 564a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the string literal. 565a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LangOptions LangOpts; 566a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 567a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (StringLiteral.hadError) 568a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 569a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 570a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Copy the string literal into our string data allocator. 571a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Length = StringLiteral.GetStringLength(); 572a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor char *Saved = StringData.Allocate<char>(Length + 1); 573a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor memcpy(Saved, StringLiteral.GetString().data(), Length); 574a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Saved[Length] = 0; 575a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 576a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Form the token. 577a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::StringLiteral; 578a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringData = Saved; 579a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringLength = Length; 580a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 581a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 582a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 583a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::comment: 584a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 585a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 586a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 587a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 588a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 589a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 590a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 591a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 592a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 593a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 594a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 595a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::skipUntil(MMToken::TokenKind K) { 596a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned braceDepth = 0; 597a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 598a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 599a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 600a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 601a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 602a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 603a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(K) && braceDepth == 0) 604a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 605a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 606a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ++braceDepth; 607a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 608a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 609a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 610a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (braceDepth > 0) 611a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor --braceDepth; 612a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else if (Tok.is(K)) 613a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 614a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 615a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 616a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 617a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (braceDepth == 0 && Tok.is(K)) 618a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 619a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 620a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 621a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 622a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 623a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 624a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 625a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 626587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \brief Parse a module-id. 627587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 628587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// module-id: 629587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier 630587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier '.' module-id 631587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 632587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \returns true if an error occurred, false otherwise. 633587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregorbool ModuleMapParser::parseModuleId(ModuleId &Id) { 634587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.clear(); 635587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor do { 636587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Tok.is(MMToken::Identifier)) { 637587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 638587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 639587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 640587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 641587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return true; 642587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 643587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 644587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!Tok.is(MMToken::Period)) 645587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor break; 646587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 647587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 648587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } while (true); 649587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 650587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return false; 651587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor} 652587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 653a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module declaration. 654a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 655a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration: 656587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* } 657a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 658a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-member: 659a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// umbrella-declaration 660a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// header-declaration 661587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// submodule-declaration 66290db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration 6631e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// 6641e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// submodule-declaration: 6651e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// module-declaration 6661e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// inferred-submodule-declaration 667a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::parseModuleDecl() { 668a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 669a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor Tok.is(MMToken::FrameworkKeyword)); 670d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'explicit' or 'framework' keyword, if present. 671587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ExplicitLoc; 672a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Explicit = false; 673d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor bool Framework = false; 674a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 675a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor // Parse 'explicit' keyword, if present. 676d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::ExplicitKeyword)) { 677587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = consumeToken(); 678a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Explicit = true; 679a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 680d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 681d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'framework' keyword, if present. 682d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 683d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor consumeToken(); 684d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Framework = true; 685d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 686a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 687a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse 'module' keyword. 688a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::ModuleKeyword)) { 689e6fb9876970e2dc55f091522644efa16caa9ba06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 690a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 691a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 692a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 693a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 694a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); // 'module' keyword 6951e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 6961e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If we have a wildcard for the module name, this is an inferred submodule. 6971e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse it. 6981e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 6991e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return parseInferredSubmoduleDecl(Explicit); 700a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 701a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the module name. 702587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleId Id; 703587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (parseModuleId(Id)) { 704587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 705587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 706587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 707587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 708587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 709587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 710587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 711587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor << SourceRange(Id.front().second, Id.back().second); 712587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 713587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 714587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 715587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 716587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else if (Id.size() == 1 && Explicit) { 717587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Top-level modules can't be explicit. 718587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 719587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Explicit = false; 720587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = SourceLocation(); 721a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 722a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 723587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 724587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Module *PreviousActiveModule = ActiveModule; 725587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 726587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // This module map defines a submodule. Go find the module of which it 727587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // is a submodule. 728587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = 0; 729587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 730587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 731587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = Next; 732587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor continue; 733587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 734587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 735587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 736587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 737587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor << Id[I].first << ActiveModule->getTopLevelModule(); 738587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 739587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 740587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 741587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 742587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 743587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 744587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 745587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 746587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor StringRef ModuleName = Id.back().first; 747587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ModuleNameLoc = Id.back().second; 748a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 749a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the opening brace. 750a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 751a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 752a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 753a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 754a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 755a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 756a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 757a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 758a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this (sub)module has already been defined. 759a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::StringMap<Module *> &ModuleSpace 760a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor = ActiveModule? ActiveModule->SubModules : Map.Modules; 761a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::StringMap<Module *>::iterator ExistingModule 762a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor = ModuleSpace.find(ModuleName); 763a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (ExistingModule != ModuleSpace.end()) { 764a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 765a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 766a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(ExistingModule->getValue()->DefinitionLoc, 767a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor diag::note_mmap_prev_definition); 768a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 769a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Skip the module definition. 770a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor skipUntil(MMToken::RBrace); 771a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 772a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 773a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 774a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 775a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 776a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 777a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 778a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Start defining this module. 779a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 780a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor Explicit); 781a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleSpace[ModuleName] = ActiveModule; 782a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 783a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Done = false; 784a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 785a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 786a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 787a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 788a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Done = true; 789a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 790a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 791a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ExplicitKeyword: 792d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor case MMToken::FrameworkKeyword: 793a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 794a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 795a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 796a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 79790db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 79890db26000aefe9335370013eec64c85232d80227Douglas Gregor parseExportDecl(); 79990db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 80090db26000aefe9335370013eec64c85232d80227Douglas Gregor 801a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::HeaderKeyword: 802a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseHeaderDecl(); 803a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 804a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 805a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::UmbrellaKeyword: 806a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseUmbrellaDecl(); 807a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 80890db26000aefe9335370013eec64c85232d80227Douglas Gregor 809a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 810a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 811a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 812a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 813a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 814a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (!Done); 815a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 816a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 817a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 818a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else { 819a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 820a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 821a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 822a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 823a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 824587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // We're done parsing this module. Pop back to the previous module. 825587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = PreviousActiveModule; 826a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 827d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 828d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// \brief Append to \p Paths the set of paths needed to get to the 829d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// subframework in which the given module lives. 830d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregorvoid appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) { 831d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Collect the framework names from the given module to the top-level module. 832d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor llvm::SmallVector<StringRef, 2> Paths; 833d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor for (; Mod; Mod = Mod->Parent) { 834d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Mod->IsFramework) 835d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Paths.push_back(Mod->Name); 836d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 837d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 838d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Paths.empty()) 839d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor return; 840d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 841d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Add Frameworks/Name.framework for each subframework. 842d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor for (unsigned I = Paths.size() - 1; I != 0; --I) { 843d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor llvm::sys::path::append(Path, "Frameworks"); 844d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor llvm::sys::path::append(Path, Paths[I-1] + ".framework"); 845d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 846d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor} 847d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 848a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse an umbrella header declaration. 849a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 850a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// umbrella-declaration: 851a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 'umbrella' string-literal 852a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::parseUmbrellaDecl() { 853a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor assert(Tok.is(MMToken::UmbrellaKeyword)); 854a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation UmbrellaLoc = consumeToken(); 855a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 856a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the header name. 857a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 858a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 859a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << "umbrella"; 860a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 861a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 862a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 863587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor std::string FileName = Tok.getString(); 864a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation FileNameLoc = consumeToken(); 865a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 8668b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Check whether we already have an umbrella header. 8678b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor if (ActiveModule->UmbrellaHeader) { 8688b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict) 8698b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor << ActiveModule->getFullModuleName() 8708b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor << ActiveModule->UmbrellaHeader->getName(); 8718b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 8728b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor return; 8738b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 8748b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor 8758b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Look for this file. 8768b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor llvm::SmallString<128> PathName; 877a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor const FileEntry *File = 0; 87818ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor 87918ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor if (llvm::sys::path::is_absolute(FileName)) { 88018ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor PathName = FileName; 881a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 88218ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } else { 88318ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor // Search for the header file within the search directory. 88418ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor PathName += Directory->getName(); 88518ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor unsigned PathLength = PathName.size(); 886d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 88718ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor if (ActiveModule->isPartOfFramework()) { 888d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor appendSubframeworkPaths(ActiveModule, PathName); 889d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 89018ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor // Check whether this file is in the public headers. 89118ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor llvm::sys::path::append(PathName, "Headers"); 89218ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor llvm::sys::path::append(PathName, FileName); 89318ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 894a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 89518ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor if (!File) { 89618ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor // Check whether this file is in the private headers. 89718ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor PathName.resize(PathLength); 89818ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor llvm::sys::path::append(PathName, "PrivateHeaders"); 89918ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor llvm::sys::path::append(PathName, FileName); 90018ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 90118ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } 90218ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } else { 90318ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor // Lookup for normal headers. 904a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor llvm::sys::path::append(PathName, FileName); 905a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 906a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor } 907a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor } 9088b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor 9098b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 9108b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Come up with a lazy way to do this. 911a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor if (File) { 912e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor const DirectoryEntry *UmbrellaDir = File->getDir(); 913e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor if (ActiveModule->IsFramework) { 914e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // For framework modules, use the framework directory as the umbrella 915e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // directory. 916e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDir = SourceMgr.getFileManager().getDirectory( 917e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor llvm::sys::path::parent_path(UmbrellaDir->getName())); 918e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 919e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 9208b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor if (const Module *OwningModule = Map.Headers[File]) { 9218b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 9228b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor << FileName << OwningModule->getFullModuleName(); 9238b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 924e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } else if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) { 925adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 926adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor << OwningModule->getFullModuleName(); 927adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor HadError = true; 9288b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 9298b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Record this umbrella header. 930e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Map.setUmbrellaHeader(ActiveModule, File); 9318b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 9328b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 9338b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 9348b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor << true << FileName; 9358b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 9368b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 937a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 938a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 939a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a header declaration. 940a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 941a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// header-declaration: 942a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 'header' string-literal 943a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::parseHeaderDecl() { 944a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor assert(Tok.is(MMToken::HeaderKeyword)); 945c96c7218b9968f0f4bd30c25e79aca638a3249b6Benjamin Kramer consumeToken(); 946c96c7218b9968f0f4bd30c25e79aca638a3249b6Benjamin Kramer 947a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the header name. 948a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 949a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 950a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << "header"; 951a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 952a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 953a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 954587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor std::string FileName = Tok.getString(); 955a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation FileNameLoc = consumeToken(); 956a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 9578b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Look for this file. 958587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor const FileEntry *File = 0; 9598b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor llvm::SmallString<128> PathName; 960587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (llvm::sys::path::is_absolute(FileName)) { 961587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor PathName = FileName; 962587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 963587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 964587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Search for the header file within the search directory. 96518ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor PathName += Directory->getName(); 966587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor unsigned PathLength = PathName.size(); 96718ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor 968d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (ActiveModule->isPartOfFramework()) { 969d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor appendSubframeworkPaths(ActiveModule, PathName); 970587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 971587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the public headers. 97218ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor llvm::sys::path::append(PathName, "Headers"); 973587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(PathName, FileName); 974587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 975587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 976587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!File) { 977587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the private headers. 978587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor PathName.resize(PathLength); 979587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(PathName, "PrivateHeaders"); 980587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(PathName, FileName); 981587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 982587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 983587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 984587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Lookup for normal headers. 985587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(PathName, FileName); 986587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 987d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 98818ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } 989a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 9908b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 9918b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Come up with a lazy way to do this. 992587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (File) { 9938b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor if (const Module *OwningModule = Map.Headers[File]) { 9948b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 9958b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor << FileName << OwningModule->getFullModuleName(); 9968b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 9978b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 9988b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Record this file. 999e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Map.addHeader(ActiveModule, File); 10008b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 10018b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 10028b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 10038b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor << false << FileName; 10048b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 10058b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1006a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1007a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 100890db26000aefe9335370013eec64c85232d80227Douglas Gregor/// \brief Parse a module export declaration. 100990db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 101090db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration: 101190db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 'export' wildcard-module-id 101290db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 101390db26000aefe9335370013eec64c85232d80227Douglas Gregor/// wildcard-module-id: 101490db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier 101590db26000aefe9335370013eec64c85232d80227Douglas Gregor/// '*' 101690db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier '.' wildcard-module-id 101790db26000aefe9335370013eec64c85232d80227Douglas Gregorvoid ModuleMapParser::parseExportDecl() { 101890db26000aefe9335370013eec64c85232d80227Douglas Gregor assert(Tok.is(MMToken::ExportKeyword)); 101990db26000aefe9335370013eec64c85232d80227Douglas Gregor SourceLocation ExportLoc = consumeToken(); 102090db26000aefe9335370013eec64c85232d80227Douglas Gregor 102190db26000aefe9335370013eec64c85232d80227Douglas Gregor // Parse the module-id with an optional wildcard at the end. 102290db26000aefe9335370013eec64c85232d80227Douglas Gregor ModuleId ParsedModuleId; 102390db26000aefe9335370013eec64c85232d80227Douglas Gregor bool Wildcard = false; 102490db26000aefe9335370013eec64c85232d80227Douglas Gregor do { 102590db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Identifier)) { 102690db26000aefe9335370013eec64c85232d80227Douglas Gregor ParsedModuleId.push_back(std::make_pair(Tok.getString(), 102790db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.getLocation())); 102890db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 102990db26000aefe9335370013eec64c85232d80227Douglas Gregor 103090db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Period)) { 103190db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 103290db26000aefe9335370013eec64c85232d80227Douglas Gregor continue; 103390db26000aefe9335370013eec64c85232d80227Douglas Gregor } 103490db26000aefe9335370013eec64c85232d80227Douglas Gregor 103590db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 103690db26000aefe9335370013eec64c85232d80227Douglas Gregor } 103790db26000aefe9335370013eec64c85232d80227Douglas Gregor 103890db26000aefe9335370013eec64c85232d80227Douglas Gregor if(Tok.is(MMToken::Star)) { 103990db26000aefe9335370013eec64c85232d80227Douglas Gregor Wildcard = true; 10400adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor consumeToken(); 104190db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 104290db26000aefe9335370013eec64c85232d80227Douglas Gregor } 104390db26000aefe9335370013eec64c85232d80227Douglas Gregor 104490db26000aefe9335370013eec64c85232d80227Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 104590db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 104690db26000aefe9335370013eec64c85232d80227Douglas Gregor return; 104790db26000aefe9335370013eec64c85232d80227Douglas Gregor } while (true); 104890db26000aefe9335370013eec64c85232d80227Douglas Gregor 104990db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::UnresolvedExportDecl Unresolved = { 105090db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportLoc, ParsedModuleId, Wildcard 105190db26000aefe9335370013eec64c85232d80227Douglas Gregor }; 105290db26000aefe9335370013eec64c85232d80227Douglas Gregor ActiveModule->UnresolvedExports.push_back(Unresolved); 105390db26000aefe9335370013eec64c85232d80227Douglas Gregor} 105490db26000aefe9335370013eec64c85232d80227Douglas Gregor 10551e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregorvoid ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) { 10561e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor assert(Tok.is(MMToken::Star)); 10571e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation StarLoc = consumeToken(); 10581e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Failed = false; 10591e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10601e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Inferred modules must be submodules. 10611e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (!ActiveModule) { 10621e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 10631e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Failed = true; 10641e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 10651e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10661e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Inferred modules must have umbrella headers. 1067ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor if (!Failed && !ActiveModule->UmbrellaHeader) { 10681e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 10691e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Failed = true; 10701e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 10711e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10721e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Check for redefinition of an inferred module. 1073ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor if (!Failed && ActiveModule->InferSubmodules) { 10741e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1075ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor if (ActiveModule->InferredSubmoduleLoc.isValid()) 1076ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor Diags.Report(ActiveModule->InferredSubmoduleLoc, 10771e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor diag::note_mmap_prev_definition); 10781e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Failed = true; 10791e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 10801e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10811e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If there were any problems with this inferred submodule, skip its body. 10821e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Failed) { 10831e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::LBrace)) { 10841e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 10851e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor skipUntil(MMToken::RBrace); 10861e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 10871e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 10881e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 10891e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 10901e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 10911e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 10921e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10931e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Note that we have an inferred submodule. 1094ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferSubmodules = true; 1095ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferredSubmoduleLoc = StarLoc; 1096ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferExplicitSubmodules = Explicit; 10971e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10981e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the opening brace. 10991e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 11001e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 11011e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 11021e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 11031e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 11041e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 11051e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 11061e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the body of the inferred submodule. 11071e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Done = false; 11081e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor do { 11091e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor switch (Tok.Kind) { 11101e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::EndOfFile: 11111e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::RBrace: 11121e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Done = true; 11131e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 11141e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 11151e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ExportKeyword: { 11161e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 11171e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 1118ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferExportWildcard = true; 11191e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else 11201e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), 11211e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor diag::err_mmap_expected_export_wildcard); 11221e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 11231e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 11241e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 11251e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 11261e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ExplicitKeyword: 11271e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ModuleKeyword: 11281e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::HeaderKeyword: 11291e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::UmbrellaKeyword: 11301e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor default: 11311e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member); 11321e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 11331e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 11341e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 11351e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } while (!Done); 11361e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 11371e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 11381e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 11391e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else { 11401e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 11411e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 11421e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 11431e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 11441e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor} 11451e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 1146a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module map file. 1147a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1148a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-map-file: 1149a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration* 1150a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool ModuleMapParser::parseModuleMapFile() { 1151a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1152a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1153a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1154a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return HadError; 1155a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1156587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor case MMToken::ExplicitKeyword: 1157a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 1158a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor case MMToken::FrameworkKeyword: 1159a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 1160a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1161a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 116290db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 1163a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::HeaderKeyword: 1164a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::Identifier: 1165a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 116690db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Period: 1167a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 116890db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Star: 1169a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::StringLiteral: 1170a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::UmbrellaKeyword: 1171a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1172a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1173a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1174a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1175a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1176a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 1177a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1178a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return HadError; 1179a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1180a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1181a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool ModuleMap::parseModuleMapFile(const FileEntry *File) { 1182a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 1183a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 1184a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Buffer) 1185a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return true; 1186a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1187a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse this module map file. 1188a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 1189a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags->getClient()->BeginSourceFile(LangOpts); 11908b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 1191a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Result = Parser.parseModuleMapFile(); 1192a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags->getClient()->EndSourceFile(); 1193a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1194a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 1195a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1196