1*f4a2713aSLionel Sambuc //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This file defines the ModuleMap implementation, which describes the layout 11*f4a2713aSLionel Sambuc // of a module as it relates to headers. 12*f4a2713aSLionel Sambuc // 13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14*f4a2713aSLionel Sambuc #include "clang/Lex/ModuleMap.h" 15*f4a2713aSLionel Sambuc #include "clang/Basic/CharInfo.h" 16*f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h" 17*f4a2713aSLionel Sambuc #include "clang/Basic/DiagnosticOptions.h" 18*f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h" 19*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 20*f4a2713aSLionel Sambuc #include "clang/Basic/TargetOptions.h" 21*f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h" 22*f4a2713aSLionel Sambuc #include "clang/Lex/LexDiagnostic.h" 23*f4a2713aSLionel Sambuc #include "clang/Lex/Lexer.h" 24*f4a2713aSLionel Sambuc #include "clang/Lex/LiteralSupport.h" 25*f4a2713aSLionel Sambuc #include "llvm/ADT/StringRef.h" 26*f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h" 27*f4a2713aSLionel Sambuc #include "llvm/Support/Allocator.h" 28*f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h" 29*f4a2713aSLionel Sambuc #include "llvm/Support/Host.h" 30*f4a2713aSLionel Sambuc #include "llvm/Support/Path.h" 31*f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h" 32*f4a2713aSLionel Sambuc #include <stdlib.h> 33*f4a2713aSLionel Sambuc #if defined(LLVM_ON_UNIX) 34*f4a2713aSLionel Sambuc #include <limits.h> 35*f4a2713aSLionel Sambuc #endif 36*f4a2713aSLionel Sambuc using namespace clang; 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc Module::ExportDecl 39*f4a2713aSLionel Sambuc ModuleMap::resolveExport(Module *Mod, 40*f4a2713aSLionel Sambuc const Module::UnresolvedExportDecl &Unresolved, 41*f4a2713aSLionel Sambuc bool Complain) const { 42*f4a2713aSLionel Sambuc // We may have just a wildcard. 43*f4a2713aSLionel Sambuc if (Unresolved.Id.empty()) { 44*f4a2713aSLionel Sambuc assert(Unresolved.Wildcard && "Invalid unresolved export"); 45*f4a2713aSLionel Sambuc return Module::ExportDecl(0, true); 46*f4a2713aSLionel Sambuc } 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc // Resolve the module-id. 49*f4a2713aSLionel Sambuc Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 50*f4a2713aSLionel Sambuc if (!Context) 51*f4a2713aSLionel Sambuc return Module::ExportDecl(); 52*f4a2713aSLionel Sambuc 53*f4a2713aSLionel Sambuc return Module::ExportDecl(Context, Unresolved.Wildcard); 54*f4a2713aSLionel Sambuc } 55*f4a2713aSLionel Sambuc 56*f4a2713aSLionel Sambuc Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 57*f4a2713aSLionel Sambuc bool Complain) const { 58*f4a2713aSLionel Sambuc // Find the starting module. 59*f4a2713aSLionel Sambuc Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 60*f4a2713aSLionel Sambuc if (!Context) { 61*f4a2713aSLionel Sambuc if (Complain) 62*f4a2713aSLionel Sambuc Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 63*f4a2713aSLionel Sambuc << Id[0].first << Mod->getFullModuleName(); 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc return 0; 66*f4a2713aSLionel Sambuc } 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc // Dig into the module path. 69*f4a2713aSLionel Sambuc for (unsigned I = 1, N = Id.size(); I != N; ++I) { 70*f4a2713aSLionel Sambuc Module *Sub = lookupModuleQualified(Id[I].first, Context); 71*f4a2713aSLionel Sambuc if (!Sub) { 72*f4a2713aSLionel Sambuc if (Complain) 73*f4a2713aSLionel Sambuc Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified) 74*f4a2713aSLionel Sambuc << Id[I].first << Context->getFullModuleName() 75*f4a2713aSLionel Sambuc << SourceRange(Id[0].second, Id[I-1].second); 76*f4a2713aSLionel Sambuc 77*f4a2713aSLionel Sambuc return 0; 78*f4a2713aSLionel Sambuc } 79*f4a2713aSLionel Sambuc 80*f4a2713aSLionel Sambuc Context = Sub; 81*f4a2713aSLionel Sambuc } 82*f4a2713aSLionel Sambuc 83*f4a2713aSLionel Sambuc return Context; 84*f4a2713aSLionel Sambuc } 85*f4a2713aSLionel Sambuc 86*f4a2713aSLionel Sambuc ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC, 87*f4a2713aSLionel Sambuc const LangOptions &LangOpts, const TargetInfo *Target, 88*f4a2713aSLionel Sambuc HeaderSearch &HeaderInfo) 89*f4a2713aSLionel Sambuc : SourceMgr(SourceMgr), LangOpts(LangOpts), Target(Target), 90*f4a2713aSLionel Sambuc HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0), 91*f4a2713aSLionel Sambuc SourceModule(0) { 92*f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 93*f4a2713aSLionel Sambuc Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( 94*f4a2713aSLionel Sambuc new DiagnosticsEngine(DiagIDs, new DiagnosticOptions)); 95*f4a2713aSLionel Sambuc Diags->setClient(new ForwardingDiagnosticConsumer(DC), 96*f4a2713aSLionel Sambuc /*ShouldOwnClient=*/true); 97*f4a2713aSLionel Sambuc Diags->setSourceManager(&SourceMgr); 98*f4a2713aSLionel Sambuc } 99*f4a2713aSLionel Sambuc 100*f4a2713aSLionel Sambuc ModuleMap::~ModuleMap() { 101*f4a2713aSLionel Sambuc for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 102*f4a2713aSLionel Sambuc IEnd = Modules.end(); 103*f4a2713aSLionel Sambuc I != IEnd; ++I) { 104*f4a2713aSLionel Sambuc delete I->getValue(); 105*f4a2713aSLionel Sambuc } 106*f4a2713aSLionel Sambuc } 107*f4a2713aSLionel Sambuc 108*f4a2713aSLionel Sambuc void ModuleMap::setTarget(const TargetInfo &Target) { 109*f4a2713aSLionel Sambuc assert((!this->Target || this->Target == &Target) && 110*f4a2713aSLionel Sambuc "Improper target override"); 111*f4a2713aSLionel Sambuc this->Target = &Target; 112*f4a2713aSLionel Sambuc } 113*f4a2713aSLionel Sambuc 114*f4a2713aSLionel Sambuc /// \brief "Sanitize" a filename so that it can be used as an identifier. 115*f4a2713aSLionel Sambuc static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 116*f4a2713aSLionel Sambuc SmallVectorImpl<char> &Buffer) { 117*f4a2713aSLionel Sambuc if (Name.empty()) 118*f4a2713aSLionel Sambuc return Name; 119*f4a2713aSLionel Sambuc 120*f4a2713aSLionel Sambuc if (!isValidIdentifier(Name)) { 121*f4a2713aSLionel Sambuc // If we don't already have something with the form of an identifier, 122*f4a2713aSLionel Sambuc // create a buffer with the sanitized name. 123*f4a2713aSLionel Sambuc Buffer.clear(); 124*f4a2713aSLionel Sambuc if (isDigit(Name[0])) 125*f4a2713aSLionel Sambuc Buffer.push_back('_'); 126*f4a2713aSLionel Sambuc Buffer.reserve(Buffer.size() + Name.size()); 127*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Name.size(); I != N; ++I) { 128*f4a2713aSLionel Sambuc if (isIdentifierBody(Name[I])) 129*f4a2713aSLionel Sambuc Buffer.push_back(Name[I]); 130*f4a2713aSLionel Sambuc else 131*f4a2713aSLionel Sambuc Buffer.push_back('_'); 132*f4a2713aSLionel Sambuc } 133*f4a2713aSLionel Sambuc 134*f4a2713aSLionel Sambuc Name = StringRef(Buffer.data(), Buffer.size()); 135*f4a2713aSLionel Sambuc } 136*f4a2713aSLionel Sambuc 137*f4a2713aSLionel Sambuc while (llvm::StringSwitch<bool>(Name) 138*f4a2713aSLionel Sambuc #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 139*f4a2713aSLionel Sambuc #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 140*f4a2713aSLionel Sambuc #include "clang/Basic/TokenKinds.def" 141*f4a2713aSLionel Sambuc .Default(false)) { 142*f4a2713aSLionel Sambuc if (Name.data() != Buffer.data()) 143*f4a2713aSLionel Sambuc Buffer.append(Name.begin(), Name.end()); 144*f4a2713aSLionel Sambuc Buffer.push_back('_'); 145*f4a2713aSLionel Sambuc Name = StringRef(Buffer.data(), Buffer.size()); 146*f4a2713aSLionel Sambuc } 147*f4a2713aSLionel Sambuc 148*f4a2713aSLionel Sambuc return Name; 149*f4a2713aSLionel Sambuc } 150*f4a2713aSLionel Sambuc 151*f4a2713aSLionel Sambuc /// \brief Determine whether the given file name is the name of a builtin 152*f4a2713aSLionel Sambuc /// header, supplied by Clang to replace, override, or augment existing system 153*f4a2713aSLionel Sambuc /// headers. 154*f4a2713aSLionel Sambuc static bool isBuiltinHeader(StringRef FileName) { 155*f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(FileName) 156*f4a2713aSLionel Sambuc .Case("float.h", true) 157*f4a2713aSLionel Sambuc .Case("iso646.h", true) 158*f4a2713aSLionel Sambuc .Case("limits.h", true) 159*f4a2713aSLionel Sambuc .Case("stdalign.h", true) 160*f4a2713aSLionel Sambuc .Case("stdarg.h", true) 161*f4a2713aSLionel Sambuc .Case("stdbool.h", true) 162*f4a2713aSLionel Sambuc .Case("stddef.h", true) 163*f4a2713aSLionel Sambuc .Case("stdint.h", true) 164*f4a2713aSLionel Sambuc .Case("tgmath.h", true) 165*f4a2713aSLionel Sambuc .Case("unwind.h", true) 166*f4a2713aSLionel Sambuc .Default(false); 167*f4a2713aSLionel Sambuc } 168*f4a2713aSLionel Sambuc 169*f4a2713aSLionel Sambuc ModuleMap::KnownHeader 170*f4a2713aSLionel Sambuc ModuleMap::findModuleForHeader(const FileEntry *File, 171*f4a2713aSLionel Sambuc Module *RequestingModule) { 172*f4a2713aSLionel Sambuc HeadersMap::iterator Known = Headers.find(File); 173*f4a2713aSLionel Sambuc if (Known != Headers.end()) { 174*f4a2713aSLionel Sambuc ModuleMap::KnownHeader Result = KnownHeader(); 175*f4a2713aSLionel Sambuc 176*f4a2713aSLionel Sambuc // Iterate over all modules that 'File' is part of to find the best fit. 177*f4a2713aSLionel Sambuc for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 178*f4a2713aSLionel Sambuc E = Known->second.end(); 179*f4a2713aSLionel Sambuc I != E; ++I) { 180*f4a2713aSLionel Sambuc // Cannot use a module if the header is excluded or unavailable in it. 181*f4a2713aSLionel Sambuc if (I->getRole() == ModuleMap::ExcludedHeader || 182*f4a2713aSLionel Sambuc !I->getModule()->isAvailable()) 183*f4a2713aSLionel Sambuc continue; 184*f4a2713aSLionel Sambuc 185*f4a2713aSLionel Sambuc // If 'File' is part of 'RequestingModule', 'RequestingModule' is the 186*f4a2713aSLionel Sambuc // module we are looking for. 187*f4a2713aSLionel Sambuc if (I->getModule() == RequestingModule) 188*f4a2713aSLionel Sambuc return *I; 189*f4a2713aSLionel Sambuc 190*f4a2713aSLionel Sambuc // If uses need to be specified explicitly, we are only allowed to return 191*f4a2713aSLionel Sambuc // modules that are explicitly used by the requesting module. 192*f4a2713aSLionel Sambuc if (RequestingModule && LangOpts.ModulesDeclUse && 193*f4a2713aSLionel Sambuc std::find(RequestingModule->DirectUses.begin(), 194*f4a2713aSLionel Sambuc RequestingModule->DirectUses.end(), 195*f4a2713aSLionel Sambuc I->getModule()) == RequestingModule->DirectUses.end()) 196*f4a2713aSLionel Sambuc continue; 197*f4a2713aSLionel Sambuc Result = *I; 198*f4a2713aSLionel Sambuc // If 'File' is a public header of this module, this is as good as we 199*f4a2713aSLionel Sambuc // are going to get. 200*f4a2713aSLionel Sambuc if (I->getRole() == ModuleMap::NormalHeader) 201*f4a2713aSLionel Sambuc break; 202*f4a2713aSLionel Sambuc } 203*f4a2713aSLionel Sambuc return Result; 204*f4a2713aSLionel Sambuc } 205*f4a2713aSLionel Sambuc 206*f4a2713aSLionel Sambuc // If we've found a builtin header within Clang's builtin include directory, 207*f4a2713aSLionel Sambuc // load all of the module maps to see if it will get associated with a 208*f4a2713aSLionel Sambuc // specific module (e.g., in /usr/include). 209*f4a2713aSLionel Sambuc if (File->getDir() == BuiltinIncludeDir && 210*f4a2713aSLionel Sambuc isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 211*f4a2713aSLionel Sambuc HeaderInfo.loadTopLevelSystemModules(); 212*f4a2713aSLionel Sambuc 213*f4a2713aSLionel Sambuc // Check again. 214*f4a2713aSLionel Sambuc if (Headers.find(File) != Headers.end()) 215*f4a2713aSLionel Sambuc return findModuleForHeader(File, RequestingModule); 216*f4a2713aSLionel Sambuc } 217*f4a2713aSLionel Sambuc 218*f4a2713aSLionel Sambuc const DirectoryEntry *Dir = File->getDir(); 219*f4a2713aSLionel Sambuc SmallVector<const DirectoryEntry *, 2> SkippedDirs; 220*f4a2713aSLionel Sambuc 221*f4a2713aSLionel Sambuc // Note: as an egregious but useful hack we use the real path here, because 222*f4a2713aSLionel Sambuc // frameworks moving from top-level frameworks to embedded frameworks tend 223*f4a2713aSLionel Sambuc // to be symlinked from the top-level location to the embedded location, 224*f4a2713aSLionel Sambuc // and we need to resolve lookups as if we had found the embedded location. 225*f4a2713aSLionel Sambuc StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel Sambuc // Keep walking up the directory hierarchy, looking for a directory with 228*f4a2713aSLionel Sambuc // an umbrella header. 229*f4a2713aSLionel Sambuc do { 230*f4a2713aSLionel Sambuc llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 231*f4a2713aSLionel Sambuc = UmbrellaDirs.find(Dir); 232*f4a2713aSLionel Sambuc if (KnownDir != UmbrellaDirs.end()) { 233*f4a2713aSLionel Sambuc Module *Result = KnownDir->second; 234*f4a2713aSLionel Sambuc 235*f4a2713aSLionel Sambuc // Search up the module stack until we find a module with an umbrella 236*f4a2713aSLionel Sambuc // directory. 237*f4a2713aSLionel Sambuc Module *UmbrellaModule = Result; 238*f4a2713aSLionel Sambuc while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 239*f4a2713aSLionel Sambuc UmbrellaModule = UmbrellaModule->Parent; 240*f4a2713aSLionel Sambuc 241*f4a2713aSLionel Sambuc if (UmbrellaModule->InferSubmodules) { 242*f4a2713aSLionel Sambuc // Infer submodules for each of the directories we found between 243*f4a2713aSLionel Sambuc // the directory of the umbrella header and the directory where 244*f4a2713aSLionel Sambuc // the actual header is located. 245*f4a2713aSLionel Sambuc bool Explicit = UmbrellaModule->InferExplicitSubmodules; 246*f4a2713aSLionel Sambuc 247*f4a2713aSLionel Sambuc for (unsigned I = SkippedDirs.size(); I != 0; --I) { 248*f4a2713aSLionel Sambuc // Find or create the module that corresponds to this directory name. 249*f4a2713aSLionel Sambuc SmallString<32> NameBuf; 250*f4a2713aSLionel Sambuc StringRef Name = sanitizeFilenameAsIdentifier( 251*f4a2713aSLionel Sambuc llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 252*f4a2713aSLionel Sambuc NameBuf); 253*f4a2713aSLionel Sambuc Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 254*f4a2713aSLionel Sambuc Explicit).first; 255*f4a2713aSLionel Sambuc 256*f4a2713aSLionel Sambuc // Associate the module and the directory. 257*f4a2713aSLionel Sambuc UmbrellaDirs[SkippedDirs[I-1]] = Result; 258*f4a2713aSLionel Sambuc 259*f4a2713aSLionel Sambuc // If inferred submodules export everything they import, add a 260*f4a2713aSLionel Sambuc // wildcard to the set of exports. 261*f4a2713aSLionel Sambuc if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 262*f4a2713aSLionel Sambuc Result->Exports.push_back(Module::ExportDecl(0, true)); 263*f4a2713aSLionel Sambuc } 264*f4a2713aSLionel Sambuc 265*f4a2713aSLionel Sambuc // Infer a submodule with the same name as this header file. 266*f4a2713aSLionel Sambuc SmallString<32> NameBuf; 267*f4a2713aSLionel Sambuc StringRef Name = sanitizeFilenameAsIdentifier( 268*f4a2713aSLionel Sambuc llvm::sys::path::stem(File->getName()), NameBuf); 269*f4a2713aSLionel Sambuc Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 270*f4a2713aSLionel Sambuc Explicit).first; 271*f4a2713aSLionel Sambuc Result->addTopHeader(File); 272*f4a2713aSLionel Sambuc 273*f4a2713aSLionel Sambuc // If inferred submodules export everything they import, add a 274*f4a2713aSLionel Sambuc // wildcard to the set of exports. 275*f4a2713aSLionel Sambuc if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 276*f4a2713aSLionel Sambuc Result->Exports.push_back(Module::ExportDecl(0, true)); 277*f4a2713aSLionel Sambuc } else { 278*f4a2713aSLionel Sambuc // Record each of the directories we stepped through as being part of 279*f4a2713aSLionel Sambuc // the module we found, since the umbrella header covers them all. 280*f4a2713aSLionel Sambuc for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 281*f4a2713aSLionel Sambuc UmbrellaDirs[SkippedDirs[I]] = Result; 282*f4a2713aSLionel Sambuc } 283*f4a2713aSLionel Sambuc 284*f4a2713aSLionel Sambuc Headers[File].push_back(KnownHeader(Result, NormalHeader)); 285*f4a2713aSLionel Sambuc 286*f4a2713aSLionel Sambuc // If a header corresponds to an unavailable module, don't report 287*f4a2713aSLionel Sambuc // that it maps to anything. 288*f4a2713aSLionel Sambuc if (!Result->isAvailable()) 289*f4a2713aSLionel Sambuc return KnownHeader(); 290*f4a2713aSLionel Sambuc 291*f4a2713aSLionel Sambuc return Headers[File].back(); 292*f4a2713aSLionel Sambuc } 293*f4a2713aSLionel Sambuc 294*f4a2713aSLionel Sambuc SkippedDirs.push_back(Dir); 295*f4a2713aSLionel Sambuc 296*f4a2713aSLionel Sambuc // Retrieve our parent path. 297*f4a2713aSLionel Sambuc DirName = llvm::sys::path::parent_path(DirName); 298*f4a2713aSLionel Sambuc if (DirName.empty()) 299*f4a2713aSLionel Sambuc break; 300*f4a2713aSLionel Sambuc 301*f4a2713aSLionel Sambuc // Resolve the parent path to a directory entry. 302*f4a2713aSLionel Sambuc Dir = SourceMgr.getFileManager().getDirectory(DirName); 303*f4a2713aSLionel Sambuc } while (Dir); 304*f4a2713aSLionel Sambuc 305*f4a2713aSLionel Sambuc return KnownHeader(); 306*f4a2713aSLionel Sambuc } 307*f4a2713aSLionel Sambuc 308*f4a2713aSLionel Sambuc bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 309*f4a2713aSLionel Sambuc HeadersMap::const_iterator Known = Headers.find(Header); 310*f4a2713aSLionel Sambuc if (Known != Headers.end()) { 311*f4a2713aSLionel Sambuc for (SmallVectorImpl<KnownHeader>::const_iterator 312*f4a2713aSLionel Sambuc I = Known->second.begin(), 313*f4a2713aSLionel Sambuc E = Known->second.end(); 314*f4a2713aSLionel Sambuc I != E; ++I) { 315*f4a2713aSLionel Sambuc if (I->isAvailable()) 316*f4a2713aSLionel Sambuc return false; 317*f4a2713aSLionel Sambuc } 318*f4a2713aSLionel Sambuc return true; 319*f4a2713aSLionel Sambuc } 320*f4a2713aSLionel Sambuc 321*f4a2713aSLionel Sambuc const DirectoryEntry *Dir = Header->getDir(); 322*f4a2713aSLionel Sambuc SmallVector<const DirectoryEntry *, 2> SkippedDirs; 323*f4a2713aSLionel Sambuc StringRef DirName = Dir->getName(); 324*f4a2713aSLionel Sambuc 325*f4a2713aSLionel Sambuc // Keep walking up the directory hierarchy, looking for a directory with 326*f4a2713aSLionel Sambuc // an umbrella header. 327*f4a2713aSLionel Sambuc do { 328*f4a2713aSLionel Sambuc llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 329*f4a2713aSLionel Sambuc = UmbrellaDirs.find(Dir); 330*f4a2713aSLionel Sambuc if (KnownDir != UmbrellaDirs.end()) { 331*f4a2713aSLionel Sambuc Module *Found = KnownDir->second; 332*f4a2713aSLionel Sambuc if (!Found->isAvailable()) 333*f4a2713aSLionel Sambuc return true; 334*f4a2713aSLionel Sambuc 335*f4a2713aSLionel Sambuc // Search up the module stack until we find a module with an umbrella 336*f4a2713aSLionel Sambuc // directory. 337*f4a2713aSLionel Sambuc Module *UmbrellaModule = Found; 338*f4a2713aSLionel Sambuc while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 339*f4a2713aSLionel Sambuc UmbrellaModule = UmbrellaModule->Parent; 340*f4a2713aSLionel Sambuc 341*f4a2713aSLionel Sambuc if (UmbrellaModule->InferSubmodules) { 342*f4a2713aSLionel Sambuc for (unsigned I = SkippedDirs.size(); I != 0; --I) { 343*f4a2713aSLionel Sambuc // Find or create the module that corresponds to this directory name. 344*f4a2713aSLionel Sambuc SmallString<32> NameBuf; 345*f4a2713aSLionel Sambuc StringRef Name = sanitizeFilenameAsIdentifier( 346*f4a2713aSLionel Sambuc llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 347*f4a2713aSLionel Sambuc NameBuf); 348*f4a2713aSLionel Sambuc Found = lookupModuleQualified(Name, Found); 349*f4a2713aSLionel Sambuc if (!Found) 350*f4a2713aSLionel Sambuc return false; 351*f4a2713aSLionel Sambuc if (!Found->isAvailable()) 352*f4a2713aSLionel Sambuc return true; 353*f4a2713aSLionel Sambuc } 354*f4a2713aSLionel Sambuc 355*f4a2713aSLionel Sambuc // Infer a submodule with the same name as this header file. 356*f4a2713aSLionel Sambuc SmallString<32> NameBuf; 357*f4a2713aSLionel Sambuc StringRef Name = sanitizeFilenameAsIdentifier( 358*f4a2713aSLionel Sambuc llvm::sys::path::stem(Header->getName()), 359*f4a2713aSLionel Sambuc NameBuf); 360*f4a2713aSLionel Sambuc Found = lookupModuleQualified(Name, Found); 361*f4a2713aSLionel Sambuc if (!Found) 362*f4a2713aSLionel Sambuc return false; 363*f4a2713aSLionel Sambuc } 364*f4a2713aSLionel Sambuc 365*f4a2713aSLionel Sambuc return !Found->isAvailable(); 366*f4a2713aSLionel Sambuc } 367*f4a2713aSLionel Sambuc 368*f4a2713aSLionel Sambuc SkippedDirs.push_back(Dir); 369*f4a2713aSLionel Sambuc 370*f4a2713aSLionel Sambuc // Retrieve our parent path. 371*f4a2713aSLionel Sambuc DirName = llvm::sys::path::parent_path(DirName); 372*f4a2713aSLionel Sambuc if (DirName.empty()) 373*f4a2713aSLionel Sambuc break; 374*f4a2713aSLionel Sambuc 375*f4a2713aSLionel Sambuc // Resolve the parent path to a directory entry. 376*f4a2713aSLionel Sambuc Dir = SourceMgr.getFileManager().getDirectory(DirName); 377*f4a2713aSLionel Sambuc } while (Dir); 378*f4a2713aSLionel Sambuc 379*f4a2713aSLionel Sambuc return false; 380*f4a2713aSLionel Sambuc } 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambuc Module *ModuleMap::findModule(StringRef Name) const { 383*f4a2713aSLionel Sambuc llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 384*f4a2713aSLionel Sambuc if (Known != Modules.end()) 385*f4a2713aSLionel Sambuc return Known->getValue(); 386*f4a2713aSLionel Sambuc 387*f4a2713aSLionel Sambuc return 0; 388*f4a2713aSLionel Sambuc } 389*f4a2713aSLionel Sambuc 390*f4a2713aSLionel Sambuc Module *ModuleMap::lookupModuleUnqualified(StringRef Name, 391*f4a2713aSLionel Sambuc Module *Context) const { 392*f4a2713aSLionel Sambuc for(; Context; Context = Context->Parent) { 393*f4a2713aSLionel Sambuc if (Module *Sub = lookupModuleQualified(Name, Context)) 394*f4a2713aSLionel Sambuc return Sub; 395*f4a2713aSLionel Sambuc } 396*f4a2713aSLionel Sambuc 397*f4a2713aSLionel Sambuc return findModule(Name); 398*f4a2713aSLionel Sambuc } 399*f4a2713aSLionel Sambuc 400*f4a2713aSLionel Sambuc Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 401*f4a2713aSLionel Sambuc if (!Context) 402*f4a2713aSLionel Sambuc return findModule(Name); 403*f4a2713aSLionel Sambuc 404*f4a2713aSLionel Sambuc return Context->findSubmodule(Name); 405*f4a2713aSLionel Sambuc } 406*f4a2713aSLionel Sambuc 407*f4a2713aSLionel Sambuc std::pair<Module *, bool> 408*f4a2713aSLionel Sambuc ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 409*f4a2713aSLionel Sambuc bool IsExplicit) { 410*f4a2713aSLionel Sambuc // Try to find an existing module with this name. 411*f4a2713aSLionel Sambuc if (Module *Sub = lookupModuleQualified(Name, Parent)) 412*f4a2713aSLionel Sambuc return std::make_pair(Sub, false); 413*f4a2713aSLionel Sambuc 414*f4a2713aSLionel Sambuc // Create a new module with this name. 415*f4a2713aSLionel Sambuc Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 416*f4a2713aSLionel Sambuc IsExplicit); 417*f4a2713aSLionel Sambuc if (LangOpts.CurrentModule == Name) { 418*f4a2713aSLionel Sambuc SourceModule = Result; 419*f4a2713aSLionel Sambuc SourceModuleName = Name; 420*f4a2713aSLionel Sambuc } 421*f4a2713aSLionel Sambuc if (!Parent) { 422*f4a2713aSLionel Sambuc Modules[Name] = Result; 423*f4a2713aSLionel Sambuc if (!LangOpts.CurrentModule.empty() && !CompilingModule && 424*f4a2713aSLionel Sambuc Name == LangOpts.CurrentModule) { 425*f4a2713aSLionel Sambuc CompilingModule = Result; 426*f4a2713aSLionel Sambuc } 427*f4a2713aSLionel Sambuc } 428*f4a2713aSLionel Sambuc return std::make_pair(Result, true); 429*f4a2713aSLionel Sambuc } 430*f4a2713aSLionel Sambuc 431*f4a2713aSLionel Sambuc bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 432*f4a2713aSLionel Sambuc StringRef Name, bool &IsSystem) const { 433*f4a2713aSLionel Sambuc // Check whether we have already looked into the parent directory 434*f4a2713aSLionel Sambuc // for a module map. 435*f4a2713aSLionel Sambuc llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 436*f4a2713aSLionel Sambuc inferred = InferredDirectories.find(ParentDir); 437*f4a2713aSLionel Sambuc if (inferred == InferredDirectories.end()) 438*f4a2713aSLionel Sambuc return false; 439*f4a2713aSLionel Sambuc 440*f4a2713aSLionel Sambuc if (!inferred->second.InferModules) 441*f4a2713aSLionel Sambuc return false; 442*f4a2713aSLionel Sambuc 443*f4a2713aSLionel Sambuc // We're allowed to infer for this directory, but make sure it's okay 444*f4a2713aSLionel Sambuc // to infer this particular module. 445*f4a2713aSLionel Sambuc bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 446*f4a2713aSLionel Sambuc inferred->second.ExcludedModules.end(), 447*f4a2713aSLionel Sambuc Name) == inferred->second.ExcludedModules.end(); 448*f4a2713aSLionel Sambuc 449*f4a2713aSLionel Sambuc if (canInfer && inferred->second.InferSystemModules) 450*f4a2713aSLionel Sambuc IsSystem = true; 451*f4a2713aSLionel Sambuc 452*f4a2713aSLionel Sambuc return canInfer; 453*f4a2713aSLionel Sambuc } 454*f4a2713aSLionel Sambuc 455*f4a2713aSLionel Sambuc /// \brief For a framework module, infer the framework against which we 456*f4a2713aSLionel Sambuc /// should link. 457*f4a2713aSLionel Sambuc static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 458*f4a2713aSLionel Sambuc FileManager &FileMgr) { 459*f4a2713aSLionel Sambuc assert(Mod->IsFramework && "Can only infer linking for framework modules"); 460*f4a2713aSLionel Sambuc assert(!Mod->isSubFramework() && 461*f4a2713aSLionel Sambuc "Can only infer linking for top-level frameworks"); 462*f4a2713aSLionel Sambuc 463*f4a2713aSLionel Sambuc SmallString<128> LibName; 464*f4a2713aSLionel Sambuc LibName += FrameworkDir->getName(); 465*f4a2713aSLionel Sambuc llvm::sys::path::append(LibName, Mod->Name); 466*f4a2713aSLionel Sambuc if (FileMgr.getFile(LibName)) { 467*f4a2713aSLionel Sambuc Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 468*f4a2713aSLionel Sambuc /*IsFramework=*/true)); 469*f4a2713aSLionel Sambuc } 470*f4a2713aSLionel Sambuc } 471*f4a2713aSLionel Sambuc 472*f4a2713aSLionel Sambuc Module * 473*f4a2713aSLionel Sambuc ModuleMap::inferFrameworkModule(StringRef ModuleName, 474*f4a2713aSLionel Sambuc const DirectoryEntry *FrameworkDir, 475*f4a2713aSLionel Sambuc bool IsSystem, 476*f4a2713aSLionel Sambuc Module *Parent) { 477*f4a2713aSLionel Sambuc // Check whether we've already found this module. 478*f4a2713aSLionel Sambuc if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 479*f4a2713aSLionel Sambuc return Mod; 480*f4a2713aSLionel Sambuc 481*f4a2713aSLionel Sambuc FileManager &FileMgr = SourceMgr.getFileManager(); 482*f4a2713aSLionel Sambuc 483*f4a2713aSLionel Sambuc // If the framework has a parent path from which we're allowed to infer 484*f4a2713aSLionel Sambuc // a framework module, do so. 485*f4a2713aSLionel Sambuc if (!Parent) { 486*f4a2713aSLionel Sambuc // Determine whether we're allowed to infer a module map. 487*f4a2713aSLionel Sambuc 488*f4a2713aSLionel Sambuc // Note: as an egregious but useful hack we use the real path here, because 489*f4a2713aSLionel Sambuc // we might be looking at an embedded framework that symlinks out to a 490*f4a2713aSLionel Sambuc // top-level framework, and we need to infer as if we were naming the 491*f4a2713aSLionel Sambuc // top-level framework. 492*f4a2713aSLionel Sambuc StringRef FrameworkDirName 493*f4a2713aSLionel Sambuc = SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 494*f4a2713aSLionel Sambuc 495*f4a2713aSLionel Sambuc bool canInfer = false; 496*f4a2713aSLionel Sambuc if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 497*f4a2713aSLionel Sambuc // Figure out the parent path. 498*f4a2713aSLionel Sambuc StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 499*f4a2713aSLionel Sambuc if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 500*f4a2713aSLionel Sambuc // Check whether we have already looked into the parent directory 501*f4a2713aSLionel Sambuc // for a module map. 502*f4a2713aSLionel Sambuc llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 503*f4a2713aSLionel Sambuc inferred = InferredDirectories.find(ParentDir); 504*f4a2713aSLionel Sambuc if (inferred == InferredDirectories.end()) { 505*f4a2713aSLionel Sambuc // We haven't looked here before. Load a module map, if there is 506*f4a2713aSLionel Sambuc // one. 507*f4a2713aSLionel Sambuc SmallString<128> ModMapPath = Parent; 508*f4a2713aSLionel Sambuc llvm::sys::path::append(ModMapPath, "module.map"); 509*f4a2713aSLionel Sambuc if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) { 510*f4a2713aSLionel Sambuc parseModuleMapFile(ModMapFile, IsSystem); 511*f4a2713aSLionel Sambuc inferred = InferredDirectories.find(ParentDir); 512*f4a2713aSLionel Sambuc } 513*f4a2713aSLionel Sambuc 514*f4a2713aSLionel Sambuc if (inferred == InferredDirectories.end()) 515*f4a2713aSLionel Sambuc inferred = InferredDirectories.insert( 516*f4a2713aSLionel Sambuc std::make_pair(ParentDir, InferredDirectory())).first; 517*f4a2713aSLionel Sambuc } 518*f4a2713aSLionel Sambuc 519*f4a2713aSLionel Sambuc if (inferred->second.InferModules) { 520*f4a2713aSLionel Sambuc // We're allowed to infer for this directory, but make sure it's okay 521*f4a2713aSLionel Sambuc // to infer this particular module. 522*f4a2713aSLionel Sambuc StringRef Name = llvm::sys::path::stem(FrameworkDirName); 523*f4a2713aSLionel Sambuc canInfer = std::find(inferred->second.ExcludedModules.begin(), 524*f4a2713aSLionel Sambuc inferred->second.ExcludedModules.end(), 525*f4a2713aSLionel Sambuc Name) == inferred->second.ExcludedModules.end(); 526*f4a2713aSLionel Sambuc 527*f4a2713aSLionel Sambuc if (inferred->second.InferSystemModules) 528*f4a2713aSLionel Sambuc IsSystem = true; 529*f4a2713aSLionel Sambuc } 530*f4a2713aSLionel Sambuc } 531*f4a2713aSLionel Sambuc } 532*f4a2713aSLionel Sambuc 533*f4a2713aSLionel Sambuc // If we're not allowed to infer a framework module, don't. 534*f4a2713aSLionel Sambuc if (!canInfer) 535*f4a2713aSLionel Sambuc return 0; 536*f4a2713aSLionel Sambuc } 537*f4a2713aSLionel Sambuc 538*f4a2713aSLionel Sambuc 539*f4a2713aSLionel Sambuc // Look for an umbrella header. 540*f4a2713aSLionel Sambuc SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 541*f4a2713aSLionel Sambuc llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 542*f4a2713aSLionel Sambuc const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 543*f4a2713aSLionel Sambuc 544*f4a2713aSLionel Sambuc // FIXME: If there's no umbrella header, we could probably scan the 545*f4a2713aSLionel Sambuc // framework to load *everything*. But, it's not clear that this is a good 546*f4a2713aSLionel Sambuc // idea. 547*f4a2713aSLionel Sambuc if (!UmbrellaHeader) 548*f4a2713aSLionel Sambuc return 0; 549*f4a2713aSLionel Sambuc 550*f4a2713aSLionel Sambuc Module *Result = new Module(ModuleName, SourceLocation(), Parent, 551*f4a2713aSLionel Sambuc /*IsFramework=*/true, /*IsExplicit=*/false); 552*f4a2713aSLionel Sambuc if (LangOpts.CurrentModule == ModuleName) { 553*f4a2713aSLionel Sambuc SourceModule = Result; 554*f4a2713aSLionel Sambuc SourceModuleName = ModuleName; 555*f4a2713aSLionel Sambuc } 556*f4a2713aSLionel Sambuc if (IsSystem) 557*f4a2713aSLionel Sambuc Result->IsSystem = IsSystem; 558*f4a2713aSLionel Sambuc 559*f4a2713aSLionel Sambuc if (!Parent) 560*f4a2713aSLionel Sambuc Modules[ModuleName] = Result; 561*f4a2713aSLionel Sambuc 562*f4a2713aSLionel Sambuc // umbrella header "umbrella-header-name" 563*f4a2713aSLionel Sambuc Result->Umbrella = UmbrellaHeader; 564*f4a2713aSLionel Sambuc Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); 565*f4a2713aSLionel Sambuc UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 566*f4a2713aSLionel Sambuc 567*f4a2713aSLionel Sambuc // export * 568*f4a2713aSLionel Sambuc Result->Exports.push_back(Module::ExportDecl(0, true)); 569*f4a2713aSLionel Sambuc 570*f4a2713aSLionel Sambuc // module * { export * } 571*f4a2713aSLionel Sambuc Result->InferSubmodules = true; 572*f4a2713aSLionel Sambuc Result->InferExportWildcard = true; 573*f4a2713aSLionel Sambuc 574*f4a2713aSLionel Sambuc // Look for subframeworks. 575*f4a2713aSLionel Sambuc llvm::error_code EC; 576*f4a2713aSLionel Sambuc SmallString<128> SubframeworksDirName 577*f4a2713aSLionel Sambuc = StringRef(FrameworkDir->getName()); 578*f4a2713aSLionel Sambuc llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 579*f4a2713aSLionel Sambuc llvm::sys::path::native(SubframeworksDirName); 580*f4a2713aSLionel Sambuc for (llvm::sys::fs::directory_iterator 581*f4a2713aSLionel Sambuc Dir(SubframeworksDirName.str(), EC), DirEnd; 582*f4a2713aSLionel Sambuc Dir != DirEnd && !EC; Dir.increment(EC)) { 583*f4a2713aSLionel Sambuc if (!StringRef(Dir->path()).endswith(".framework")) 584*f4a2713aSLionel Sambuc continue; 585*f4a2713aSLionel Sambuc 586*f4a2713aSLionel Sambuc if (const DirectoryEntry *SubframeworkDir 587*f4a2713aSLionel Sambuc = FileMgr.getDirectory(Dir->path())) { 588*f4a2713aSLionel Sambuc // Note: as an egregious but useful hack, we use the real path here and 589*f4a2713aSLionel Sambuc // check whether it is actually a subdirectory of the parent directory. 590*f4a2713aSLionel Sambuc // This will not be the case if the 'subframework' is actually a symlink 591*f4a2713aSLionel Sambuc // out to a top-level framework. 592*f4a2713aSLionel Sambuc StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 593*f4a2713aSLionel Sambuc bool FoundParent = false; 594*f4a2713aSLionel Sambuc do { 595*f4a2713aSLionel Sambuc // Get the parent directory name. 596*f4a2713aSLionel Sambuc SubframeworkDirName 597*f4a2713aSLionel Sambuc = llvm::sys::path::parent_path(SubframeworkDirName); 598*f4a2713aSLionel Sambuc if (SubframeworkDirName.empty()) 599*f4a2713aSLionel Sambuc break; 600*f4a2713aSLionel Sambuc 601*f4a2713aSLionel Sambuc if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 602*f4a2713aSLionel Sambuc FoundParent = true; 603*f4a2713aSLionel Sambuc break; 604*f4a2713aSLionel Sambuc } 605*f4a2713aSLionel Sambuc } while (true); 606*f4a2713aSLionel Sambuc 607*f4a2713aSLionel Sambuc if (!FoundParent) 608*f4a2713aSLionel Sambuc continue; 609*f4a2713aSLionel Sambuc 610*f4a2713aSLionel Sambuc // FIXME: Do we want to warn about subframeworks without umbrella headers? 611*f4a2713aSLionel Sambuc SmallString<32> NameBuf; 612*f4a2713aSLionel Sambuc inferFrameworkModule(sanitizeFilenameAsIdentifier( 613*f4a2713aSLionel Sambuc llvm::sys::path::stem(Dir->path()), NameBuf), 614*f4a2713aSLionel Sambuc SubframeworkDir, IsSystem, Result); 615*f4a2713aSLionel Sambuc } 616*f4a2713aSLionel Sambuc } 617*f4a2713aSLionel Sambuc 618*f4a2713aSLionel Sambuc // If the module is a top-level framework, automatically link against the 619*f4a2713aSLionel Sambuc // framework. 620*f4a2713aSLionel Sambuc if (!Result->isSubFramework()) { 621*f4a2713aSLionel Sambuc inferFrameworkLink(Result, FrameworkDir, FileMgr); 622*f4a2713aSLionel Sambuc } 623*f4a2713aSLionel Sambuc 624*f4a2713aSLionel Sambuc return Result; 625*f4a2713aSLionel Sambuc } 626*f4a2713aSLionel Sambuc 627*f4a2713aSLionel Sambuc void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 628*f4a2713aSLionel Sambuc Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 629*f4a2713aSLionel Sambuc Mod->Umbrella = UmbrellaHeader; 630*f4a2713aSLionel Sambuc UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 631*f4a2713aSLionel Sambuc } 632*f4a2713aSLionel Sambuc 633*f4a2713aSLionel Sambuc void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 634*f4a2713aSLionel Sambuc Mod->Umbrella = UmbrellaDir; 635*f4a2713aSLionel Sambuc UmbrellaDirs[UmbrellaDir] = Mod; 636*f4a2713aSLionel Sambuc } 637*f4a2713aSLionel Sambuc 638*f4a2713aSLionel Sambuc void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 639*f4a2713aSLionel Sambuc ModuleHeaderRole Role) { 640*f4a2713aSLionel Sambuc if (Role == ExcludedHeader) { 641*f4a2713aSLionel Sambuc Mod->ExcludedHeaders.push_back(Header); 642*f4a2713aSLionel Sambuc } else { 643*f4a2713aSLionel Sambuc if (Role == PrivateHeader) 644*f4a2713aSLionel Sambuc Mod->PrivateHeaders.push_back(Header); 645*f4a2713aSLionel Sambuc else 646*f4a2713aSLionel Sambuc Mod->NormalHeaders.push_back(Header); 647*f4a2713aSLionel Sambuc bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 648*f4a2713aSLionel Sambuc HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); 649*f4a2713aSLionel Sambuc } 650*f4a2713aSLionel Sambuc Headers[Header].push_back(KnownHeader(Mod, Role)); 651*f4a2713aSLionel Sambuc } 652*f4a2713aSLionel Sambuc 653*f4a2713aSLionel Sambuc const FileEntry * 654*f4a2713aSLionel Sambuc ModuleMap::getContainingModuleMapFile(Module *Module) const { 655*f4a2713aSLionel Sambuc if (Module->DefinitionLoc.isInvalid()) 656*f4a2713aSLionel Sambuc return 0; 657*f4a2713aSLionel Sambuc 658*f4a2713aSLionel Sambuc return SourceMgr.getFileEntryForID( 659*f4a2713aSLionel Sambuc SourceMgr.getFileID(Module->DefinitionLoc)); 660*f4a2713aSLionel Sambuc } 661*f4a2713aSLionel Sambuc 662*f4a2713aSLionel Sambuc void ModuleMap::dump() { 663*f4a2713aSLionel Sambuc llvm::errs() << "Modules:"; 664*f4a2713aSLionel Sambuc for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 665*f4a2713aSLionel Sambuc MEnd = Modules.end(); 666*f4a2713aSLionel Sambuc M != MEnd; ++M) 667*f4a2713aSLionel Sambuc M->getValue()->print(llvm::errs(), 2); 668*f4a2713aSLionel Sambuc 669*f4a2713aSLionel Sambuc llvm::errs() << "Headers:"; 670*f4a2713aSLionel Sambuc for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 671*f4a2713aSLionel Sambuc H != HEnd; ++H) { 672*f4a2713aSLionel Sambuc llvm::errs() << " \"" << H->first->getName() << "\" -> "; 673*f4a2713aSLionel Sambuc for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 674*f4a2713aSLionel Sambuc E = H->second.end(); 675*f4a2713aSLionel Sambuc I != E; ++I) { 676*f4a2713aSLionel Sambuc if (I != H->second.begin()) 677*f4a2713aSLionel Sambuc llvm::errs() << ","; 678*f4a2713aSLionel Sambuc llvm::errs() << I->getModule()->getFullModuleName(); 679*f4a2713aSLionel Sambuc } 680*f4a2713aSLionel Sambuc llvm::errs() << "\n"; 681*f4a2713aSLionel Sambuc } 682*f4a2713aSLionel Sambuc } 683*f4a2713aSLionel Sambuc 684*f4a2713aSLionel Sambuc bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 685*f4a2713aSLionel Sambuc bool HadError = false; 686*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 687*f4a2713aSLionel Sambuc Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 688*f4a2713aSLionel Sambuc Complain); 689*f4a2713aSLionel Sambuc if (Export.getPointer() || Export.getInt()) 690*f4a2713aSLionel Sambuc Mod->Exports.push_back(Export); 691*f4a2713aSLionel Sambuc else 692*f4a2713aSLionel Sambuc HadError = true; 693*f4a2713aSLionel Sambuc } 694*f4a2713aSLionel Sambuc Mod->UnresolvedExports.clear(); 695*f4a2713aSLionel Sambuc return HadError; 696*f4a2713aSLionel Sambuc } 697*f4a2713aSLionel Sambuc 698*f4a2713aSLionel Sambuc bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 699*f4a2713aSLionel Sambuc bool HadError = false; 700*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 701*f4a2713aSLionel Sambuc Module *DirectUse = 702*f4a2713aSLionel Sambuc resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 703*f4a2713aSLionel Sambuc if (DirectUse) 704*f4a2713aSLionel Sambuc Mod->DirectUses.push_back(DirectUse); 705*f4a2713aSLionel Sambuc else 706*f4a2713aSLionel Sambuc HadError = true; 707*f4a2713aSLionel Sambuc } 708*f4a2713aSLionel Sambuc Mod->UnresolvedDirectUses.clear(); 709*f4a2713aSLionel Sambuc return HadError; 710*f4a2713aSLionel Sambuc } 711*f4a2713aSLionel Sambuc 712*f4a2713aSLionel Sambuc bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 713*f4a2713aSLionel Sambuc bool HadError = false; 714*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 715*f4a2713aSLionel Sambuc Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 716*f4a2713aSLionel Sambuc Mod, Complain); 717*f4a2713aSLionel Sambuc if (!OtherMod) { 718*f4a2713aSLionel Sambuc HadError = true; 719*f4a2713aSLionel Sambuc continue; 720*f4a2713aSLionel Sambuc } 721*f4a2713aSLionel Sambuc 722*f4a2713aSLionel Sambuc Module::Conflict Conflict; 723*f4a2713aSLionel Sambuc Conflict.Other = OtherMod; 724*f4a2713aSLionel Sambuc Conflict.Message = Mod->UnresolvedConflicts[I].Message; 725*f4a2713aSLionel Sambuc Mod->Conflicts.push_back(Conflict); 726*f4a2713aSLionel Sambuc } 727*f4a2713aSLionel Sambuc Mod->UnresolvedConflicts.clear(); 728*f4a2713aSLionel Sambuc return HadError; 729*f4a2713aSLionel Sambuc } 730*f4a2713aSLionel Sambuc 731*f4a2713aSLionel Sambuc Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 732*f4a2713aSLionel Sambuc if (Loc.isInvalid()) 733*f4a2713aSLionel Sambuc return 0; 734*f4a2713aSLionel Sambuc 735*f4a2713aSLionel Sambuc // Use the expansion location to determine which module we're in. 736*f4a2713aSLionel Sambuc FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 737*f4a2713aSLionel Sambuc if (!ExpansionLoc.isFileID()) 738*f4a2713aSLionel Sambuc return 0; 739*f4a2713aSLionel Sambuc 740*f4a2713aSLionel Sambuc 741*f4a2713aSLionel Sambuc const SourceManager &SrcMgr = Loc.getManager(); 742*f4a2713aSLionel Sambuc FileID ExpansionFileID = ExpansionLoc.getFileID(); 743*f4a2713aSLionel Sambuc 744*f4a2713aSLionel Sambuc while (const FileEntry *ExpansionFile 745*f4a2713aSLionel Sambuc = SrcMgr.getFileEntryForID(ExpansionFileID)) { 746*f4a2713aSLionel Sambuc // Find the module that owns this header (if any). 747*f4a2713aSLionel Sambuc if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 748*f4a2713aSLionel Sambuc return Mod; 749*f4a2713aSLionel Sambuc 750*f4a2713aSLionel Sambuc // No module owns this header, so look up the inclusion chain to see if 751*f4a2713aSLionel Sambuc // any included header has an associated module. 752*f4a2713aSLionel Sambuc SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 753*f4a2713aSLionel Sambuc if (IncludeLoc.isInvalid()) 754*f4a2713aSLionel Sambuc return 0; 755*f4a2713aSLionel Sambuc 756*f4a2713aSLionel Sambuc ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 757*f4a2713aSLionel Sambuc } 758*f4a2713aSLionel Sambuc 759*f4a2713aSLionel Sambuc return 0; 760*f4a2713aSLionel Sambuc } 761*f4a2713aSLionel Sambuc 762*f4a2713aSLionel Sambuc //----------------------------------------------------------------------------// 763*f4a2713aSLionel Sambuc // Module map file parser 764*f4a2713aSLionel Sambuc //----------------------------------------------------------------------------// 765*f4a2713aSLionel Sambuc 766*f4a2713aSLionel Sambuc namespace clang { 767*f4a2713aSLionel Sambuc /// \brief A token in a module map file. 768*f4a2713aSLionel Sambuc struct MMToken { 769*f4a2713aSLionel Sambuc enum TokenKind { 770*f4a2713aSLionel Sambuc Comma, 771*f4a2713aSLionel Sambuc ConfigMacros, 772*f4a2713aSLionel Sambuc Conflict, 773*f4a2713aSLionel Sambuc EndOfFile, 774*f4a2713aSLionel Sambuc HeaderKeyword, 775*f4a2713aSLionel Sambuc Identifier, 776*f4a2713aSLionel Sambuc Exclaim, 777*f4a2713aSLionel Sambuc ExcludeKeyword, 778*f4a2713aSLionel Sambuc ExplicitKeyword, 779*f4a2713aSLionel Sambuc ExportKeyword, 780*f4a2713aSLionel Sambuc ExternKeyword, 781*f4a2713aSLionel Sambuc FrameworkKeyword, 782*f4a2713aSLionel Sambuc LinkKeyword, 783*f4a2713aSLionel Sambuc ModuleKeyword, 784*f4a2713aSLionel Sambuc Period, 785*f4a2713aSLionel Sambuc PrivateKeyword, 786*f4a2713aSLionel Sambuc UmbrellaKeyword, 787*f4a2713aSLionel Sambuc UseKeyword, 788*f4a2713aSLionel Sambuc RequiresKeyword, 789*f4a2713aSLionel Sambuc Star, 790*f4a2713aSLionel Sambuc StringLiteral, 791*f4a2713aSLionel Sambuc LBrace, 792*f4a2713aSLionel Sambuc RBrace, 793*f4a2713aSLionel Sambuc LSquare, 794*f4a2713aSLionel Sambuc RSquare 795*f4a2713aSLionel Sambuc } Kind; 796*f4a2713aSLionel Sambuc 797*f4a2713aSLionel Sambuc unsigned Location; 798*f4a2713aSLionel Sambuc unsigned StringLength; 799*f4a2713aSLionel Sambuc const char *StringData; 800*f4a2713aSLionel Sambuc 801*f4a2713aSLionel Sambuc void clear() { 802*f4a2713aSLionel Sambuc Kind = EndOfFile; 803*f4a2713aSLionel Sambuc Location = 0; 804*f4a2713aSLionel Sambuc StringLength = 0; 805*f4a2713aSLionel Sambuc StringData = 0; 806*f4a2713aSLionel Sambuc } 807*f4a2713aSLionel Sambuc 808*f4a2713aSLionel Sambuc bool is(TokenKind K) const { return Kind == K; } 809*f4a2713aSLionel Sambuc 810*f4a2713aSLionel Sambuc SourceLocation getLocation() const { 811*f4a2713aSLionel Sambuc return SourceLocation::getFromRawEncoding(Location); 812*f4a2713aSLionel Sambuc } 813*f4a2713aSLionel Sambuc 814*f4a2713aSLionel Sambuc StringRef getString() const { 815*f4a2713aSLionel Sambuc return StringRef(StringData, StringLength); 816*f4a2713aSLionel Sambuc } 817*f4a2713aSLionel Sambuc }; 818*f4a2713aSLionel Sambuc 819*f4a2713aSLionel Sambuc /// \brief The set of attributes that can be attached to a module. 820*f4a2713aSLionel Sambuc struct Attributes { 821*f4a2713aSLionel Sambuc Attributes() : IsSystem(), IsExhaustive() { } 822*f4a2713aSLionel Sambuc 823*f4a2713aSLionel Sambuc /// \brief Whether this is a system module. 824*f4a2713aSLionel Sambuc unsigned IsSystem : 1; 825*f4a2713aSLionel Sambuc 826*f4a2713aSLionel Sambuc /// \brief Whether this is an exhaustive set of configuration macros. 827*f4a2713aSLionel Sambuc unsigned IsExhaustive : 1; 828*f4a2713aSLionel Sambuc }; 829*f4a2713aSLionel Sambuc 830*f4a2713aSLionel Sambuc 831*f4a2713aSLionel Sambuc class ModuleMapParser { 832*f4a2713aSLionel Sambuc Lexer &L; 833*f4a2713aSLionel Sambuc SourceManager &SourceMgr; 834*f4a2713aSLionel Sambuc 835*f4a2713aSLionel Sambuc /// \brief Default target information, used only for string literal 836*f4a2713aSLionel Sambuc /// parsing. 837*f4a2713aSLionel Sambuc const TargetInfo *Target; 838*f4a2713aSLionel Sambuc 839*f4a2713aSLionel Sambuc DiagnosticsEngine &Diags; 840*f4a2713aSLionel Sambuc ModuleMap ⤅ 841*f4a2713aSLionel Sambuc 842*f4a2713aSLionel Sambuc /// \brief The directory that this module map resides in. 843*f4a2713aSLionel Sambuc const DirectoryEntry *Directory; 844*f4a2713aSLionel Sambuc 845*f4a2713aSLionel Sambuc /// \brief The directory containing Clang-supplied headers. 846*f4a2713aSLionel Sambuc const DirectoryEntry *BuiltinIncludeDir; 847*f4a2713aSLionel Sambuc 848*f4a2713aSLionel Sambuc /// \brief Whether this module map is in a system header directory. 849*f4a2713aSLionel Sambuc bool IsSystem; 850*f4a2713aSLionel Sambuc 851*f4a2713aSLionel Sambuc /// \brief Whether an error occurred. 852*f4a2713aSLionel Sambuc bool HadError; 853*f4a2713aSLionel Sambuc 854*f4a2713aSLionel Sambuc /// \brief Stores string data for the various string literals referenced 855*f4a2713aSLionel Sambuc /// during parsing. 856*f4a2713aSLionel Sambuc llvm::BumpPtrAllocator StringData; 857*f4a2713aSLionel Sambuc 858*f4a2713aSLionel Sambuc /// \brief The current token. 859*f4a2713aSLionel Sambuc MMToken Tok; 860*f4a2713aSLionel Sambuc 861*f4a2713aSLionel Sambuc /// \brief The active module. 862*f4a2713aSLionel Sambuc Module *ActiveModule; 863*f4a2713aSLionel Sambuc 864*f4a2713aSLionel Sambuc /// \brief Consume the current token and return its location. 865*f4a2713aSLionel Sambuc SourceLocation consumeToken(); 866*f4a2713aSLionel Sambuc 867*f4a2713aSLionel Sambuc /// \brief Skip tokens until we reach the a token with the given kind 868*f4a2713aSLionel Sambuc /// (or the end of the file). 869*f4a2713aSLionel Sambuc void skipUntil(MMToken::TokenKind K); 870*f4a2713aSLionel Sambuc 871*f4a2713aSLionel Sambuc typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 872*f4a2713aSLionel Sambuc bool parseModuleId(ModuleId &Id); 873*f4a2713aSLionel Sambuc void parseModuleDecl(); 874*f4a2713aSLionel Sambuc void parseExternModuleDecl(); 875*f4a2713aSLionel Sambuc void parseRequiresDecl(); 876*f4a2713aSLionel Sambuc void parseHeaderDecl(clang::MMToken::TokenKind, 877*f4a2713aSLionel Sambuc SourceLocation LeadingLoc); 878*f4a2713aSLionel Sambuc void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 879*f4a2713aSLionel Sambuc void parseExportDecl(); 880*f4a2713aSLionel Sambuc void parseUseDecl(); 881*f4a2713aSLionel Sambuc void parseLinkDecl(); 882*f4a2713aSLionel Sambuc void parseConfigMacros(); 883*f4a2713aSLionel Sambuc void parseConflict(); 884*f4a2713aSLionel Sambuc void parseInferredModuleDecl(bool Framework, bool Explicit); 885*f4a2713aSLionel Sambuc bool parseOptionalAttributes(Attributes &Attrs); 886*f4a2713aSLionel Sambuc 887*f4a2713aSLionel Sambuc const DirectoryEntry *getOverriddenHeaderSearchDir(); 888*f4a2713aSLionel Sambuc 889*f4a2713aSLionel Sambuc public: 890*f4a2713aSLionel Sambuc explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 891*f4a2713aSLionel Sambuc const TargetInfo *Target, 892*f4a2713aSLionel Sambuc DiagnosticsEngine &Diags, 893*f4a2713aSLionel Sambuc ModuleMap &Map, 894*f4a2713aSLionel Sambuc const DirectoryEntry *Directory, 895*f4a2713aSLionel Sambuc const DirectoryEntry *BuiltinIncludeDir, 896*f4a2713aSLionel Sambuc bool IsSystem) 897*f4a2713aSLionel Sambuc : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 898*f4a2713aSLionel Sambuc Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 899*f4a2713aSLionel Sambuc IsSystem(IsSystem), HadError(false), ActiveModule(0) 900*f4a2713aSLionel Sambuc { 901*f4a2713aSLionel Sambuc Tok.clear(); 902*f4a2713aSLionel Sambuc consumeToken(); 903*f4a2713aSLionel Sambuc } 904*f4a2713aSLionel Sambuc 905*f4a2713aSLionel Sambuc bool parseModuleMapFile(); 906*f4a2713aSLionel Sambuc }; 907*f4a2713aSLionel Sambuc } 908*f4a2713aSLionel Sambuc 909*f4a2713aSLionel Sambuc SourceLocation ModuleMapParser::consumeToken() { 910*f4a2713aSLionel Sambuc retry: 911*f4a2713aSLionel Sambuc SourceLocation Result = Tok.getLocation(); 912*f4a2713aSLionel Sambuc Tok.clear(); 913*f4a2713aSLionel Sambuc 914*f4a2713aSLionel Sambuc Token LToken; 915*f4a2713aSLionel Sambuc L.LexFromRawLexer(LToken); 916*f4a2713aSLionel Sambuc Tok.Location = LToken.getLocation().getRawEncoding(); 917*f4a2713aSLionel Sambuc switch (LToken.getKind()) { 918*f4a2713aSLionel Sambuc case tok::raw_identifier: 919*f4a2713aSLionel Sambuc Tok.StringData = LToken.getRawIdentifierData(); 920*f4a2713aSLionel Sambuc Tok.StringLength = LToken.getLength(); 921*f4a2713aSLionel Sambuc Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 922*f4a2713aSLionel Sambuc .Case("config_macros", MMToken::ConfigMacros) 923*f4a2713aSLionel Sambuc .Case("conflict", MMToken::Conflict) 924*f4a2713aSLionel Sambuc .Case("exclude", MMToken::ExcludeKeyword) 925*f4a2713aSLionel Sambuc .Case("explicit", MMToken::ExplicitKeyword) 926*f4a2713aSLionel Sambuc .Case("export", MMToken::ExportKeyword) 927*f4a2713aSLionel Sambuc .Case("extern", MMToken::ExternKeyword) 928*f4a2713aSLionel Sambuc .Case("framework", MMToken::FrameworkKeyword) 929*f4a2713aSLionel Sambuc .Case("header", MMToken::HeaderKeyword) 930*f4a2713aSLionel Sambuc .Case("link", MMToken::LinkKeyword) 931*f4a2713aSLionel Sambuc .Case("module", MMToken::ModuleKeyword) 932*f4a2713aSLionel Sambuc .Case("private", MMToken::PrivateKeyword) 933*f4a2713aSLionel Sambuc .Case("requires", MMToken::RequiresKeyword) 934*f4a2713aSLionel Sambuc .Case("umbrella", MMToken::UmbrellaKeyword) 935*f4a2713aSLionel Sambuc .Case("use", MMToken::UseKeyword) 936*f4a2713aSLionel Sambuc .Default(MMToken::Identifier); 937*f4a2713aSLionel Sambuc break; 938*f4a2713aSLionel Sambuc 939*f4a2713aSLionel Sambuc case tok::comma: 940*f4a2713aSLionel Sambuc Tok.Kind = MMToken::Comma; 941*f4a2713aSLionel Sambuc break; 942*f4a2713aSLionel Sambuc 943*f4a2713aSLionel Sambuc case tok::eof: 944*f4a2713aSLionel Sambuc Tok.Kind = MMToken::EndOfFile; 945*f4a2713aSLionel Sambuc break; 946*f4a2713aSLionel Sambuc 947*f4a2713aSLionel Sambuc case tok::l_brace: 948*f4a2713aSLionel Sambuc Tok.Kind = MMToken::LBrace; 949*f4a2713aSLionel Sambuc break; 950*f4a2713aSLionel Sambuc 951*f4a2713aSLionel Sambuc case tok::l_square: 952*f4a2713aSLionel Sambuc Tok.Kind = MMToken::LSquare; 953*f4a2713aSLionel Sambuc break; 954*f4a2713aSLionel Sambuc 955*f4a2713aSLionel Sambuc case tok::period: 956*f4a2713aSLionel Sambuc Tok.Kind = MMToken::Period; 957*f4a2713aSLionel Sambuc break; 958*f4a2713aSLionel Sambuc 959*f4a2713aSLionel Sambuc case tok::r_brace: 960*f4a2713aSLionel Sambuc Tok.Kind = MMToken::RBrace; 961*f4a2713aSLionel Sambuc break; 962*f4a2713aSLionel Sambuc 963*f4a2713aSLionel Sambuc case tok::r_square: 964*f4a2713aSLionel Sambuc Tok.Kind = MMToken::RSquare; 965*f4a2713aSLionel Sambuc break; 966*f4a2713aSLionel Sambuc 967*f4a2713aSLionel Sambuc case tok::star: 968*f4a2713aSLionel Sambuc Tok.Kind = MMToken::Star; 969*f4a2713aSLionel Sambuc break; 970*f4a2713aSLionel Sambuc 971*f4a2713aSLionel Sambuc case tok::exclaim: 972*f4a2713aSLionel Sambuc Tok.Kind = MMToken::Exclaim; 973*f4a2713aSLionel Sambuc break; 974*f4a2713aSLionel Sambuc 975*f4a2713aSLionel Sambuc case tok::string_literal: { 976*f4a2713aSLionel Sambuc if (LToken.hasUDSuffix()) { 977*f4a2713aSLionel Sambuc Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 978*f4a2713aSLionel Sambuc HadError = true; 979*f4a2713aSLionel Sambuc goto retry; 980*f4a2713aSLionel Sambuc } 981*f4a2713aSLionel Sambuc 982*f4a2713aSLionel Sambuc // Parse the string literal. 983*f4a2713aSLionel Sambuc LangOptions LangOpts; 984*f4a2713aSLionel Sambuc StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 985*f4a2713aSLionel Sambuc if (StringLiteral.hadError) 986*f4a2713aSLionel Sambuc goto retry; 987*f4a2713aSLionel Sambuc 988*f4a2713aSLionel Sambuc // Copy the string literal into our string data allocator. 989*f4a2713aSLionel Sambuc unsigned Length = StringLiteral.GetStringLength(); 990*f4a2713aSLionel Sambuc char *Saved = StringData.Allocate<char>(Length + 1); 991*f4a2713aSLionel Sambuc memcpy(Saved, StringLiteral.GetString().data(), Length); 992*f4a2713aSLionel Sambuc Saved[Length] = 0; 993*f4a2713aSLionel Sambuc 994*f4a2713aSLionel Sambuc // Form the token. 995*f4a2713aSLionel Sambuc Tok.Kind = MMToken::StringLiteral; 996*f4a2713aSLionel Sambuc Tok.StringData = Saved; 997*f4a2713aSLionel Sambuc Tok.StringLength = Length; 998*f4a2713aSLionel Sambuc break; 999*f4a2713aSLionel Sambuc } 1000*f4a2713aSLionel Sambuc 1001*f4a2713aSLionel Sambuc case tok::comment: 1002*f4a2713aSLionel Sambuc goto retry; 1003*f4a2713aSLionel Sambuc 1004*f4a2713aSLionel Sambuc default: 1005*f4a2713aSLionel Sambuc Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1006*f4a2713aSLionel Sambuc HadError = true; 1007*f4a2713aSLionel Sambuc goto retry; 1008*f4a2713aSLionel Sambuc } 1009*f4a2713aSLionel Sambuc 1010*f4a2713aSLionel Sambuc return Result; 1011*f4a2713aSLionel Sambuc } 1012*f4a2713aSLionel Sambuc 1013*f4a2713aSLionel Sambuc void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1014*f4a2713aSLionel Sambuc unsigned braceDepth = 0; 1015*f4a2713aSLionel Sambuc unsigned squareDepth = 0; 1016*f4a2713aSLionel Sambuc do { 1017*f4a2713aSLionel Sambuc switch (Tok.Kind) { 1018*f4a2713aSLionel Sambuc case MMToken::EndOfFile: 1019*f4a2713aSLionel Sambuc return; 1020*f4a2713aSLionel Sambuc 1021*f4a2713aSLionel Sambuc case MMToken::LBrace: 1022*f4a2713aSLionel Sambuc if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1023*f4a2713aSLionel Sambuc return; 1024*f4a2713aSLionel Sambuc 1025*f4a2713aSLionel Sambuc ++braceDepth; 1026*f4a2713aSLionel Sambuc break; 1027*f4a2713aSLionel Sambuc 1028*f4a2713aSLionel Sambuc case MMToken::LSquare: 1029*f4a2713aSLionel Sambuc if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1030*f4a2713aSLionel Sambuc return; 1031*f4a2713aSLionel Sambuc 1032*f4a2713aSLionel Sambuc ++squareDepth; 1033*f4a2713aSLionel Sambuc break; 1034*f4a2713aSLionel Sambuc 1035*f4a2713aSLionel Sambuc case MMToken::RBrace: 1036*f4a2713aSLionel Sambuc if (braceDepth > 0) 1037*f4a2713aSLionel Sambuc --braceDepth; 1038*f4a2713aSLionel Sambuc else if (Tok.is(K)) 1039*f4a2713aSLionel Sambuc return; 1040*f4a2713aSLionel Sambuc break; 1041*f4a2713aSLionel Sambuc 1042*f4a2713aSLionel Sambuc case MMToken::RSquare: 1043*f4a2713aSLionel Sambuc if (squareDepth > 0) 1044*f4a2713aSLionel Sambuc --squareDepth; 1045*f4a2713aSLionel Sambuc else if (Tok.is(K)) 1046*f4a2713aSLionel Sambuc return; 1047*f4a2713aSLionel Sambuc break; 1048*f4a2713aSLionel Sambuc 1049*f4a2713aSLionel Sambuc default: 1050*f4a2713aSLionel Sambuc if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1051*f4a2713aSLionel Sambuc return; 1052*f4a2713aSLionel Sambuc break; 1053*f4a2713aSLionel Sambuc } 1054*f4a2713aSLionel Sambuc 1055*f4a2713aSLionel Sambuc consumeToken(); 1056*f4a2713aSLionel Sambuc } while (true); 1057*f4a2713aSLionel Sambuc } 1058*f4a2713aSLionel Sambuc 1059*f4a2713aSLionel Sambuc /// \brief Parse a module-id. 1060*f4a2713aSLionel Sambuc /// 1061*f4a2713aSLionel Sambuc /// module-id: 1062*f4a2713aSLionel Sambuc /// identifier 1063*f4a2713aSLionel Sambuc /// identifier '.' module-id 1064*f4a2713aSLionel Sambuc /// 1065*f4a2713aSLionel Sambuc /// \returns true if an error occurred, false otherwise. 1066*f4a2713aSLionel Sambuc bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1067*f4a2713aSLionel Sambuc Id.clear(); 1068*f4a2713aSLionel Sambuc do { 1069*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Identifier)) { 1070*f4a2713aSLionel Sambuc Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1071*f4a2713aSLionel Sambuc consumeToken(); 1072*f4a2713aSLionel Sambuc } else { 1073*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1074*f4a2713aSLionel Sambuc return true; 1075*f4a2713aSLionel Sambuc } 1076*f4a2713aSLionel Sambuc 1077*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Period)) 1078*f4a2713aSLionel Sambuc break; 1079*f4a2713aSLionel Sambuc 1080*f4a2713aSLionel Sambuc consumeToken(); 1081*f4a2713aSLionel Sambuc } while (true); 1082*f4a2713aSLionel Sambuc 1083*f4a2713aSLionel Sambuc return false; 1084*f4a2713aSLionel Sambuc } 1085*f4a2713aSLionel Sambuc 1086*f4a2713aSLionel Sambuc namespace { 1087*f4a2713aSLionel Sambuc /// \brief Enumerates the known attributes. 1088*f4a2713aSLionel Sambuc enum AttributeKind { 1089*f4a2713aSLionel Sambuc /// \brief An unknown attribute. 1090*f4a2713aSLionel Sambuc AT_unknown, 1091*f4a2713aSLionel Sambuc /// \brief The 'system' attribute. 1092*f4a2713aSLionel Sambuc AT_system, 1093*f4a2713aSLionel Sambuc /// \brief The 'exhaustive' attribute. 1094*f4a2713aSLionel Sambuc AT_exhaustive 1095*f4a2713aSLionel Sambuc }; 1096*f4a2713aSLionel Sambuc } 1097*f4a2713aSLionel Sambuc 1098*f4a2713aSLionel Sambuc /// \brief Parse a module declaration. 1099*f4a2713aSLionel Sambuc /// 1100*f4a2713aSLionel Sambuc /// module-declaration: 1101*f4a2713aSLionel Sambuc /// 'extern' 'module' module-id string-literal 1102*f4a2713aSLionel Sambuc /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1103*f4a2713aSLionel Sambuc /// { module-member* } 1104*f4a2713aSLionel Sambuc /// 1105*f4a2713aSLionel Sambuc /// module-member: 1106*f4a2713aSLionel Sambuc /// requires-declaration 1107*f4a2713aSLionel Sambuc /// header-declaration 1108*f4a2713aSLionel Sambuc /// submodule-declaration 1109*f4a2713aSLionel Sambuc /// export-declaration 1110*f4a2713aSLionel Sambuc /// link-declaration 1111*f4a2713aSLionel Sambuc /// 1112*f4a2713aSLionel Sambuc /// submodule-declaration: 1113*f4a2713aSLionel Sambuc /// module-declaration 1114*f4a2713aSLionel Sambuc /// inferred-submodule-declaration 1115*f4a2713aSLionel Sambuc void ModuleMapParser::parseModuleDecl() { 1116*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1117*f4a2713aSLionel Sambuc Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1118*f4a2713aSLionel Sambuc if (Tok.is(MMToken::ExternKeyword)) { 1119*f4a2713aSLionel Sambuc parseExternModuleDecl(); 1120*f4a2713aSLionel Sambuc return; 1121*f4a2713aSLionel Sambuc } 1122*f4a2713aSLionel Sambuc 1123*f4a2713aSLionel Sambuc // Parse 'explicit' or 'framework' keyword, if present. 1124*f4a2713aSLionel Sambuc SourceLocation ExplicitLoc; 1125*f4a2713aSLionel Sambuc bool Explicit = false; 1126*f4a2713aSLionel Sambuc bool Framework = false; 1127*f4a2713aSLionel Sambuc 1128*f4a2713aSLionel Sambuc // Parse 'explicit' keyword, if present. 1129*f4a2713aSLionel Sambuc if (Tok.is(MMToken::ExplicitKeyword)) { 1130*f4a2713aSLionel Sambuc ExplicitLoc = consumeToken(); 1131*f4a2713aSLionel Sambuc Explicit = true; 1132*f4a2713aSLionel Sambuc } 1133*f4a2713aSLionel Sambuc 1134*f4a2713aSLionel Sambuc // Parse 'framework' keyword, if present. 1135*f4a2713aSLionel Sambuc if (Tok.is(MMToken::FrameworkKeyword)) { 1136*f4a2713aSLionel Sambuc consumeToken(); 1137*f4a2713aSLionel Sambuc Framework = true; 1138*f4a2713aSLionel Sambuc } 1139*f4a2713aSLionel Sambuc 1140*f4a2713aSLionel Sambuc // Parse 'module' keyword. 1141*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::ModuleKeyword)) { 1142*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1143*f4a2713aSLionel Sambuc consumeToken(); 1144*f4a2713aSLionel Sambuc HadError = true; 1145*f4a2713aSLionel Sambuc return; 1146*f4a2713aSLionel Sambuc } 1147*f4a2713aSLionel Sambuc consumeToken(); // 'module' keyword 1148*f4a2713aSLionel Sambuc 1149*f4a2713aSLionel Sambuc // If we have a wildcard for the module name, this is an inferred submodule. 1150*f4a2713aSLionel Sambuc // Parse it. 1151*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Star)) 1152*f4a2713aSLionel Sambuc return parseInferredModuleDecl(Framework, Explicit); 1153*f4a2713aSLionel Sambuc 1154*f4a2713aSLionel Sambuc // Parse the module name. 1155*f4a2713aSLionel Sambuc ModuleId Id; 1156*f4a2713aSLionel Sambuc if (parseModuleId(Id)) { 1157*f4a2713aSLionel Sambuc HadError = true; 1158*f4a2713aSLionel Sambuc return; 1159*f4a2713aSLionel Sambuc } 1160*f4a2713aSLionel Sambuc 1161*f4a2713aSLionel Sambuc if (ActiveModule) { 1162*f4a2713aSLionel Sambuc if (Id.size() > 1) { 1163*f4a2713aSLionel Sambuc Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1164*f4a2713aSLionel Sambuc << SourceRange(Id.front().second, Id.back().second); 1165*f4a2713aSLionel Sambuc 1166*f4a2713aSLionel Sambuc HadError = true; 1167*f4a2713aSLionel Sambuc return; 1168*f4a2713aSLionel Sambuc } 1169*f4a2713aSLionel Sambuc } else if (Id.size() == 1 && Explicit) { 1170*f4a2713aSLionel Sambuc // Top-level modules can't be explicit. 1171*f4a2713aSLionel Sambuc Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1172*f4a2713aSLionel Sambuc Explicit = false; 1173*f4a2713aSLionel Sambuc ExplicitLoc = SourceLocation(); 1174*f4a2713aSLionel Sambuc HadError = true; 1175*f4a2713aSLionel Sambuc } 1176*f4a2713aSLionel Sambuc 1177*f4a2713aSLionel Sambuc Module *PreviousActiveModule = ActiveModule; 1178*f4a2713aSLionel Sambuc if (Id.size() > 1) { 1179*f4a2713aSLionel Sambuc // This module map defines a submodule. Go find the module of which it 1180*f4a2713aSLionel Sambuc // is a submodule. 1181*f4a2713aSLionel Sambuc ActiveModule = 0; 1182*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1183*f4a2713aSLionel Sambuc if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1184*f4a2713aSLionel Sambuc ActiveModule = Next; 1185*f4a2713aSLionel Sambuc continue; 1186*f4a2713aSLionel Sambuc } 1187*f4a2713aSLionel Sambuc 1188*f4a2713aSLionel Sambuc if (ActiveModule) { 1189*f4a2713aSLionel Sambuc Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1190*f4a2713aSLionel Sambuc << Id[I].first << ActiveModule->getTopLevelModule(); 1191*f4a2713aSLionel Sambuc } else { 1192*f4a2713aSLionel Sambuc Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1193*f4a2713aSLionel Sambuc } 1194*f4a2713aSLionel Sambuc HadError = true; 1195*f4a2713aSLionel Sambuc return; 1196*f4a2713aSLionel Sambuc } 1197*f4a2713aSLionel Sambuc } 1198*f4a2713aSLionel Sambuc 1199*f4a2713aSLionel Sambuc StringRef ModuleName = Id.back().first; 1200*f4a2713aSLionel Sambuc SourceLocation ModuleNameLoc = Id.back().second; 1201*f4a2713aSLionel Sambuc 1202*f4a2713aSLionel Sambuc // Parse the optional attribute list. 1203*f4a2713aSLionel Sambuc Attributes Attrs; 1204*f4a2713aSLionel Sambuc parseOptionalAttributes(Attrs); 1205*f4a2713aSLionel Sambuc 1206*f4a2713aSLionel Sambuc // Parse the opening brace. 1207*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::LBrace)) { 1208*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1209*f4a2713aSLionel Sambuc << ModuleName; 1210*f4a2713aSLionel Sambuc HadError = true; 1211*f4a2713aSLionel Sambuc return; 1212*f4a2713aSLionel Sambuc } 1213*f4a2713aSLionel Sambuc SourceLocation LBraceLoc = consumeToken(); 1214*f4a2713aSLionel Sambuc 1215*f4a2713aSLionel Sambuc // Determine whether this (sub)module has already been defined. 1216*f4a2713aSLionel Sambuc if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1217*f4a2713aSLionel Sambuc if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1218*f4a2713aSLionel Sambuc // Skip the module definition. 1219*f4a2713aSLionel Sambuc skipUntil(MMToken::RBrace); 1220*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RBrace)) 1221*f4a2713aSLionel Sambuc consumeToken(); 1222*f4a2713aSLionel Sambuc else { 1223*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1224*f4a2713aSLionel Sambuc Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1225*f4a2713aSLionel Sambuc HadError = true; 1226*f4a2713aSLionel Sambuc } 1227*f4a2713aSLionel Sambuc return; 1228*f4a2713aSLionel Sambuc } 1229*f4a2713aSLionel Sambuc 1230*f4a2713aSLionel Sambuc Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1231*f4a2713aSLionel Sambuc << ModuleName; 1232*f4a2713aSLionel Sambuc Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1233*f4a2713aSLionel Sambuc 1234*f4a2713aSLionel Sambuc // Skip the module definition. 1235*f4a2713aSLionel Sambuc skipUntil(MMToken::RBrace); 1236*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RBrace)) 1237*f4a2713aSLionel Sambuc consumeToken(); 1238*f4a2713aSLionel Sambuc 1239*f4a2713aSLionel Sambuc HadError = true; 1240*f4a2713aSLionel Sambuc return; 1241*f4a2713aSLionel Sambuc } 1242*f4a2713aSLionel Sambuc 1243*f4a2713aSLionel Sambuc // Start defining this module. 1244*f4a2713aSLionel Sambuc ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1245*f4a2713aSLionel Sambuc Explicit).first; 1246*f4a2713aSLionel Sambuc ActiveModule->DefinitionLoc = ModuleNameLoc; 1247*f4a2713aSLionel Sambuc if (Attrs.IsSystem || IsSystem) 1248*f4a2713aSLionel Sambuc ActiveModule->IsSystem = true; 1249*f4a2713aSLionel Sambuc 1250*f4a2713aSLionel Sambuc bool Done = false; 1251*f4a2713aSLionel Sambuc do { 1252*f4a2713aSLionel Sambuc switch (Tok.Kind) { 1253*f4a2713aSLionel Sambuc case MMToken::EndOfFile: 1254*f4a2713aSLionel Sambuc case MMToken::RBrace: 1255*f4a2713aSLionel Sambuc Done = true; 1256*f4a2713aSLionel Sambuc break; 1257*f4a2713aSLionel Sambuc 1258*f4a2713aSLionel Sambuc case MMToken::ConfigMacros: 1259*f4a2713aSLionel Sambuc parseConfigMacros(); 1260*f4a2713aSLionel Sambuc break; 1261*f4a2713aSLionel Sambuc 1262*f4a2713aSLionel Sambuc case MMToken::Conflict: 1263*f4a2713aSLionel Sambuc parseConflict(); 1264*f4a2713aSLionel Sambuc break; 1265*f4a2713aSLionel Sambuc 1266*f4a2713aSLionel Sambuc case MMToken::ExplicitKeyword: 1267*f4a2713aSLionel Sambuc case MMToken::ExternKeyword: 1268*f4a2713aSLionel Sambuc case MMToken::FrameworkKeyword: 1269*f4a2713aSLionel Sambuc case MMToken::ModuleKeyword: 1270*f4a2713aSLionel Sambuc parseModuleDecl(); 1271*f4a2713aSLionel Sambuc break; 1272*f4a2713aSLionel Sambuc 1273*f4a2713aSLionel Sambuc case MMToken::ExportKeyword: 1274*f4a2713aSLionel Sambuc parseExportDecl(); 1275*f4a2713aSLionel Sambuc break; 1276*f4a2713aSLionel Sambuc 1277*f4a2713aSLionel Sambuc case MMToken::UseKeyword: 1278*f4a2713aSLionel Sambuc parseUseDecl(); 1279*f4a2713aSLionel Sambuc break; 1280*f4a2713aSLionel Sambuc 1281*f4a2713aSLionel Sambuc case MMToken::RequiresKeyword: 1282*f4a2713aSLionel Sambuc parseRequiresDecl(); 1283*f4a2713aSLionel Sambuc break; 1284*f4a2713aSLionel Sambuc 1285*f4a2713aSLionel Sambuc case MMToken::UmbrellaKeyword: { 1286*f4a2713aSLionel Sambuc SourceLocation UmbrellaLoc = consumeToken(); 1287*f4a2713aSLionel Sambuc if (Tok.is(MMToken::HeaderKeyword)) 1288*f4a2713aSLionel Sambuc parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1289*f4a2713aSLionel Sambuc else 1290*f4a2713aSLionel Sambuc parseUmbrellaDirDecl(UmbrellaLoc); 1291*f4a2713aSLionel Sambuc break; 1292*f4a2713aSLionel Sambuc } 1293*f4a2713aSLionel Sambuc 1294*f4a2713aSLionel Sambuc case MMToken::ExcludeKeyword: { 1295*f4a2713aSLionel Sambuc SourceLocation ExcludeLoc = consumeToken(); 1296*f4a2713aSLionel Sambuc if (Tok.is(MMToken::HeaderKeyword)) { 1297*f4a2713aSLionel Sambuc parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc); 1298*f4a2713aSLionel Sambuc } else { 1299*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1300*f4a2713aSLionel Sambuc << "exclude"; 1301*f4a2713aSLionel Sambuc } 1302*f4a2713aSLionel Sambuc break; 1303*f4a2713aSLionel Sambuc } 1304*f4a2713aSLionel Sambuc 1305*f4a2713aSLionel Sambuc case MMToken::PrivateKeyword: { 1306*f4a2713aSLionel Sambuc SourceLocation PrivateLoc = consumeToken(); 1307*f4a2713aSLionel Sambuc if (Tok.is(MMToken::HeaderKeyword)) { 1308*f4a2713aSLionel Sambuc parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc); 1309*f4a2713aSLionel Sambuc } else { 1310*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1311*f4a2713aSLionel Sambuc << "private"; 1312*f4a2713aSLionel Sambuc } 1313*f4a2713aSLionel Sambuc break; 1314*f4a2713aSLionel Sambuc } 1315*f4a2713aSLionel Sambuc 1316*f4a2713aSLionel Sambuc case MMToken::HeaderKeyword: 1317*f4a2713aSLionel Sambuc parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation()); 1318*f4a2713aSLionel Sambuc break; 1319*f4a2713aSLionel Sambuc 1320*f4a2713aSLionel Sambuc case MMToken::LinkKeyword: 1321*f4a2713aSLionel Sambuc parseLinkDecl(); 1322*f4a2713aSLionel Sambuc break; 1323*f4a2713aSLionel Sambuc 1324*f4a2713aSLionel Sambuc default: 1325*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1326*f4a2713aSLionel Sambuc consumeToken(); 1327*f4a2713aSLionel Sambuc break; 1328*f4a2713aSLionel Sambuc } 1329*f4a2713aSLionel Sambuc } while (!Done); 1330*f4a2713aSLionel Sambuc 1331*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RBrace)) 1332*f4a2713aSLionel Sambuc consumeToken(); 1333*f4a2713aSLionel Sambuc else { 1334*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1335*f4a2713aSLionel Sambuc Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1336*f4a2713aSLionel Sambuc HadError = true; 1337*f4a2713aSLionel Sambuc } 1338*f4a2713aSLionel Sambuc 1339*f4a2713aSLionel Sambuc // If the active module is a top-level framework, and there are no link 1340*f4a2713aSLionel Sambuc // libraries, automatically link against the framework. 1341*f4a2713aSLionel Sambuc if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1342*f4a2713aSLionel Sambuc ActiveModule->LinkLibraries.empty()) { 1343*f4a2713aSLionel Sambuc inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1344*f4a2713aSLionel Sambuc } 1345*f4a2713aSLionel Sambuc 1346*f4a2713aSLionel Sambuc // We're done parsing this module. Pop back to the previous module. 1347*f4a2713aSLionel Sambuc ActiveModule = PreviousActiveModule; 1348*f4a2713aSLionel Sambuc } 1349*f4a2713aSLionel Sambuc 1350*f4a2713aSLionel Sambuc /// \brief Parse an extern module declaration. 1351*f4a2713aSLionel Sambuc /// 1352*f4a2713aSLionel Sambuc /// extern module-declaration: 1353*f4a2713aSLionel Sambuc /// 'extern' 'module' module-id string-literal 1354*f4a2713aSLionel Sambuc void ModuleMapParser::parseExternModuleDecl() { 1355*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::ExternKeyword)); 1356*f4a2713aSLionel Sambuc consumeToken(); // 'extern' keyword 1357*f4a2713aSLionel Sambuc 1358*f4a2713aSLionel Sambuc // Parse 'module' keyword. 1359*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::ModuleKeyword)) { 1360*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1361*f4a2713aSLionel Sambuc consumeToken(); 1362*f4a2713aSLionel Sambuc HadError = true; 1363*f4a2713aSLionel Sambuc return; 1364*f4a2713aSLionel Sambuc } 1365*f4a2713aSLionel Sambuc consumeToken(); // 'module' keyword 1366*f4a2713aSLionel Sambuc 1367*f4a2713aSLionel Sambuc // Parse the module name. 1368*f4a2713aSLionel Sambuc ModuleId Id; 1369*f4a2713aSLionel Sambuc if (parseModuleId(Id)) { 1370*f4a2713aSLionel Sambuc HadError = true; 1371*f4a2713aSLionel Sambuc return; 1372*f4a2713aSLionel Sambuc } 1373*f4a2713aSLionel Sambuc 1374*f4a2713aSLionel Sambuc // Parse the referenced module map file name. 1375*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::StringLiteral)) { 1376*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1377*f4a2713aSLionel Sambuc HadError = true; 1378*f4a2713aSLionel Sambuc return; 1379*f4a2713aSLionel Sambuc } 1380*f4a2713aSLionel Sambuc std::string FileName = Tok.getString(); 1381*f4a2713aSLionel Sambuc consumeToken(); // filename 1382*f4a2713aSLionel Sambuc 1383*f4a2713aSLionel Sambuc StringRef FileNameRef = FileName; 1384*f4a2713aSLionel Sambuc SmallString<128> ModuleMapFileName; 1385*f4a2713aSLionel Sambuc if (llvm::sys::path::is_relative(FileNameRef)) { 1386*f4a2713aSLionel Sambuc ModuleMapFileName += Directory->getName(); 1387*f4a2713aSLionel Sambuc llvm::sys::path::append(ModuleMapFileName, FileName); 1388*f4a2713aSLionel Sambuc FileNameRef = ModuleMapFileName.str(); 1389*f4a2713aSLionel Sambuc } 1390*f4a2713aSLionel Sambuc if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1391*f4a2713aSLionel Sambuc Map.parseModuleMapFile(File, /*IsSystem=*/false); 1392*f4a2713aSLionel Sambuc } 1393*f4a2713aSLionel Sambuc 1394*f4a2713aSLionel Sambuc /// \brief Parse a requires declaration. 1395*f4a2713aSLionel Sambuc /// 1396*f4a2713aSLionel Sambuc /// requires-declaration: 1397*f4a2713aSLionel Sambuc /// 'requires' feature-list 1398*f4a2713aSLionel Sambuc /// 1399*f4a2713aSLionel Sambuc /// feature-list: 1400*f4a2713aSLionel Sambuc /// feature ',' feature-list 1401*f4a2713aSLionel Sambuc /// feature 1402*f4a2713aSLionel Sambuc /// 1403*f4a2713aSLionel Sambuc /// feature: 1404*f4a2713aSLionel Sambuc /// '!'[opt] identifier 1405*f4a2713aSLionel Sambuc void ModuleMapParser::parseRequiresDecl() { 1406*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::RequiresKeyword)); 1407*f4a2713aSLionel Sambuc 1408*f4a2713aSLionel Sambuc // Parse 'requires' keyword. 1409*f4a2713aSLionel Sambuc consumeToken(); 1410*f4a2713aSLionel Sambuc 1411*f4a2713aSLionel Sambuc // Parse the feature-list. 1412*f4a2713aSLionel Sambuc do { 1413*f4a2713aSLionel Sambuc bool RequiredState = true; 1414*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Exclaim)) { 1415*f4a2713aSLionel Sambuc RequiredState = false; 1416*f4a2713aSLionel Sambuc consumeToken(); 1417*f4a2713aSLionel Sambuc } 1418*f4a2713aSLionel Sambuc 1419*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Identifier)) { 1420*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1421*f4a2713aSLionel Sambuc HadError = true; 1422*f4a2713aSLionel Sambuc return; 1423*f4a2713aSLionel Sambuc } 1424*f4a2713aSLionel Sambuc 1425*f4a2713aSLionel Sambuc // Consume the feature name. 1426*f4a2713aSLionel Sambuc std::string Feature = Tok.getString(); 1427*f4a2713aSLionel Sambuc consumeToken(); 1428*f4a2713aSLionel Sambuc 1429*f4a2713aSLionel Sambuc // Add this feature. 1430*f4a2713aSLionel Sambuc ActiveModule->addRequirement(Feature, RequiredState, 1431*f4a2713aSLionel Sambuc Map.LangOpts, *Map.Target); 1432*f4a2713aSLionel Sambuc 1433*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Comma)) 1434*f4a2713aSLionel Sambuc break; 1435*f4a2713aSLionel Sambuc 1436*f4a2713aSLionel Sambuc // Consume the comma. 1437*f4a2713aSLionel Sambuc consumeToken(); 1438*f4a2713aSLionel Sambuc } while (true); 1439*f4a2713aSLionel Sambuc } 1440*f4a2713aSLionel Sambuc 1441*f4a2713aSLionel Sambuc /// \brief Append to \p Paths the set of paths needed to get to the 1442*f4a2713aSLionel Sambuc /// subframework in which the given module lives. 1443*f4a2713aSLionel Sambuc static void appendSubframeworkPaths(Module *Mod, 1444*f4a2713aSLionel Sambuc SmallVectorImpl<char> &Path) { 1445*f4a2713aSLionel Sambuc // Collect the framework names from the given module to the top-level module. 1446*f4a2713aSLionel Sambuc SmallVector<StringRef, 2> Paths; 1447*f4a2713aSLionel Sambuc for (; Mod; Mod = Mod->Parent) { 1448*f4a2713aSLionel Sambuc if (Mod->IsFramework) 1449*f4a2713aSLionel Sambuc Paths.push_back(Mod->Name); 1450*f4a2713aSLionel Sambuc } 1451*f4a2713aSLionel Sambuc 1452*f4a2713aSLionel Sambuc if (Paths.empty()) 1453*f4a2713aSLionel Sambuc return; 1454*f4a2713aSLionel Sambuc 1455*f4a2713aSLionel Sambuc // Add Frameworks/Name.framework for each subframework. 1456*f4a2713aSLionel Sambuc for (unsigned I = Paths.size() - 1; I != 0; --I) 1457*f4a2713aSLionel Sambuc llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1458*f4a2713aSLionel Sambuc } 1459*f4a2713aSLionel Sambuc 1460*f4a2713aSLionel Sambuc /// \brief Parse a header declaration. 1461*f4a2713aSLionel Sambuc /// 1462*f4a2713aSLionel Sambuc /// header-declaration: 1463*f4a2713aSLionel Sambuc /// 'umbrella'[opt] 'header' string-literal 1464*f4a2713aSLionel Sambuc /// 'exclude'[opt] 'header' string-literal 1465*f4a2713aSLionel Sambuc void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1466*f4a2713aSLionel Sambuc SourceLocation LeadingLoc) { 1467*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::HeaderKeyword)); 1468*f4a2713aSLionel Sambuc consumeToken(); 1469*f4a2713aSLionel Sambuc 1470*f4a2713aSLionel Sambuc // Parse the header name. 1471*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::StringLiteral)) { 1472*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1473*f4a2713aSLionel Sambuc << "header"; 1474*f4a2713aSLionel Sambuc HadError = true; 1475*f4a2713aSLionel Sambuc return; 1476*f4a2713aSLionel Sambuc } 1477*f4a2713aSLionel Sambuc std::string FileName = Tok.getString(); 1478*f4a2713aSLionel Sambuc SourceLocation FileNameLoc = consumeToken(); 1479*f4a2713aSLionel Sambuc 1480*f4a2713aSLionel Sambuc // Check whether we already have an umbrella. 1481*f4a2713aSLionel Sambuc if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1482*f4a2713aSLionel Sambuc Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 1483*f4a2713aSLionel Sambuc << ActiveModule->getFullModuleName(); 1484*f4a2713aSLionel Sambuc HadError = true; 1485*f4a2713aSLionel Sambuc return; 1486*f4a2713aSLionel Sambuc } 1487*f4a2713aSLionel Sambuc 1488*f4a2713aSLionel Sambuc // Look for this file. 1489*f4a2713aSLionel Sambuc const FileEntry *File = 0; 1490*f4a2713aSLionel Sambuc const FileEntry *BuiltinFile = 0; 1491*f4a2713aSLionel Sambuc SmallString<128> PathName; 1492*f4a2713aSLionel Sambuc if (llvm::sys::path::is_absolute(FileName)) { 1493*f4a2713aSLionel Sambuc PathName = FileName; 1494*f4a2713aSLionel Sambuc File = SourceMgr.getFileManager().getFile(PathName); 1495*f4a2713aSLionel Sambuc } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 1496*f4a2713aSLionel Sambuc PathName = Dir->getName(); 1497*f4a2713aSLionel Sambuc llvm::sys::path::append(PathName, FileName); 1498*f4a2713aSLionel Sambuc File = SourceMgr.getFileManager().getFile(PathName); 1499*f4a2713aSLionel Sambuc } else { 1500*f4a2713aSLionel Sambuc // Search for the header file within the search directory. 1501*f4a2713aSLionel Sambuc PathName = Directory->getName(); 1502*f4a2713aSLionel Sambuc unsigned PathLength = PathName.size(); 1503*f4a2713aSLionel Sambuc 1504*f4a2713aSLionel Sambuc if (ActiveModule->isPartOfFramework()) { 1505*f4a2713aSLionel Sambuc appendSubframeworkPaths(ActiveModule, PathName); 1506*f4a2713aSLionel Sambuc 1507*f4a2713aSLionel Sambuc // Check whether this file is in the public headers. 1508*f4a2713aSLionel Sambuc llvm::sys::path::append(PathName, "Headers", FileName); 1509*f4a2713aSLionel Sambuc File = SourceMgr.getFileManager().getFile(PathName); 1510*f4a2713aSLionel Sambuc 1511*f4a2713aSLionel Sambuc if (!File) { 1512*f4a2713aSLionel Sambuc // Check whether this file is in the private headers. 1513*f4a2713aSLionel Sambuc PathName.resize(PathLength); 1514*f4a2713aSLionel Sambuc llvm::sys::path::append(PathName, "PrivateHeaders", FileName); 1515*f4a2713aSLionel Sambuc File = SourceMgr.getFileManager().getFile(PathName); 1516*f4a2713aSLionel Sambuc } 1517*f4a2713aSLionel Sambuc } else { 1518*f4a2713aSLionel Sambuc // Lookup for normal headers. 1519*f4a2713aSLionel Sambuc llvm::sys::path::append(PathName, FileName); 1520*f4a2713aSLionel Sambuc File = SourceMgr.getFileManager().getFile(PathName); 1521*f4a2713aSLionel Sambuc 1522*f4a2713aSLionel Sambuc // If this is a system module with a top-level header, this header 1523*f4a2713aSLionel Sambuc // may have a counterpart (or replacement) in the set of headers 1524*f4a2713aSLionel Sambuc // supplied by Clang. Find that builtin header. 1525*f4a2713aSLionel Sambuc if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1526*f4a2713aSLionel Sambuc BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1527*f4a2713aSLionel Sambuc isBuiltinHeader(FileName)) { 1528*f4a2713aSLionel Sambuc SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1529*f4a2713aSLionel Sambuc llvm::sys::path::append(BuiltinPathName, FileName); 1530*f4a2713aSLionel Sambuc BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1531*f4a2713aSLionel Sambuc 1532*f4a2713aSLionel Sambuc // If Clang supplies this header but the underlying system does not, 1533*f4a2713aSLionel Sambuc // just silently swap in our builtin version. Otherwise, we'll end 1534*f4a2713aSLionel Sambuc // up adding both (later). 1535*f4a2713aSLionel Sambuc if (!File && BuiltinFile) { 1536*f4a2713aSLionel Sambuc File = BuiltinFile; 1537*f4a2713aSLionel Sambuc BuiltinFile = 0; 1538*f4a2713aSLionel Sambuc } 1539*f4a2713aSLionel Sambuc } 1540*f4a2713aSLionel Sambuc } 1541*f4a2713aSLionel Sambuc } 1542*f4a2713aSLionel Sambuc 1543*f4a2713aSLionel Sambuc // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1544*f4a2713aSLionel Sambuc // Come up with a lazy way to do this. 1545*f4a2713aSLionel Sambuc if (File) { 1546*f4a2713aSLionel Sambuc if (LeadingToken == MMToken::UmbrellaKeyword) { 1547*f4a2713aSLionel Sambuc const DirectoryEntry *UmbrellaDir = File->getDir(); 1548*f4a2713aSLionel Sambuc if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1549*f4a2713aSLionel Sambuc Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 1550*f4a2713aSLionel Sambuc << UmbrellaModule->getFullModuleName(); 1551*f4a2713aSLionel Sambuc HadError = true; 1552*f4a2713aSLionel Sambuc } else { 1553*f4a2713aSLionel Sambuc // Record this umbrella header. 1554*f4a2713aSLionel Sambuc Map.setUmbrellaHeader(ActiveModule, File); 1555*f4a2713aSLionel Sambuc } 1556*f4a2713aSLionel Sambuc } else { 1557*f4a2713aSLionel Sambuc // Record this header. 1558*f4a2713aSLionel Sambuc ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1559*f4a2713aSLionel Sambuc if (LeadingToken == MMToken::ExcludeKeyword) 1560*f4a2713aSLionel Sambuc Role = ModuleMap::ExcludedHeader; 1561*f4a2713aSLionel Sambuc else if (LeadingToken == MMToken::PrivateKeyword) 1562*f4a2713aSLionel Sambuc Role = ModuleMap::PrivateHeader; 1563*f4a2713aSLionel Sambuc else 1564*f4a2713aSLionel Sambuc assert(LeadingToken == MMToken::HeaderKeyword); 1565*f4a2713aSLionel Sambuc 1566*f4a2713aSLionel Sambuc Map.addHeader(ActiveModule, File, Role); 1567*f4a2713aSLionel Sambuc 1568*f4a2713aSLionel Sambuc // If there is a builtin counterpart to this file, add it now. 1569*f4a2713aSLionel Sambuc if (BuiltinFile) 1570*f4a2713aSLionel Sambuc Map.addHeader(ActiveModule, BuiltinFile, Role); 1571*f4a2713aSLionel Sambuc } 1572*f4a2713aSLionel Sambuc } else if (LeadingToken != MMToken::ExcludeKeyword) { 1573*f4a2713aSLionel Sambuc // Ignore excluded header files. They're optional anyway. 1574*f4a2713aSLionel Sambuc 1575*f4a2713aSLionel Sambuc Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1576*f4a2713aSLionel Sambuc << (LeadingToken == MMToken::UmbrellaKeyword) << FileName; 1577*f4a2713aSLionel Sambuc HadError = true; 1578*f4a2713aSLionel Sambuc } 1579*f4a2713aSLionel Sambuc } 1580*f4a2713aSLionel Sambuc 1581*f4a2713aSLionel Sambuc /// \brief Parse an umbrella directory declaration. 1582*f4a2713aSLionel Sambuc /// 1583*f4a2713aSLionel Sambuc /// umbrella-dir-declaration: 1584*f4a2713aSLionel Sambuc /// umbrella string-literal 1585*f4a2713aSLionel Sambuc void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1586*f4a2713aSLionel Sambuc // Parse the directory name. 1587*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::StringLiteral)) { 1588*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1589*f4a2713aSLionel Sambuc << "umbrella"; 1590*f4a2713aSLionel Sambuc HadError = true; 1591*f4a2713aSLionel Sambuc return; 1592*f4a2713aSLionel Sambuc } 1593*f4a2713aSLionel Sambuc 1594*f4a2713aSLionel Sambuc std::string DirName = Tok.getString(); 1595*f4a2713aSLionel Sambuc SourceLocation DirNameLoc = consumeToken(); 1596*f4a2713aSLionel Sambuc 1597*f4a2713aSLionel Sambuc // Check whether we already have an umbrella. 1598*f4a2713aSLionel Sambuc if (ActiveModule->Umbrella) { 1599*f4a2713aSLionel Sambuc Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1600*f4a2713aSLionel Sambuc << ActiveModule->getFullModuleName(); 1601*f4a2713aSLionel Sambuc HadError = true; 1602*f4a2713aSLionel Sambuc return; 1603*f4a2713aSLionel Sambuc } 1604*f4a2713aSLionel Sambuc 1605*f4a2713aSLionel Sambuc // Look for this file. 1606*f4a2713aSLionel Sambuc const DirectoryEntry *Dir = 0; 1607*f4a2713aSLionel Sambuc if (llvm::sys::path::is_absolute(DirName)) 1608*f4a2713aSLionel Sambuc Dir = SourceMgr.getFileManager().getDirectory(DirName); 1609*f4a2713aSLionel Sambuc else { 1610*f4a2713aSLionel Sambuc SmallString<128> PathName; 1611*f4a2713aSLionel Sambuc PathName = Directory->getName(); 1612*f4a2713aSLionel Sambuc llvm::sys::path::append(PathName, DirName); 1613*f4a2713aSLionel Sambuc Dir = SourceMgr.getFileManager().getDirectory(PathName); 1614*f4a2713aSLionel Sambuc } 1615*f4a2713aSLionel Sambuc 1616*f4a2713aSLionel Sambuc if (!Dir) { 1617*f4a2713aSLionel Sambuc Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1618*f4a2713aSLionel Sambuc << DirName; 1619*f4a2713aSLionel Sambuc HadError = true; 1620*f4a2713aSLionel Sambuc return; 1621*f4a2713aSLionel Sambuc } 1622*f4a2713aSLionel Sambuc 1623*f4a2713aSLionel Sambuc if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1624*f4a2713aSLionel Sambuc Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1625*f4a2713aSLionel Sambuc << OwningModule->getFullModuleName(); 1626*f4a2713aSLionel Sambuc HadError = true; 1627*f4a2713aSLionel Sambuc return; 1628*f4a2713aSLionel Sambuc } 1629*f4a2713aSLionel Sambuc 1630*f4a2713aSLionel Sambuc // Record this umbrella directory. 1631*f4a2713aSLionel Sambuc Map.setUmbrellaDir(ActiveModule, Dir); 1632*f4a2713aSLionel Sambuc } 1633*f4a2713aSLionel Sambuc 1634*f4a2713aSLionel Sambuc /// \brief Parse a module export declaration. 1635*f4a2713aSLionel Sambuc /// 1636*f4a2713aSLionel Sambuc /// export-declaration: 1637*f4a2713aSLionel Sambuc /// 'export' wildcard-module-id 1638*f4a2713aSLionel Sambuc /// 1639*f4a2713aSLionel Sambuc /// wildcard-module-id: 1640*f4a2713aSLionel Sambuc /// identifier 1641*f4a2713aSLionel Sambuc /// '*' 1642*f4a2713aSLionel Sambuc /// identifier '.' wildcard-module-id 1643*f4a2713aSLionel Sambuc void ModuleMapParser::parseExportDecl() { 1644*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::ExportKeyword)); 1645*f4a2713aSLionel Sambuc SourceLocation ExportLoc = consumeToken(); 1646*f4a2713aSLionel Sambuc 1647*f4a2713aSLionel Sambuc // Parse the module-id with an optional wildcard at the end. 1648*f4a2713aSLionel Sambuc ModuleId ParsedModuleId; 1649*f4a2713aSLionel Sambuc bool Wildcard = false; 1650*f4a2713aSLionel Sambuc do { 1651*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Identifier)) { 1652*f4a2713aSLionel Sambuc ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1653*f4a2713aSLionel Sambuc Tok.getLocation())); 1654*f4a2713aSLionel Sambuc consumeToken(); 1655*f4a2713aSLionel Sambuc 1656*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Period)) { 1657*f4a2713aSLionel Sambuc consumeToken(); 1658*f4a2713aSLionel Sambuc continue; 1659*f4a2713aSLionel Sambuc } 1660*f4a2713aSLionel Sambuc 1661*f4a2713aSLionel Sambuc break; 1662*f4a2713aSLionel Sambuc } 1663*f4a2713aSLionel Sambuc 1664*f4a2713aSLionel Sambuc if(Tok.is(MMToken::Star)) { 1665*f4a2713aSLionel Sambuc Wildcard = true; 1666*f4a2713aSLionel Sambuc consumeToken(); 1667*f4a2713aSLionel Sambuc break; 1668*f4a2713aSLionel Sambuc } 1669*f4a2713aSLionel Sambuc 1670*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 1671*f4a2713aSLionel Sambuc HadError = true; 1672*f4a2713aSLionel Sambuc return; 1673*f4a2713aSLionel Sambuc } while (true); 1674*f4a2713aSLionel Sambuc 1675*f4a2713aSLionel Sambuc Module::UnresolvedExportDecl Unresolved = { 1676*f4a2713aSLionel Sambuc ExportLoc, ParsedModuleId, Wildcard 1677*f4a2713aSLionel Sambuc }; 1678*f4a2713aSLionel Sambuc ActiveModule->UnresolvedExports.push_back(Unresolved); 1679*f4a2713aSLionel Sambuc } 1680*f4a2713aSLionel Sambuc 1681*f4a2713aSLionel Sambuc /// \brief Parse a module uses declaration. 1682*f4a2713aSLionel Sambuc /// 1683*f4a2713aSLionel Sambuc /// uses-declaration: 1684*f4a2713aSLionel Sambuc /// 'uses' wildcard-module-id 1685*f4a2713aSLionel Sambuc void ModuleMapParser::parseUseDecl() { 1686*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::UseKeyword)); 1687*f4a2713aSLionel Sambuc consumeToken(); 1688*f4a2713aSLionel Sambuc // Parse the module-id. 1689*f4a2713aSLionel Sambuc ModuleId ParsedModuleId; 1690*f4a2713aSLionel Sambuc 1691*f4a2713aSLionel Sambuc do { 1692*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Identifier)) { 1693*f4a2713aSLionel Sambuc ParsedModuleId.push_back( 1694*f4a2713aSLionel Sambuc std::make_pair(Tok.getString(), Tok.getLocation())); 1695*f4a2713aSLionel Sambuc consumeToken(); 1696*f4a2713aSLionel Sambuc 1697*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Period)) { 1698*f4a2713aSLionel Sambuc consumeToken(); 1699*f4a2713aSLionel Sambuc continue; 1700*f4a2713aSLionel Sambuc } 1701*f4a2713aSLionel Sambuc 1702*f4a2713aSLionel Sambuc break; 1703*f4a2713aSLionel Sambuc } 1704*f4a2713aSLionel Sambuc 1705*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 1706*f4a2713aSLionel Sambuc HadError = true; 1707*f4a2713aSLionel Sambuc return; 1708*f4a2713aSLionel Sambuc } while (true); 1709*f4a2713aSLionel Sambuc 1710*f4a2713aSLionel Sambuc ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1711*f4a2713aSLionel Sambuc } 1712*f4a2713aSLionel Sambuc 1713*f4a2713aSLionel Sambuc /// \brief Parse a link declaration. 1714*f4a2713aSLionel Sambuc /// 1715*f4a2713aSLionel Sambuc /// module-declaration: 1716*f4a2713aSLionel Sambuc /// 'link' 'framework'[opt] string-literal 1717*f4a2713aSLionel Sambuc void ModuleMapParser::parseLinkDecl() { 1718*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::LinkKeyword)); 1719*f4a2713aSLionel Sambuc SourceLocation LinkLoc = consumeToken(); 1720*f4a2713aSLionel Sambuc 1721*f4a2713aSLionel Sambuc // Parse the optional 'framework' keyword. 1722*f4a2713aSLionel Sambuc bool IsFramework = false; 1723*f4a2713aSLionel Sambuc if (Tok.is(MMToken::FrameworkKeyword)) { 1724*f4a2713aSLionel Sambuc consumeToken(); 1725*f4a2713aSLionel Sambuc IsFramework = true; 1726*f4a2713aSLionel Sambuc } 1727*f4a2713aSLionel Sambuc 1728*f4a2713aSLionel Sambuc // Parse the library name 1729*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::StringLiteral)) { 1730*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1731*f4a2713aSLionel Sambuc << IsFramework << SourceRange(LinkLoc); 1732*f4a2713aSLionel Sambuc HadError = true; 1733*f4a2713aSLionel Sambuc return; 1734*f4a2713aSLionel Sambuc } 1735*f4a2713aSLionel Sambuc 1736*f4a2713aSLionel Sambuc std::string LibraryName = Tok.getString(); 1737*f4a2713aSLionel Sambuc consumeToken(); 1738*f4a2713aSLionel Sambuc ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1739*f4a2713aSLionel Sambuc IsFramework)); 1740*f4a2713aSLionel Sambuc } 1741*f4a2713aSLionel Sambuc 1742*f4a2713aSLionel Sambuc /// \brief Parse a configuration macro declaration. 1743*f4a2713aSLionel Sambuc /// 1744*f4a2713aSLionel Sambuc /// module-declaration: 1745*f4a2713aSLionel Sambuc /// 'config_macros' attributes[opt] config-macro-list? 1746*f4a2713aSLionel Sambuc /// 1747*f4a2713aSLionel Sambuc /// config-macro-list: 1748*f4a2713aSLionel Sambuc /// identifier (',' identifier)? 1749*f4a2713aSLionel Sambuc void ModuleMapParser::parseConfigMacros() { 1750*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::ConfigMacros)); 1751*f4a2713aSLionel Sambuc SourceLocation ConfigMacrosLoc = consumeToken(); 1752*f4a2713aSLionel Sambuc 1753*f4a2713aSLionel Sambuc // Only top-level modules can have configuration macros. 1754*f4a2713aSLionel Sambuc if (ActiveModule->Parent) { 1755*f4a2713aSLionel Sambuc Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 1756*f4a2713aSLionel Sambuc } 1757*f4a2713aSLionel Sambuc 1758*f4a2713aSLionel Sambuc // Parse the optional attributes. 1759*f4a2713aSLionel Sambuc Attributes Attrs; 1760*f4a2713aSLionel Sambuc parseOptionalAttributes(Attrs); 1761*f4a2713aSLionel Sambuc if (Attrs.IsExhaustive && !ActiveModule->Parent) { 1762*f4a2713aSLionel Sambuc ActiveModule->ConfigMacrosExhaustive = true; 1763*f4a2713aSLionel Sambuc } 1764*f4a2713aSLionel Sambuc 1765*f4a2713aSLionel Sambuc // If we don't have an identifier, we're done. 1766*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Identifier)) 1767*f4a2713aSLionel Sambuc return; 1768*f4a2713aSLionel Sambuc 1769*f4a2713aSLionel Sambuc // Consume the first identifier. 1770*f4a2713aSLionel Sambuc if (!ActiveModule->Parent) { 1771*f4a2713aSLionel Sambuc ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1772*f4a2713aSLionel Sambuc } 1773*f4a2713aSLionel Sambuc consumeToken(); 1774*f4a2713aSLionel Sambuc 1775*f4a2713aSLionel Sambuc do { 1776*f4a2713aSLionel Sambuc // If there's a comma, consume it. 1777*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Comma)) 1778*f4a2713aSLionel Sambuc break; 1779*f4a2713aSLionel Sambuc consumeToken(); 1780*f4a2713aSLionel Sambuc 1781*f4a2713aSLionel Sambuc // We expect to see a macro name here. 1782*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Identifier)) { 1783*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 1784*f4a2713aSLionel Sambuc break; 1785*f4a2713aSLionel Sambuc } 1786*f4a2713aSLionel Sambuc 1787*f4a2713aSLionel Sambuc // Consume the macro name. 1788*f4a2713aSLionel Sambuc if (!ActiveModule->Parent) { 1789*f4a2713aSLionel Sambuc ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1790*f4a2713aSLionel Sambuc } 1791*f4a2713aSLionel Sambuc consumeToken(); 1792*f4a2713aSLionel Sambuc } while (true); 1793*f4a2713aSLionel Sambuc } 1794*f4a2713aSLionel Sambuc 1795*f4a2713aSLionel Sambuc /// \brief Format a module-id into a string. 1796*f4a2713aSLionel Sambuc static std::string formatModuleId(const ModuleId &Id) { 1797*f4a2713aSLionel Sambuc std::string result; 1798*f4a2713aSLionel Sambuc { 1799*f4a2713aSLionel Sambuc llvm::raw_string_ostream OS(result); 1800*f4a2713aSLionel Sambuc 1801*f4a2713aSLionel Sambuc for (unsigned I = 0, N = Id.size(); I != N; ++I) { 1802*f4a2713aSLionel Sambuc if (I) 1803*f4a2713aSLionel Sambuc OS << "."; 1804*f4a2713aSLionel Sambuc OS << Id[I].first; 1805*f4a2713aSLionel Sambuc } 1806*f4a2713aSLionel Sambuc } 1807*f4a2713aSLionel Sambuc 1808*f4a2713aSLionel Sambuc return result; 1809*f4a2713aSLionel Sambuc } 1810*f4a2713aSLionel Sambuc 1811*f4a2713aSLionel Sambuc /// \brief Parse a conflict declaration. 1812*f4a2713aSLionel Sambuc /// 1813*f4a2713aSLionel Sambuc /// module-declaration: 1814*f4a2713aSLionel Sambuc /// 'conflict' module-id ',' string-literal 1815*f4a2713aSLionel Sambuc void ModuleMapParser::parseConflict() { 1816*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::Conflict)); 1817*f4a2713aSLionel Sambuc SourceLocation ConflictLoc = consumeToken(); 1818*f4a2713aSLionel Sambuc Module::UnresolvedConflict Conflict; 1819*f4a2713aSLionel Sambuc 1820*f4a2713aSLionel Sambuc // Parse the module-id. 1821*f4a2713aSLionel Sambuc if (parseModuleId(Conflict.Id)) 1822*f4a2713aSLionel Sambuc return; 1823*f4a2713aSLionel Sambuc 1824*f4a2713aSLionel Sambuc // Parse the ','. 1825*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Comma)) { 1826*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 1827*f4a2713aSLionel Sambuc << SourceRange(ConflictLoc); 1828*f4a2713aSLionel Sambuc return; 1829*f4a2713aSLionel Sambuc } 1830*f4a2713aSLionel Sambuc consumeToken(); 1831*f4a2713aSLionel Sambuc 1832*f4a2713aSLionel Sambuc // Parse the message. 1833*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::StringLiteral)) { 1834*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 1835*f4a2713aSLionel Sambuc << formatModuleId(Conflict.Id); 1836*f4a2713aSLionel Sambuc return; 1837*f4a2713aSLionel Sambuc } 1838*f4a2713aSLionel Sambuc Conflict.Message = Tok.getString().str(); 1839*f4a2713aSLionel Sambuc consumeToken(); 1840*f4a2713aSLionel Sambuc 1841*f4a2713aSLionel Sambuc // Add this unresolved conflict. 1842*f4a2713aSLionel Sambuc ActiveModule->UnresolvedConflicts.push_back(Conflict); 1843*f4a2713aSLionel Sambuc } 1844*f4a2713aSLionel Sambuc 1845*f4a2713aSLionel Sambuc /// \brief Parse an inferred module declaration (wildcard modules). 1846*f4a2713aSLionel Sambuc /// 1847*f4a2713aSLionel Sambuc /// module-declaration: 1848*f4a2713aSLionel Sambuc /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 1849*f4a2713aSLionel Sambuc /// { inferred-module-member* } 1850*f4a2713aSLionel Sambuc /// 1851*f4a2713aSLionel Sambuc /// inferred-module-member: 1852*f4a2713aSLionel Sambuc /// 'export' '*' 1853*f4a2713aSLionel Sambuc /// 'exclude' identifier 1854*f4a2713aSLionel Sambuc void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 1855*f4a2713aSLionel Sambuc assert(Tok.is(MMToken::Star)); 1856*f4a2713aSLionel Sambuc SourceLocation StarLoc = consumeToken(); 1857*f4a2713aSLionel Sambuc bool Failed = false; 1858*f4a2713aSLionel Sambuc 1859*f4a2713aSLionel Sambuc // Inferred modules must be submodules. 1860*f4a2713aSLionel Sambuc if (!ActiveModule && !Framework) { 1861*f4a2713aSLionel Sambuc Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 1862*f4a2713aSLionel Sambuc Failed = true; 1863*f4a2713aSLionel Sambuc } 1864*f4a2713aSLionel Sambuc 1865*f4a2713aSLionel Sambuc if (ActiveModule) { 1866*f4a2713aSLionel Sambuc // Inferred modules must have umbrella directories. 1867*f4a2713aSLionel Sambuc if (!Failed && !ActiveModule->getUmbrellaDir()) { 1868*f4a2713aSLionel Sambuc Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 1869*f4a2713aSLionel Sambuc Failed = true; 1870*f4a2713aSLionel Sambuc } 1871*f4a2713aSLionel Sambuc 1872*f4a2713aSLionel Sambuc // Check for redefinition of an inferred module. 1873*f4a2713aSLionel Sambuc if (!Failed && ActiveModule->InferSubmodules) { 1874*f4a2713aSLionel Sambuc Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 1875*f4a2713aSLionel Sambuc if (ActiveModule->InferredSubmoduleLoc.isValid()) 1876*f4a2713aSLionel Sambuc Diags.Report(ActiveModule->InferredSubmoduleLoc, 1877*f4a2713aSLionel Sambuc diag::note_mmap_prev_definition); 1878*f4a2713aSLionel Sambuc Failed = true; 1879*f4a2713aSLionel Sambuc } 1880*f4a2713aSLionel Sambuc 1881*f4a2713aSLionel Sambuc // Check for the 'framework' keyword, which is not permitted here. 1882*f4a2713aSLionel Sambuc if (Framework) { 1883*f4a2713aSLionel Sambuc Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 1884*f4a2713aSLionel Sambuc Framework = false; 1885*f4a2713aSLionel Sambuc } 1886*f4a2713aSLionel Sambuc } else if (Explicit) { 1887*f4a2713aSLionel Sambuc Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 1888*f4a2713aSLionel Sambuc Explicit = false; 1889*f4a2713aSLionel Sambuc } 1890*f4a2713aSLionel Sambuc 1891*f4a2713aSLionel Sambuc // If there were any problems with this inferred submodule, skip its body. 1892*f4a2713aSLionel Sambuc if (Failed) { 1893*f4a2713aSLionel Sambuc if (Tok.is(MMToken::LBrace)) { 1894*f4a2713aSLionel Sambuc consumeToken(); 1895*f4a2713aSLionel Sambuc skipUntil(MMToken::RBrace); 1896*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RBrace)) 1897*f4a2713aSLionel Sambuc consumeToken(); 1898*f4a2713aSLionel Sambuc } 1899*f4a2713aSLionel Sambuc HadError = true; 1900*f4a2713aSLionel Sambuc return; 1901*f4a2713aSLionel Sambuc } 1902*f4a2713aSLionel Sambuc 1903*f4a2713aSLionel Sambuc // Parse optional attributes. 1904*f4a2713aSLionel Sambuc Attributes Attrs; 1905*f4a2713aSLionel Sambuc parseOptionalAttributes(Attrs); 1906*f4a2713aSLionel Sambuc 1907*f4a2713aSLionel Sambuc if (ActiveModule) { 1908*f4a2713aSLionel Sambuc // Note that we have an inferred submodule. 1909*f4a2713aSLionel Sambuc ActiveModule->InferSubmodules = true; 1910*f4a2713aSLionel Sambuc ActiveModule->InferredSubmoduleLoc = StarLoc; 1911*f4a2713aSLionel Sambuc ActiveModule->InferExplicitSubmodules = Explicit; 1912*f4a2713aSLionel Sambuc } else { 1913*f4a2713aSLionel Sambuc // We'll be inferring framework modules for this directory. 1914*f4a2713aSLionel Sambuc Map.InferredDirectories[Directory].InferModules = true; 1915*f4a2713aSLionel Sambuc Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 1916*f4a2713aSLionel Sambuc } 1917*f4a2713aSLionel Sambuc 1918*f4a2713aSLionel Sambuc // Parse the opening brace. 1919*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::LBrace)) { 1920*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 1921*f4a2713aSLionel Sambuc HadError = true; 1922*f4a2713aSLionel Sambuc return; 1923*f4a2713aSLionel Sambuc } 1924*f4a2713aSLionel Sambuc SourceLocation LBraceLoc = consumeToken(); 1925*f4a2713aSLionel Sambuc 1926*f4a2713aSLionel Sambuc // Parse the body of the inferred submodule. 1927*f4a2713aSLionel Sambuc bool Done = false; 1928*f4a2713aSLionel Sambuc do { 1929*f4a2713aSLionel Sambuc switch (Tok.Kind) { 1930*f4a2713aSLionel Sambuc case MMToken::EndOfFile: 1931*f4a2713aSLionel Sambuc case MMToken::RBrace: 1932*f4a2713aSLionel Sambuc Done = true; 1933*f4a2713aSLionel Sambuc break; 1934*f4a2713aSLionel Sambuc 1935*f4a2713aSLionel Sambuc case MMToken::ExcludeKeyword: { 1936*f4a2713aSLionel Sambuc if (ActiveModule) { 1937*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1938*f4a2713aSLionel Sambuc << (ActiveModule != 0); 1939*f4a2713aSLionel Sambuc consumeToken(); 1940*f4a2713aSLionel Sambuc break; 1941*f4a2713aSLionel Sambuc } 1942*f4a2713aSLionel Sambuc 1943*f4a2713aSLionel Sambuc consumeToken(); 1944*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Identifier)) { 1945*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 1946*f4a2713aSLionel Sambuc break; 1947*f4a2713aSLionel Sambuc } 1948*f4a2713aSLionel Sambuc 1949*f4a2713aSLionel Sambuc Map.InferredDirectories[Directory].ExcludedModules 1950*f4a2713aSLionel Sambuc .push_back(Tok.getString()); 1951*f4a2713aSLionel Sambuc consumeToken(); 1952*f4a2713aSLionel Sambuc break; 1953*f4a2713aSLionel Sambuc } 1954*f4a2713aSLionel Sambuc 1955*f4a2713aSLionel Sambuc case MMToken::ExportKeyword: 1956*f4a2713aSLionel Sambuc if (!ActiveModule) { 1957*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1958*f4a2713aSLionel Sambuc << (ActiveModule != 0); 1959*f4a2713aSLionel Sambuc consumeToken(); 1960*f4a2713aSLionel Sambuc break; 1961*f4a2713aSLionel Sambuc } 1962*f4a2713aSLionel Sambuc 1963*f4a2713aSLionel Sambuc consumeToken(); 1964*f4a2713aSLionel Sambuc if (Tok.is(MMToken::Star)) 1965*f4a2713aSLionel Sambuc ActiveModule->InferExportWildcard = true; 1966*f4a2713aSLionel Sambuc else 1967*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), 1968*f4a2713aSLionel Sambuc diag::err_mmap_expected_export_wildcard); 1969*f4a2713aSLionel Sambuc consumeToken(); 1970*f4a2713aSLionel Sambuc break; 1971*f4a2713aSLionel Sambuc 1972*f4a2713aSLionel Sambuc case MMToken::ExplicitKeyword: 1973*f4a2713aSLionel Sambuc case MMToken::ModuleKeyword: 1974*f4a2713aSLionel Sambuc case MMToken::HeaderKeyword: 1975*f4a2713aSLionel Sambuc case MMToken::PrivateKeyword: 1976*f4a2713aSLionel Sambuc case MMToken::UmbrellaKeyword: 1977*f4a2713aSLionel Sambuc default: 1978*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1979*f4a2713aSLionel Sambuc << (ActiveModule != 0); 1980*f4a2713aSLionel Sambuc consumeToken(); 1981*f4a2713aSLionel Sambuc break; 1982*f4a2713aSLionel Sambuc } 1983*f4a2713aSLionel Sambuc } while (!Done); 1984*f4a2713aSLionel Sambuc 1985*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RBrace)) 1986*f4a2713aSLionel Sambuc consumeToken(); 1987*f4a2713aSLionel Sambuc else { 1988*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1989*f4a2713aSLionel Sambuc Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1990*f4a2713aSLionel Sambuc HadError = true; 1991*f4a2713aSLionel Sambuc } 1992*f4a2713aSLionel Sambuc } 1993*f4a2713aSLionel Sambuc 1994*f4a2713aSLionel Sambuc /// \brief Parse optional attributes. 1995*f4a2713aSLionel Sambuc /// 1996*f4a2713aSLionel Sambuc /// attributes: 1997*f4a2713aSLionel Sambuc /// attribute attributes 1998*f4a2713aSLionel Sambuc /// attribute 1999*f4a2713aSLionel Sambuc /// 2000*f4a2713aSLionel Sambuc /// attribute: 2001*f4a2713aSLionel Sambuc /// [ identifier ] 2002*f4a2713aSLionel Sambuc /// 2003*f4a2713aSLionel Sambuc /// \param Attrs Will be filled in with the parsed attributes. 2004*f4a2713aSLionel Sambuc /// 2005*f4a2713aSLionel Sambuc /// \returns true if an error occurred, false otherwise. 2006*f4a2713aSLionel Sambuc bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2007*f4a2713aSLionel Sambuc bool HadError = false; 2008*f4a2713aSLionel Sambuc 2009*f4a2713aSLionel Sambuc while (Tok.is(MMToken::LSquare)) { 2010*f4a2713aSLionel Sambuc // Consume the '['. 2011*f4a2713aSLionel Sambuc SourceLocation LSquareLoc = consumeToken(); 2012*f4a2713aSLionel Sambuc 2013*f4a2713aSLionel Sambuc // Check whether we have an attribute name here. 2014*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::Identifier)) { 2015*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2016*f4a2713aSLionel Sambuc skipUntil(MMToken::RSquare); 2017*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RSquare)) 2018*f4a2713aSLionel Sambuc consumeToken(); 2019*f4a2713aSLionel Sambuc HadError = true; 2020*f4a2713aSLionel Sambuc } 2021*f4a2713aSLionel Sambuc 2022*f4a2713aSLionel Sambuc // Decode the attribute name. 2023*f4a2713aSLionel Sambuc AttributeKind Attribute 2024*f4a2713aSLionel Sambuc = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2025*f4a2713aSLionel Sambuc .Case("exhaustive", AT_exhaustive) 2026*f4a2713aSLionel Sambuc .Case("system", AT_system) 2027*f4a2713aSLionel Sambuc .Default(AT_unknown); 2028*f4a2713aSLionel Sambuc switch (Attribute) { 2029*f4a2713aSLionel Sambuc case AT_unknown: 2030*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2031*f4a2713aSLionel Sambuc << Tok.getString(); 2032*f4a2713aSLionel Sambuc break; 2033*f4a2713aSLionel Sambuc 2034*f4a2713aSLionel Sambuc case AT_system: 2035*f4a2713aSLionel Sambuc Attrs.IsSystem = true; 2036*f4a2713aSLionel Sambuc break; 2037*f4a2713aSLionel Sambuc 2038*f4a2713aSLionel Sambuc case AT_exhaustive: 2039*f4a2713aSLionel Sambuc Attrs.IsExhaustive = true; 2040*f4a2713aSLionel Sambuc break; 2041*f4a2713aSLionel Sambuc } 2042*f4a2713aSLionel Sambuc consumeToken(); 2043*f4a2713aSLionel Sambuc 2044*f4a2713aSLionel Sambuc // Consume the ']'. 2045*f4a2713aSLionel Sambuc if (!Tok.is(MMToken::RSquare)) { 2046*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2047*f4a2713aSLionel Sambuc Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2048*f4a2713aSLionel Sambuc skipUntil(MMToken::RSquare); 2049*f4a2713aSLionel Sambuc HadError = true; 2050*f4a2713aSLionel Sambuc } 2051*f4a2713aSLionel Sambuc 2052*f4a2713aSLionel Sambuc if (Tok.is(MMToken::RSquare)) 2053*f4a2713aSLionel Sambuc consumeToken(); 2054*f4a2713aSLionel Sambuc } 2055*f4a2713aSLionel Sambuc 2056*f4a2713aSLionel Sambuc return HadError; 2057*f4a2713aSLionel Sambuc } 2058*f4a2713aSLionel Sambuc 2059*f4a2713aSLionel Sambuc /// \brief If there is a specific header search directory due the presence 2060*f4a2713aSLionel Sambuc /// of an umbrella directory, retrieve that directory. Otherwise, returns null. 2061*f4a2713aSLionel Sambuc const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 2062*f4a2713aSLionel Sambuc for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 2063*f4a2713aSLionel Sambuc // If we have an umbrella directory, use that. 2064*f4a2713aSLionel Sambuc if (Mod->hasUmbrellaDir()) 2065*f4a2713aSLionel Sambuc return Mod->getUmbrellaDir(); 2066*f4a2713aSLionel Sambuc 2067*f4a2713aSLionel Sambuc // If we have a framework directory, stop looking. 2068*f4a2713aSLionel Sambuc if (Mod->IsFramework) 2069*f4a2713aSLionel Sambuc return 0; 2070*f4a2713aSLionel Sambuc } 2071*f4a2713aSLionel Sambuc 2072*f4a2713aSLionel Sambuc return 0; 2073*f4a2713aSLionel Sambuc } 2074*f4a2713aSLionel Sambuc 2075*f4a2713aSLionel Sambuc /// \brief Parse a module map file. 2076*f4a2713aSLionel Sambuc /// 2077*f4a2713aSLionel Sambuc /// module-map-file: 2078*f4a2713aSLionel Sambuc /// module-declaration* 2079*f4a2713aSLionel Sambuc bool ModuleMapParser::parseModuleMapFile() { 2080*f4a2713aSLionel Sambuc do { 2081*f4a2713aSLionel Sambuc switch (Tok.Kind) { 2082*f4a2713aSLionel Sambuc case MMToken::EndOfFile: 2083*f4a2713aSLionel Sambuc return HadError; 2084*f4a2713aSLionel Sambuc 2085*f4a2713aSLionel Sambuc case MMToken::ExplicitKeyword: 2086*f4a2713aSLionel Sambuc case MMToken::ExternKeyword: 2087*f4a2713aSLionel Sambuc case MMToken::ModuleKeyword: 2088*f4a2713aSLionel Sambuc case MMToken::FrameworkKeyword: 2089*f4a2713aSLionel Sambuc parseModuleDecl(); 2090*f4a2713aSLionel Sambuc break; 2091*f4a2713aSLionel Sambuc 2092*f4a2713aSLionel Sambuc case MMToken::Comma: 2093*f4a2713aSLionel Sambuc case MMToken::ConfigMacros: 2094*f4a2713aSLionel Sambuc case MMToken::Conflict: 2095*f4a2713aSLionel Sambuc case MMToken::Exclaim: 2096*f4a2713aSLionel Sambuc case MMToken::ExcludeKeyword: 2097*f4a2713aSLionel Sambuc case MMToken::ExportKeyword: 2098*f4a2713aSLionel Sambuc case MMToken::HeaderKeyword: 2099*f4a2713aSLionel Sambuc case MMToken::Identifier: 2100*f4a2713aSLionel Sambuc case MMToken::LBrace: 2101*f4a2713aSLionel Sambuc case MMToken::LinkKeyword: 2102*f4a2713aSLionel Sambuc case MMToken::LSquare: 2103*f4a2713aSLionel Sambuc case MMToken::Period: 2104*f4a2713aSLionel Sambuc case MMToken::PrivateKeyword: 2105*f4a2713aSLionel Sambuc case MMToken::RBrace: 2106*f4a2713aSLionel Sambuc case MMToken::RSquare: 2107*f4a2713aSLionel Sambuc case MMToken::RequiresKeyword: 2108*f4a2713aSLionel Sambuc case MMToken::Star: 2109*f4a2713aSLionel Sambuc case MMToken::StringLiteral: 2110*f4a2713aSLionel Sambuc case MMToken::UmbrellaKeyword: 2111*f4a2713aSLionel Sambuc case MMToken::UseKeyword: 2112*f4a2713aSLionel Sambuc Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2113*f4a2713aSLionel Sambuc HadError = true; 2114*f4a2713aSLionel Sambuc consumeToken(); 2115*f4a2713aSLionel Sambuc break; 2116*f4a2713aSLionel Sambuc } 2117*f4a2713aSLionel Sambuc } while (true); 2118*f4a2713aSLionel Sambuc } 2119*f4a2713aSLionel Sambuc 2120*f4a2713aSLionel Sambuc bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { 2121*f4a2713aSLionel Sambuc llvm::DenseMap<const FileEntry *, bool>::iterator Known 2122*f4a2713aSLionel Sambuc = ParsedModuleMap.find(File); 2123*f4a2713aSLionel Sambuc if (Known != ParsedModuleMap.end()) 2124*f4a2713aSLionel Sambuc return Known->second; 2125*f4a2713aSLionel Sambuc 2126*f4a2713aSLionel Sambuc assert(Target != 0 && "Missing target information"); 2127*f4a2713aSLionel Sambuc FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User); 2128*f4a2713aSLionel Sambuc const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2129*f4a2713aSLionel Sambuc if (!Buffer) 2130*f4a2713aSLionel Sambuc return ParsedModuleMap[File] = true; 2131*f4a2713aSLionel Sambuc 2132*f4a2713aSLionel Sambuc // Parse this module map file. 2133*f4a2713aSLionel Sambuc Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 2134*f4a2713aSLionel Sambuc Diags->getClient()->BeginSourceFile(MMapLangOpts); 2135*f4a2713aSLionel Sambuc ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(), 2136*f4a2713aSLionel Sambuc BuiltinIncludeDir, IsSystem); 2137*f4a2713aSLionel Sambuc bool Result = Parser.parseModuleMapFile(); 2138*f4a2713aSLionel Sambuc Diags->getClient()->EndSourceFile(); 2139*f4a2713aSLionel Sambuc ParsedModuleMap[File] = Result; 2140*f4a2713aSLionel Sambuc return Result; 2141*f4a2713aSLionel Sambuc } 2142