1a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// 2a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 3a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// The LLVM Compiler Infrastructure 4a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 5a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// This file is distributed under the University of Illinois Open Source 6a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// License. See LICENSE.TXT for details. 7a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 8a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//===----------------------------------------------------------------------===// 9a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 10a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// This file defines the ModuleMap implementation, which describes the layout 11a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// of a module as it relates to headers. 12a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// 13a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//===----------------------------------------------------------------------===// 14a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Lex/ModuleMap.h" 153f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose#include "clang/Basic/CharInfo.h" 16a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/Diagnostic.h" 1702c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor#include "clang/Basic/DiagnosticOptions.h" 18a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/FileManager.h" 19a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/TargetInfo.h" 20a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/TargetOptions.h" 2155ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "clang/Lex/HeaderSearchOptions.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/LexDiagnostic.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/LiteralSupport.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringRef.h" 2755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h" 28a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/Allocator.h" 29ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor#include "llvm/Support/FileSystem.h" 30a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/Host.h" 318229d22e6449851b89361bf2f41804557328be63Rafael Espindola#include "llvm/Support/Path.h" 32a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/raw_ostream.h" 3398cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor#include <stdlib.h> 343cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#if defined(LLVM_ON_UNIX) 35adeb7822cb7947194fef0e12d2d6583ccb8240b5Dmitri Gribenko#include <limits.h> 363cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#endif 37a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorusing namespace clang; 38a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 3990db26000aefe9335370013eec64c85232d80227Douglas GregorModule::ExportDecl 4090db26000aefe9335370013eec64c85232d80227Douglas GregorModuleMap::resolveExport(Module *Mod, 4190db26000aefe9335370013eec64c85232d80227Douglas Gregor const Module::UnresolvedExportDecl &Unresolved, 420be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis bool Complain) const { 430adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor // We may have just a wildcard. 440adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Unresolved.Id.empty()) { 450adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor assert(Unresolved.Wildcard && "Invalid unresolved export"); 466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Module::ExportDecl(nullptr, true); 470adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor } 480adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor 49906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Resolve the module-id. 50906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 51906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Context) 52906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Module::ExportDecl(); 53906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 54906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Module::ExportDecl(Context, Unresolved.Wildcard); 55906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 56906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 57906d66acc5cf2679453e10a4f0a67feedd765b21Douglas GregorModule *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 58906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor bool Complain) const { 5990db26000aefe9335370013eec64c85232d80227Douglas Gregor // Find the starting module. 60906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 6190db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) { 6290db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Complain) 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 64906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << Id[0].first << Mod->getFullModuleName(); 65906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6790db26000aefe9335370013eec64c85232d80227Douglas Gregor } 6890db26000aefe9335370013eec64c85232d80227Douglas Gregor 6990db26000aefe9335370013eec64c85232d80227Douglas Gregor // Dig into the module path. 70906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 1, N = Id.size(); I != N; ++I) { 71906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *Sub = lookupModuleQualified(Id[I].first, Context); 7290db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Sub) { 7390db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Complain) 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 75906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << Id[I].first << Context->getFullModuleName() 76906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << SourceRange(Id[0].second, Id[I-1].second); 77906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 7990db26000aefe9335370013eec64c85232d80227Douglas Gregor } 80906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 8190db26000aefe9335370013eec64c85232d80227Douglas Gregor Context = Sub; 8290db26000aefe9335370013eec64c85232d80227Douglas Gregor } 83906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 84906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Context; 8590db26000aefe9335370013eec64c85232d80227Douglas Gregor} 8690db26000aefe9335370013eec64c85232d80227Douglas Gregor 87651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 8855ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis const LangOptions &LangOpts, const TargetInfo *Target, 8955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HeaderSearch &HeaderInfo) 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), 920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CompilingModule(nullptr), SourceModule(nullptr) { 930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines MMapLangOpts.LineComment = true; 940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 95a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 96a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorModuleMap::~ModuleMap() { 9709fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 9809fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor IEnd = Modules.end(); 9909fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor I != IEnd; ++I) { 10009fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor delete I->getValue(); 10109fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor } 102a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 103a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 104dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregorvoid ModuleMap::setTarget(const TargetInfo &Target) { 105dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor assert((!this->Target || this->Target == &Target) && 106dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor "Improper target override"); 107dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor this->Target = &Target; 108dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor} 109dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor 1108b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor/// \brief "Sanitize" a filename so that it can be used as an identifier. 1118b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregorstatic StringRef sanitizeFilenameAsIdentifier(StringRef Name, 1128b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallVectorImpl<char> &Buffer) { 1138b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor if (Name.empty()) 1148b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor return Name; 1158b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1163f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (!isValidIdentifier(Name)) { 1178b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor // If we don't already have something with the form of an identifier, 1188b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor // create a buffer with the sanitized name. 1198b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.clear(); 1203f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isDigit(Name[0])) 1218b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1228b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.reserve(Buffer.size() + Name.size()); 1238b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor for (unsigned I = 0, N = Name.size(); I != N; ++I) { 1243f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isIdentifierBody(Name[I])) 1258b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back(Name[I]); 1268b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor else 1278b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1288b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1298b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1308b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Name = StringRef(Buffer.data(), Buffer.size()); 1318b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1328b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1338b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor while (llvm::StringSwitch<bool>(Name) 1348b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 1358b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 1368b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#include "clang/Basic/TokenKinds.def" 1378b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor .Default(false)) { 1388b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor if (Name.data() != Buffer.data()) 1398b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.append(Name.begin(), Name.end()); 1408b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1418b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Name = StringRef(Buffer.data(), Buffer.size()); 1428b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1438b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1448b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor return Name; 1458b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor} 1468b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 147db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// \brief Determine whether the given file name is the name of a builtin 148db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// header, supplied by Clang to replace, override, or augment existing system 149db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// headers. 150db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregorstatic bool isBuiltinHeader(StringRef FileName) { 151db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor return llvm::StringSwitch<bool>(FileName) 152db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("float.h", true) 153db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("iso646.h", true) 154db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("limits.h", true) 155db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdalign.h", true) 156db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdarg.h", true) 157db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdbool.h", true) 158db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stddef.h", true) 159db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdint.h", true) 160db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("tgmath.h", true) 161db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("unwind.h", true) 162db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Default(false); 163db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor} 164db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 165651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModuleMap::HeadersMap::iterator 166651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModuleMap::findKnownHeader(const FileEntry *File) { 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeadersMap::iterator Known = Headers.find(File); 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir && 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderInfo.loadTopLevelSystemModules(); 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Headers.find(File); 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Known; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::KnownHeader 1776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, 1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { 1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DirectoryEntry *Dir = File->getDir(); 1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Dir && "file in no directory"); 1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Note: as an egregious but useful hack we use the real path here, because 1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // frameworks moving from top-level frameworks to embedded frameworks tend 1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // to be symlinked from the top-level location to the embedded location, 1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // and we need to resolve lookups as if we had found the embedded location. 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 1876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Keep walking up the directory hierarchy, looking for a directory with 1896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // an umbrella header. 1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines do { 1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto KnownDir = UmbrellaDirs.find(Dir); 1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (KnownDir != UmbrellaDirs.end()) 1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return KnownHeader(KnownDir->second, NormalHeader); 1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntermediateDirs.push_back(Dir); 1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Retrieve our parent path. 1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DirName = llvm::sys::path::parent_path(DirName); 1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (DirName.empty()) 2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Resolve the parent path to a directory entry. 2036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Dir = SourceMgr.getFileManager().getDirectory(DirName); 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } while (Dir); 2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return KnownHeader(); 2066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 2076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool violatesPrivateInclude(Module *RequestingModule, 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *IncFileEnt, 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ModuleMap::ModuleHeaderRole Role, 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Module *RequestedModule) { 212176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool IsPrivateRole = Role & ModuleMap::PrivateHeader; 213176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef NDEBUG 2143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (IsPrivateRole) { 2153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Check for consistency between the module header role 2163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // as obtained from the lookup and as obtained from the module. 2173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // This check is not cheap, so enable it only for debugging. 2183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool IsPrivate = false; 2193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SmallVectorImpl<Module::Header> *HeaderList[] = { 2203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar &RequestedModule->Headers[Module::HK_Private], 2213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar &RequestedModule->Headers[Module::HK_PrivateTextual]}; 2223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar for (auto *Hs : HeaderList) 2233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar IsPrivate |= 2243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) { 2253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return H.Entry == IncFileEnt; 2263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }) != Hs->end(); 2273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles"); 2283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 229176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#endif 230176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return IsPrivateRole && 2313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // FIXME: Should we map RequestingModule to its top-level module here 2323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // too? This check is redundant with the isSubModuleOf check in 2333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // diagnoseHeaderInclusion. 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RequestedModule->getTopLevelModule() != RequestingModule; 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic Module *getTopLevelOrNull(Module *M) { 2386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return M ? M->getTopLevelModule() : nullptr; 2396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 2406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation FilenameLoc, 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Filename, 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *File) { 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // No errors for indirect modules. This may be a bit of a problem for modules 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // with no source files. 2476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (RequestingModule) 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines resolveUses(RequestingModule, /*Complain=*/false); 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Excluded = false; 2546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *Private = nullptr; 2556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *NotUsed = nullptr; 2566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeadersMap::iterator Known = findKnownHeader(File); 2586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Known != Headers.end()) { 2596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const KnownHeader &Header : Known->second) { 2606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If 'File' is part of 'RequestingModule' we can definitely include it. 2613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (Header.getModule() && 2623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Header.getModule()->isSubModuleOf(RequestingModule)) 2636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Remember private headers for later printing of a diagnostic. 2666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (violatesPrivateInclude(RequestingModule, File, Header.getRole(), 2676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Header.getModule())) { 2686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Private = Header.getModule(); 2696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 2706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If uses need to be specified explicitly, we are only allowed to return 2736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // modules that are explicitly used by the requesting module. 2746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RequestingModule && LangOpts.ModulesDeclUse && 2753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar !RequestingModule->directlyUses(Header.getModule())) { 2766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NotUsed = Header.getModule(); 2776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 2786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // We have found a module that we can happily use. 2816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 283176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 284176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Excluded = true; 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We have found a header, but it is private. 2886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Private) { 2890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module) 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Filename; 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We have found a module, but we don't use it. 2956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (NotUsed) { 2960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << RequestingModule->getFullModuleName() << Filename; 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Excluded || isHeaderInUmbrellaDirs(File)) 3026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // At this point, only non-modular includes remain. 3056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (LangOpts.ModulesStrictDeclUse) { 3070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 3086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << RequestingModule->getFullModuleName() << Filename; 3096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (RequestingModule) { 3106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? 3116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::warn_non_modular_include_in_framework_module : 3126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::warn_non_modular_include_in_module; 3136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName(); 3146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3170e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, 3180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const ModuleMap::KnownHeader &Old) { 3190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Prefer a public header over a private header. 3200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if ((New.getRole() & ModuleMap::PrivateHeader) != 3210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (Old.getRole() & ModuleMap::PrivateHeader)) 3220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return !(New.getRole() & ModuleMap::PrivateHeader); 3230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Prefer a non-textual header over a textual header. 3250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if ((New.getRole() & ModuleMap::TextualHeader) != 3260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (Old.getRole() & ModuleMap::TextualHeader)) 3270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return !(New.getRole() & ModuleMap::TextualHeader); 3280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Don't have a reason to choose between these. Just keep the first one. 3300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return false; 3310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 3320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 333c641709607d45bf97772e925647db6c94866c50aDaniel JasperModuleMap::KnownHeader 334c641709607d45bf97772e925647db6c94866c50aDaniel JasperModuleMap::findModuleForHeader(const FileEntry *File, 335176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Module *RequestingModule, 336176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool IncludeTextualHeaders) { 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeadersMap::iterator Known = findKnownHeader(File); 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 339176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { 340176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader)) 341176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ModuleMap::KnownHeader(); 342176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return R; 343176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines }; 344176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 34551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (Known != Headers.end()) { 346176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ModuleMap::KnownHeader Result; 347c641709607d45bf97772e925647db6c94866c50aDaniel Jasper 348c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // Iterate over all modules that 'File' is part of to find the best fit. 349c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 350c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = Known->second.end(); 351c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Cannot use a module if it is unavailable. 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!I->getModule()->isAvailable()) 354c641709607d45bf97772e925647db6c94866c50aDaniel Jasper continue; 35551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 356c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // If 'File' is part of 'RequestingModule', 'RequestingModule' is the 357c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // module we are looking for. 358c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (I->getModule() == RequestingModule) 359176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return MakeResult(*I); 360c641709607d45bf97772e925647db6c94866c50aDaniel Jasper 361c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // If uses need to be specified explicitly, we are only allowed to return 362c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // modules that are explicitly used by the requesting module. 363c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (RequestingModule && LangOpts.ModulesDeclUse && 3643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar !RequestingModule->directlyUses(I->getModule())) 365c641709607d45bf97772e925647db6c94866c50aDaniel Jasper continue; 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!Result || isBetterKnownHeader(*I, Result)) 368176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Result = *I; 369c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 370176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return MakeResult(Result); 37151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 372db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 373cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> SkippedDirs; 3746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); 3756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (H) { 3766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *Result = H.getModule(); 3776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Search up the module stack until we find a module with an umbrella 3796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // directory. 3806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *UmbrellaModule = Result; 3816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 3826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UmbrellaModule = UmbrellaModule->Parent; 3836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (UmbrellaModule->InferSubmodules) { 385176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const FileEntry *UmbrellaModuleMap = 386176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getModuleMapFileForUniquing(UmbrellaModule); 387176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Infer submodules for each of the directories we found between 3896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the directory of the umbrella header and the directory where 3906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the actual header is located. 3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Explicit = UmbrellaModule->InferExplicitSubmodules; 3926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned I = SkippedDirs.size(); I != 0; --I) { 3946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Find or create the module that corresponds to this directory name. 3958b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 3968b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 3976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf); 398176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Explicit).first; 400176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 4016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->IsInferred = true; 4026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Associate the module and the directory. 4046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UmbrellaDirs[SkippedDirs[I-1]] = Result; 4056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If inferred submodules export everything they import, add a 407e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // wildcard to the set of exports. 4089f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 4096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 410e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 41151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 4126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Infer a submodule with the same name as this header file. 4136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallString<32> NameBuf; 4146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef Name = sanitizeFilenameAsIdentifier( 4156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::path::stem(File->getName()), NameBuf); 416176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 417176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Explicit).first; 418176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 4196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->IsInferred = true; 4206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->addTopHeader(File); 4216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If inferred submodules export everything they import, add a 4236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // wildcard to the set of exports. 4246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 4256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 4266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 4276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Record each of the directories we stepped through as being part of 4286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the module we found, since the umbrella header covers them all. 4296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UmbrellaDirs[SkippedDirs[I]] = Result; 431adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor } 4326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Headers[File].push_back(KnownHeader(Result, NormalHeader)); 4346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If a header corresponds to an unavailable module, don't report 4366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // that it maps to anything. 4376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Result->isAvailable()) 4386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return KnownHeader(); 4396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 440176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return MakeResult(Headers[File].back()); 4416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 443bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return KnownHeader(); 44465f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor} 44565f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 4460be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidisbool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 4476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return isHeaderUnavailableInModule(Header, nullptr); 4486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool 4516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, 4526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Module *RequestingModule) const { 4530be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis HeadersMap::const_iterator Known = Headers.find(Header); 454c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (Known != Headers.end()) { 455c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (SmallVectorImpl<KnownHeader>::const_iterator 456c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I = Known->second.begin(), 457c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = Known->second.end(); 458c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 4596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (I->isAvailable() && (!RequestingModule || 4606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines I->getModule()->isSubModuleOf(RequestingModule))) 461c641709607d45bf97772e925647db6c94866c50aDaniel Jasper return false; 462c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 463c641709607d45bf97772e925647db6c94866c50aDaniel Jasper return true; 464c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 4656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 46651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor const DirectoryEntry *Dir = Header->getDir(); 467cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> SkippedDirs; 46851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor StringRef DirName = Dir->getName(); 46951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 4706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto IsUnavailable = [&](const Module *M) { 4716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return !M->isAvailable() && (!RequestingModule || 4726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines M->isSubModuleOf(RequestingModule)); 4736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }; 4746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 47551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Keep walking up the directory hierarchy, looking for a directory with 47651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // an umbrella header. 4776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines do { 4780be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 47951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor = UmbrellaDirs.find(Dir); 48051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (KnownDir != UmbrellaDirs.end()) { 48151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Module *Found = KnownDir->second; 4826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (IsUnavailable(Found)) 48351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return true; 48451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 48551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Search up the module stack until we find a module with an umbrella 48651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // directory. 48751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Module *UmbrellaModule = Found; 48851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 48951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor UmbrellaModule = UmbrellaModule->Parent; 49051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 49151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (UmbrellaModule->InferSubmodules) { 49251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor for (unsigned I = SkippedDirs.size(); I != 0; --I) { 49351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Find or create the module that corresponds to this directory name. 4948b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 4958b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 4968b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 4978b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 49851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Found = lookupModuleQualified(Name, Found); 49951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found) 50051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 5016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (IsUnavailable(Found)) 50251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return true; 50351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 50451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 50551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Infer a submodule with the same name as this header file. 5068b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 5078b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 5088b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(Header->getName()), 5098b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 51051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Found = lookupModuleQualified(Name, Found); 51151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found) 51251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 51351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 51451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 5156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return IsUnavailable(Found); 51651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 51751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 51851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor SkippedDirs.push_back(Dir); 51951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 52051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Retrieve our parent path. 52151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 52251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (DirName.empty()) 52351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 52451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 52551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Resolve the parent path to a directory entry. 526ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Dir = SourceMgr.getFileManager().getDirectory(DirName); 52751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } while (Dir); 52851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 52951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 53051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor} 53151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 5320be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::findModule(StringRef Name) const { 5330be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 534484535e45b4d301847a157e943c7823da5d40884Douglas Gregor if (Known != Modules.end()) 535484535e45b4d301847a157e943c7823da5d40884Douglas Gregor return Known->getValue(); 5366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 538484535e45b4d301847a157e943c7823da5d40884Douglas Gregor} 539484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 5400be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::lookupModuleUnqualified(StringRef Name, 5410be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis Module *Context) const { 54290db26000aefe9335370013eec64c85232d80227Douglas Gregor for(; Context; Context = Context->Parent) { 54390db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Context)) 54490db26000aefe9335370013eec64c85232d80227Douglas Gregor return Sub; 54590db26000aefe9335370013eec64c85232d80227Douglas Gregor } 54690db26000aefe9335370013eec64c85232d80227Douglas Gregor 54790db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 54890db26000aefe9335370013eec64c85232d80227Douglas Gregor} 54990db26000aefe9335370013eec64c85232d80227Douglas Gregor 5500be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 55190db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) 55290db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 55390db26000aefe9335370013eec64c85232d80227Douglas Gregor 554b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor return Context->findSubmodule(Name); 55590db26000aefe9335370013eec64c85232d80227Douglas Gregor} 55690db26000aefe9335370013eec64c85232d80227Douglas Gregor 5571a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorstd::pair<Module *, bool> 558176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 559392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor bool IsExplicit) { 560392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Try to find an existing module with this name. 561b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Parent)) 562b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor return std::make_pair(Sub, false); 563392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 564392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Create a new module with this name. 565176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Module *Result = new Module(Name, SourceLocation(), Parent, 5666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IsFramework, IsExplicit); 567ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper if (LangOpts.CurrentModule == Name) { 568ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModule = Result; 569ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModuleName = Name; 570ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper } 571d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis if (!Parent) { 572392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Modules[Name] = Result; 573d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis if (!LangOpts.CurrentModule.empty() && !CompilingModule && 574d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis Name == LangOpts.CurrentModule) { 575d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis CompilingModule = Result; 576d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis } 577d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis } 578392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor return std::make_pair(Result, true); 579392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor} 580392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 5818767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor/// \brief For a framework module, infer the framework against which we 5828767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor/// should link. 5838767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregorstatic void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 5848767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor FileManager &FileMgr) { 5858767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor assert(Mod->IsFramework && "Can only infer linking for framework modules"); 5868767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor assert(!Mod->isSubFramework() && 5878767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor "Can only infer linking for top-level frameworks"); 5888767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 5898767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor SmallString<128> LibName; 5908767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor LibName += FrameworkDir->getName(); 5918767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor llvm::sys::path::append(LibName, Mod->Name); 5928767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (FileMgr.getFile(LibName)) { 5938767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 5948767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor /*IsFramework=*/true)); 5958767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 5968767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor} 5978767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 5981a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule * 59982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas GregorModuleMap::inferFrameworkModule(StringRef ModuleName, 600ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const DirectoryEntry *FrameworkDir, 601a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor bool IsSystem, 602ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Module *Parent) { 6030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Attributes Attrs; 6040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Attrs.IsSystem = IsSystem; 6050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent); 6060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 6070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 6080e2c34f92f00628d48968dfea096d36381f494cbStephen HinesModule *ModuleMap::inferFrameworkModule(StringRef ModuleName, 6090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const DirectoryEntry *FrameworkDir, 6100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Attributes Attrs, Module *Parent) { 6110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 6122821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Check whether we've already found this module. 613ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 614ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor return Mod; 615ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 616ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek FileManager &FileMgr = SourceMgr.getFileManager(); 61782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 61882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // If the framework has a parent path from which we're allowed to infer 61982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // a framework module, do so. 6206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMapFile = nullptr; 62182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Parent) { 6227005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether we're allowed to infer a module map. 623713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 6247005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Note: as an egregious but useful hack we use the real path here, because 6257005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // we might be looking at an embedded framework that symlinks out to a 6267005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // top-level framework, and we need to infer as if we were naming the 6277005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // top-level framework. 628713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef FrameworkDirName 629ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek = SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 6307005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 631176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // In case this is a case-insensitive filesystem, make sure the canonical 632176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // directory name matches ModuleName exactly. Modules are case-sensitive. 633176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: we should be able to give a fix-it hint for the correct spelling. 634176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (llvm::sys::path::stem(FrameworkDirName) != ModuleName) 635176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return nullptr; 636176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 63782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool canInfer = false; 6387005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 63982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Figure out the parent path. 6407005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 64182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 64282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have already looked into the parent directory 64382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // for a module map. 6440be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 64582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 64682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) { 64782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We haven't looked here before. Load a module map, if there is 64882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // one. 649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsFrameworkDir = Parent.endswith(".framework"); 650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FileEntry *ModMapFile = 651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { 6520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir); 65382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 65482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 65582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 65682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) 65782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.insert( 65882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor std::make_pair(ParentDir, InferredDirectory())).first; 65982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 66082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 66182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred->second.InferModules) { 66282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We're allowed to infer for this directory, but make sure it's okay 66382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // to infer this particular module. 6647005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef Name = llvm::sys::path::stem(FrameworkDirName); 66582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor canInfer = std::find(inferred->second.ExcludedModules.begin(), 66682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred->second.ExcludedModules.end(), 66782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Name) == inferred->second.ExcludedModules.end(); 66882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 6690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 6700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 6710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 6726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapFile = inferred->second.ModuleMapFile; 67382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 67482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 67582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 67682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 67782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // If we're not allowed to infer a framework module, don't. 67882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!canInfer) 6796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else 681176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ModuleMapFile = getModuleMapFileForUniquing(Parent); 68282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 68382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 6842821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Look for an umbrella header. 685f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 686ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 687ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 6882821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 6892821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // FIXME: If there's no umbrella header, we could probably scan the 6902821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // framework to load *everything*. But, it's not clear that this is a good 6912821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // idea. 6922821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor if (!UmbrellaHeader) 6936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Module *Result = new Module(ModuleName, SourceLocation(), Parent, 696ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor /*IsFramework=*/true, /*IsExplicit=*/false); 697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InferredModuleAllowedBy[Result] = ModuleMapFile; 698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Result->IsInferred = true; 699ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper if (LangOpts.CurrentModule == ModuleName) { 700ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModule = Result; 701ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModuleName = ModuleName; 702ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper } 7030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 7040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Result->IsSystem |= Attrs.IsSystem; 7050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Result->IsExternC |= Attrs.IsExternC; 7060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; 7070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 708b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (!Parent) 709ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Modules[ModuleName] = Result; 710b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor 711489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // umbrella header "umbrella-header-name" 71210694cee2588442bee1e717f5042c58ffee25279Douglas Gregor Result->Umbrella = UmbrellaHeader; 713c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); 7143cee31e4d7c23d3d5d0b8927998577b9f75087d7Douglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 715209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor 716209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor // export * 7176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 7186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 719e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // module * { export * } 720e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferSubmodules = true; 721e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferExportWildcard = true; 722e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 723ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // Look for subframeworks. 724c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines std::error_code EC; 725f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> SubframeworksDirName 72652b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor = StringRef(FrameworkDir->getName()); 727ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 7280f599acfd685437d1344f82ce363f994b0729a2fBenjamin Kramer llvm::sys::path::native(SubframeworksDirName); 7293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd; 730ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 731ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (!StringRef(Dir->path()).endswith(".framework")) 732ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor continue; 73398cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 734ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (const DirectoryEntry *SubframeworkDir 735ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor = FileMgr.getDirectory(Dir->path())) { 73698cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // Note: as an egregious but useful hack, we use the real path here and 73798cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // check whether it is actually a subdirectory of the parent directory. 73898cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // This will not be the case if the 'subframework' is actually a symlink 73998cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // out to a top-level framework. 740713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 741713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor bool FoundParent = false; 742713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor do { 743713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor // Get the parent directory name. 744713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor SubframeworkDirName 745713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor = llvm::sys::path::parent_path(SubframeworkDirName); 746713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (SubframeworkDirName.empty()) 747713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor break; 748713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 749713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 750713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor FoundParent = true; 751713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor break; 752713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor } 753713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor } while (true); 75498cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 755713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (!FoundParent) 756713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor continue; 75798cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 758ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // FIXME: Do we want to warn about subframeworks without umbrella headers? 7598b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 7608b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor inferFrameworkModule(sanitizeFilenameAsIdentifier( 7610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::sys::path::stem(Dir->path()), NameBuf), 7620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SubframeworkDir, Attrs, Result); 763ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 764ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 7653a110f75acafc992cb664200cebec90520986715Douglas Gregor 7668767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // If the module is a top-level framework, automatically link against the 7678767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // framework. 7688767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (!Result->isSubFramework()) { 7698767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor inferFrameworkLink(Result, FrameworkDir, FileMgr); 7708767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 7718767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 7722821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Result; 7732821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 7742821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 775e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregorvoid ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 776c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 77710694cee2588442bee1e717f5042c58ffee25279Douglas Gregor Mod->Umbrella = UmbrellaHeader; 7786a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 779e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 780e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 78177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregorvoid ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 78277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Mod->Umbrella = UmbrellaDir; 78377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor UmbrellaDirs[UmbrellaDir] = Mod; 78477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor} 78577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 7860e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstatic Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) { 787176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines switch ((int)Role) { 7880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines default: llvm_unreachable("unknown header role"); 7890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case ModuleMap::NormalHeader: 7900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Module::HK_Normal; 7910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case ModuleMap::PrivateHeader: 7920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Module::HK_Private; 7930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case ModuleMap::TextualHeader: 7940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Module::HK_Textual; 7950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case ModuleMap::PrivateHeader | ModuleMap::TextualHeader: 7960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Module::HK_PrivateTextual; 797176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 7980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 799176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 8000e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid ModuleMap::addHeader(Module *Mod, Module::Header Header, 8010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ModuleHeaderRole Role) { 802176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!(Role & TextualHeader)) { 803d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 8040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 8050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines isCompilingModuleHeader); 80655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } 8070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Headers[Header.Entry].push_back(KnownHeader(Mod, Role)); 808e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 8090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header)); 8100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 811176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 8120e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { 813176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Add this as a known header so we won't implicitly add it to any 814176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // umbrella directory module. 815176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Should we only exclude it from umbrella modules within the 816176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // specified module? 8170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (void) Headers[Header.Entry]; 8180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 8190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); 820176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 821176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 822f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregorconst FileEntry * 823176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesModuleMap::getContainingModuleMapFile(const Module *Module) const { 824ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek if (Module->DefinitionLoc.isInvalid()) 8256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 826f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 827ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek return SourceMgr.getFileEntryForID( 828ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek SourceMgr.getFileID(Module->DefinitionLoc)); 829f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor} 830f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 831176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesconst FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 832176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (M->IsInferred) { 833176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 834176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return InferredModuleAllowedBy.find(M)->second; 835176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 836176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return getContainingModuleMapFile(M); 837176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 838176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 839176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 840176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(M->IsInferred && "module not inferred"); 841176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InferredModuleAllowedBy[M] = ModMap; 842176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 843176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 844a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMap::dump() { 845a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Modules:"; 846a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 847a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MEnd = Modules.end(); 848a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor M != MEnd; ++M) 849804c3bfee22076f232dddf4839439119cfdee2b6Douglas Gregor M->getValue()->print(llvm::errs(), 2); 850a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 851a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Headers:"; 8522b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 853a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor H != HEnd; ++H) { 854c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << " \"" << H->first->getName() << "\" -> "; 855c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 856c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = H->second.end(); 857c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 858c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (I != H->second.begin()) 859c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << ","; 860c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << I->getModule()->getFullModuleName(); 861c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 862c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << "\n"; 863a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 864a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 865a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 86690db26000aefe9335370013eec64c85232d80227Douglas Gregorbool ModuleMap::resolveExports(Module *Mod, bool Complain) { 86790db26000aefe9335370013eec64c85232d80227Douglas Gregor bool HadError = false; 86890db26000aefe9335370013eec64c85232d80227Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 86990db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 87090db26000aefe9335370013eec64c85232d80227Douglas Gregor Complain); 8710adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Export.getPointer() || Export.getInt()) 87290db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->Exports.push_back(Export); 87390db26000aefe9335370013eec64c85232d80227Douglas Gregor else 87490db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 87590db26000aefe9335370013eec64c85232d80227Douglas Gregor } 87690db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->UnresolvedExports.clear(); 87790db26000aefe9335370013eec64c85232d80227Douglas Gregor return HadError; 87890db26000aefe9335370013eec64c85232d80227Douglas Gregor} 87990db26000aefe9335370013eec64c85232d80227Douglas Gregor 880ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasperbool ModuleMap::resolveUses(Module *Mod, bool Complain) { 881ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper bool HadError = false; 882ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 883ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Module *DirectUse = 884ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 885ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper if (DirectUse) 886ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Mod->DirectUses.push_back(DirectUse); 887ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper else 888ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper HadError = true; 889ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper } 890ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Mod->UnresolvedDirectUses.clear(); 891ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper return HadError; 892ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper} 893ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 894906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorbool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 895906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor bool HadError = false; 896906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 897906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 898906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod, Complain); 899906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!OtherMod) { 900906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor HadError = true; 901906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor continue; 902906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 903906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 904906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module::Conflict Conflict; 905906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Other = OtherMod; 906906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Message = Mod->UnresolvedConflicts[I].Message; 907906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod->Conflicts.push_back(Conflict); 908906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 909906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod->UnresolvedConflicts.clear(); 910906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return HadError; 911906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 912906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 91355988680ece66b8e505ee136b35e74fcb1173aeeDouglas GregorModule *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 91455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (Loc.isInvalid()) 9156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 9166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 91755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Use the expansion location to determine which module we're in. 91855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 91955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (!ExpansionLoc.isFileID()) 9206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 9216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 92255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor const SourceManager &SrcMgr = Loc.getManager(); 92355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FileID ExpansionFileID = ExpansionLoc.getFileID(); 92455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 925303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor while (const FileEntry *ExpansionFile 926303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor = SrcMgr.getFileEntryForID(ExpansionFileID)) { 927303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // Find the module that owns this header (if any). 928bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 929303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor return Mod; 930303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor 931303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // No module owns this header, so look up the inclusion chain to see if 932303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // any included header has an associated module. 933303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 934303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor if (IncludeLoc.isInvalid()) 9356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 9366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 937303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 938303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor } 9396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 94155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor} 94255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 943a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 944a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// Module map file parser 945a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 946a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 947a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregornamespace clang { 948a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief A token in a module map file. 949a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor struct MMToken { 950a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor enum TokenKind { 95151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Comma, 95263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ConfigMacros, 953906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict, 954a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor EndOfFile, 955a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HeaderKeyword, 956a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Identifier, 9575794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith Exclaim, 9582b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor ExcludeKeyword, 959a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ExplicitKeyword, 96090db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportKeyword, 9615f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ExternKeyword, 962a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor FrameworkKeyword, 963b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor LinkKeyword, 964a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleKeyword, 96590db26000aefe9335370013eec64c85232d80227Douglas Gregor Period, 966bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl PrivateKeyword, 967a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor UmbrellaKeyword, 968ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper UseKeyword, 96951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor RequiresKeyword, 97090db26000aefe9335370013eec64c85232d80227Douglas Gregor Star, 971a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLiteral, 972176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TextualKeyword, 973a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LBrace, 974a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor RBrace, 975a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor LSquare, 976a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor RSquare 977a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } Kind; 978a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 979a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Location; 980a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned StringLength; 981a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const char *StringData; 982a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 983a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void clear() { 984a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Kind = EndOfFile; 985a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Location = 0; 986a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLength = 0; 9876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringData = nullptr; 988a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 989a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 990a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool is(TokenKind K) const { return Kind == K; } 991a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 992a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation getLocation() const { 993a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return SourceLocation::getFromRawEncoding(Location); 994a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 995a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 996a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef getString() const { 997a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return StringRef(StringData, StringLength); 998a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 999a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 100082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 1001a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor class ModuleMapParser { 1002a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Lexer &L; 1003a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceManager &SourceMgr; 10049a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 10059a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor /// \brief Default target information, used only for string literal 10069a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor /// parsing. 10079a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor const TargetInfo *Target; 10089a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 1009a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags; 1010a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleMap ⤅ 10116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 10126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief The current module map file. 10136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMapFile; 1014a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 10150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// \brief The directory that file names in this module map file should 10160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /// be resolved relative to. 10178b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor const DirectoryEntry *Directory; 10182f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 10192f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor /// \brief The directory containing Clang-supplied headers. 10202f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const DirectoryEntry *BuiltinIncludeDir; 10212f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 10228f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor /// \brief Whether this module map is in a system header directory. 10238f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem; 10248f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor 1025a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Whether an error occurred. 1026a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool HadError; 10279a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 1028a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Stores string data for the various string literals referenced 1029a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// during parsing. 1030a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::BumpPtrAllocator StringData; 1031a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1032a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The current token. 1033a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MMToken Tok; 1034a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1035a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The active module. 10361a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Module *ActiveModule; 1037a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1038a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Consume the current token and return its location. 1039a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation consumeToken(); 1040a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1041a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Skip tokens until we reach the a token with the given kind 1042a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// (or the end of the file). 1043a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void skipUntil(MMToken::TokenKind K); 1044587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1045cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1046587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor bool parseModuleId(ModuleId &Id); 1047a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void parseModuleDecl(); 10485f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper void parseExternModuleDecl(); 104951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor void parseRequiresDecl(); 1050bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl void parseHeaderDecl(clang::MMToken::TokenKind, 1051bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation LeadingLoc); 105277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 105390db26000aefe9335370013eec64c85232d80227Douglas Gregor void parseExportDecl(); 1054ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper void parseUseDecl(); 1055b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor void parseLinkDecl(); 105663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor void parseConfigMacros(); 1057906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor void parseConflict(); 105882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor void parseInferredModuleDecl(bool Framework, bool Explicit); 10590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines typedef ModuleMap::Attributes Attributes; 1061ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling bool parseOptionalAttributes(Attributes &Attrs); 10626a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor 1063a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor public: 1064a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 10659a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor const TargetInfo *Target, 1066a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags, 10678b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor ModuleMap &Map, 10686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMapFile, 10692f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const DirectoryEntry *Directory, 10708f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor const DirectoryEntry *BuiltinIncludeDir, 10718f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem) 10729a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 10736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapFile(ModuleMapFile), Directory(Directory), 10746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem), 10756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HadError(false), ActiveModule(nullptr) 1076a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor { 1077a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 1078a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1079a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1080a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1081a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool parseModuleMapFile(); 1082a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 1083a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1084a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1085a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorSourceLocation ModuleMapParser::consumeToken() { 1086a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorretry: 1087a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation Result = Tok.getLocation(); 1088a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 1089a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1090a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Token LToken; 1091a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor L.LexFromRawLexer(LToken); 1092a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Location = LToken.getLocation().getRawEncoding(); 1093a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (LToken.getKind()) { 10946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case tok::raw_identifier: { 10956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef RI = LToken.getRawIdentifier(); 10966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tok.StringData = RI.data(); 10976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tok.StringLength = RI.size(); 10986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 109963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("config_macros", MMToken::ConfigMacros) 1100906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor .Case("conflict", MMToken::Conflict) 11012b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor .Case("exclude", MMToken::ExcludeKeyword) 1102a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("explicit", MMToken::ExplicitKeyword) 110390db26000aefe9335370013eec64c85232d80227Douglas Gregor .Case("export", MMToken::ExportKeyword) 11045f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper .Case("extern", MMToken::ExternKeyword) 1105a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor .Case("framework", MMToken::FrameworkKeyword) 110663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("header", MMToken::HeaderKeyword) 1107b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor .Case("link", MMToken::LinkKeyword) 1108a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("module", MMToken::ModuleKeyword) 1109bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl .Case("private", MMToken::PrivateKeyword) 111051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor .Case("requires", MMToken::RequiresKeyword) 1111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines .Case("textual", MMToken::TextualKeyword) 1112a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("umbrella", MMToken::UmbrellaKeyword) 1113ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper .Case("use", MMToken::UseKeyword) 1114a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Default(MMToken::Identifier); 1115a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 11166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 111751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 111851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case tok::comma: 111951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Tok.Kind = MMToken::Comma; 112051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 112151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 1122a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::eof: 1123a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::EndOfFile; 1124a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1125a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1126a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::l_brace: 1127a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::LBrace; 1128a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1129a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1130a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case tok::l_square: 1131a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Tok.Kind = MMToken::LSquare; 1132a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1133a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 113490db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::period: 113590db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Period; 113690db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 113790db26000aefe9335370013eec64c85232d80227Douglas Gregor 1138a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::r_brace: 1139a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::RBrace; 1140a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1141a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1142a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case tok::r_square: 1143a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Tok.Kind = MMToken::RSquare; 1144a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1145a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 114690db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::star: 114790db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Star; 114890db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 114990db26000aefe9335370013eec64c85232d80227Douglas Gregor 11505794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith case tok::exclaim: 11515794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith Tok.Kind = MMToken::Exclaim; 11525794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith break; 11535794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith 1154a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::string_literal: { 115599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (LToken.hasUDSuffix()) { 115699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 115799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith HadError = true; 115899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith goto retry; 115999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 116099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith 1161a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the string literal. 1162a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LangOptions LangOpts; 1163c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1164a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (StringLiteral.hadError) 1165a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 1166a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1167a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Copy the string literal into our string data allocator. 1168a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Length = StringLiteral.GetStringLength(); 1169a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor char *Saved = StringData.Allocate<char>(Length + 1); 1170a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor memcpy(Saved, StringLiteral.GetString().data(), Length); 1171a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Saved[Length] = 0; 1172a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1173a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Form the token. 1174a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::StringLiteral; 1175a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringData = Saved; 1176a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringLength = Length; 1177a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1178a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1179a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1180a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::comment: 1181a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 1182a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1183a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1184a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1185a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1186a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 1187a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1188a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1189a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 1190a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1191a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1192a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1193a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned braceDepth = 0; 1194a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor unsigned squareDepth = 0; 1195a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1196a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1197a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1198a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1199a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1200a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 1201a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1202a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1203a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1204a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ++braceDepth; 1205a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1206a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1207a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::LSquare: 1208a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1209a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor return; 1210a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1211a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor ++squareDepth; 1212a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1213a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1214a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 1215a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (braceDepth > 0) 1216a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor --braceDepth; 1217a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else if (Tok.is(K)) 1218a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1219a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1220a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1221a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::RSquare: 1222a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (squareDepth > 0) 1223a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor --squareDepth; 1224a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor else if (Tok.is(K)) 1225a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor return; 1226a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1227a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1228a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1229a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1230a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1231a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1232a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1233a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1234a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1235a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 1236a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1237a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1238587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \brief Parse a module-id. 1239587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 1240587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// module-id: 1241587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier 1242587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier '.' module-id 1243587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 1244587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \returns true if an error occurred, false otherwise. 1245587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregorbool ModuleMapParser::parseModuleId(ModuleId &Id) { 1246587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.clear(); 1247587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor do { 1248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1249587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1250587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 1251587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1252587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1253587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return true; 1254587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1255587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1256587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!Tok.is(MMToken::Period)) 1257587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor break; 1258587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1259587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 1260587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } while (true); 1261587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1262587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return false; 1263587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor} 1264587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1265a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregornamespace { 1266a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief Enumerates the known attributes. 1267a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor enum AttributeKind { 1268a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief An unknown attribute. 1269a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor AT_unknown, 1270a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief The 'system' attribute. 127163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor AT_system, 1272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief The 'extern_c' attribute. 1273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AT_extern_c, 127463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor /// \brief The 'exhaustive' attribute. 127563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor AT_exhaustive 1276a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor }; 1277a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor} 1278a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1279a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module declaration. 1280a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1281a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration: 12825f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 'extern' 'module' module-id string-literal 1283a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1284a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// { module-member* } 1285a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// 1286a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-member: 128751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// requires-declaration 1288a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// header-declaration 1289587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// submodule-declaration 129090db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration 1291b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// link-declaration 12921e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// 12931e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// submodule-declaration: 12941e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// module-declaration 12951e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// inferred-submodule-declaration 1296a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::parseModuleDecl() { 1297a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 12985f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 12995f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (Tok.is(MMToken::ExternKeyword)) { 13005f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper parseExternModuleDecl(); 13015f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 13025f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 13035f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 1304d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'explicit' or 'framework' keyword, if present. 1305587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ExplicitLoc; 1306a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Explicit = false; 1307d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor bool Framework = false; 1308a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 1309a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor // Parse 'explicit' keyword, if present. 1310d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::ExplicitKeyword)) { 1311587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = consumeToken(); 1312a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Explicit = true; 1313a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1314d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1315d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'framework' keyword, if present. 1316d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 1317d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor consumeToken(); 1318d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Framework = true; 1319d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 1320a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1321a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse 'module' keyword. 1322a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::ModuleKeyword)) { 1323e6fb9876970e2dc55f091522644efa16caa9ba06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1324a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1325a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1326a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1327a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1328a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); // 'module' keyword 13291e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 13301e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If we have a wildcard for the module name, this is an inferred submodule. 13311e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse it. 13321e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 133382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return parseInferredModuleDecl(Framework, Explicit); 1334a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1335a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the module name. 1336587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleId Id; 1337587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (parseModuleId(Id)) { 1338587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1339587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1340587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 134182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 1342587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 1343587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 1344587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1345587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor << SourceRange(Id.front().second, Id.back().second); 1346587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1347587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1348587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1349587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1350587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else if (Id.size() == 1 && Explicit) { 1351587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Top-level modules can't be explicit. 1352587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1353587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Explicit = false; 1354587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = SourceLocation(); 1355a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1356a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1357587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1358587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Module *PreviousActiveModule = ActiveModule; 1359587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 1360587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // This module map defines a submodule. Go find the module of which it 1361587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // is a submodule. 13626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule = nullptr; 1363176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const Module *TopLevelModule = nullptr; 1364587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1365587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1366176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (I == 0) 1367176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TopLevelModule = Next; 1368587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = Next; 1369587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor continue; 1370587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1371587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1372587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 1373587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Id[I].first 1375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << ActiveModule->getTopLevelModule()->getFullModuleName(); 1376587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1377587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1378587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1379587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1380587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1381587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1382176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1383176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1384176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1385176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "submodule defined in same file as 'module *' that allowed its " 1386176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "top-level module"); 1387176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1388176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1389176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1390587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1391587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor StringRef ModuleName = Id.back().first; 1392587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ModuleNameLoc = Id.back().second; 1393a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1394a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor // Parse the optional attribute list. 1395ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling Attributes Attrs; 139682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor parseOptionalAttributes(Attrs); 1397a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1398a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the opening brace. 1399a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 1400a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1401a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 1402a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1403a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1404a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1405a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 1406a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1407a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this (sub)module has already been defined. 1408b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1409c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1410c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor // Skip the module definition. 1411c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor skipUntil(MMToken::RBrace); 1412c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor if (Tok.is(MMToken::RBrace)) 1413c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor consumeToken(); 1414c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor else { 1415c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1416c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1417c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor HadError = true; 1418c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor } 1419c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor return; 1420c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor } 1421c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor 1422a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1423a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 1424b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1425a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1426a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Skip the module definition. 1427a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor skipUntil(MMToken::RBrace); 1428a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 1429a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1430a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1431a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1432a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1433a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1434a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1435a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Start defining this module. 1436176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1437176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Explicit).first; 1438b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor ActiveModule->DefinitionLoc = ModuleNameLoc; 14398f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (Attrs.IsSystem || IsSystem) 1440a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor ActiveModule->IsSystem = true; 1441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Attrs.IsExternC) 1442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ActiveModule->IsExternC = true; 14430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ActiveModule->Directory = Directory; 1444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1445a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Done = false; 1446a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1447a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1448a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1449a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 1450a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Done = true; 1451a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 145263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 145363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case MMToken::ConfigMacros: 145463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor parseConfigMacros(); 145563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 145663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 1457906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor case MMToken::Conflict: 1458906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor parseConflict(); 1459906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor break; 1460906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1461a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ExplicitKeyword: 14625f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper case MMToken::ExternKeyword: 1463d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor case MMToken::FrameworkKeyword: 1464a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 1465a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 1466a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 14675f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 146890db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 146990db26000aefe9335370013eec64c85232d80227Douglas Gregor parseExportDecl(); 147090db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 1471ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 1472ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper case MMToken::UseKeyword: 1473ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper parseUseDecl(); 1474ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper break; 147590db26000aefe9335370013eec64c85232d80227Douglas Gregor 147651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::RequiresKeyword: 147751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor parseRequiresDecl(); 147851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 147951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 1480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case MMToken::TextualKeyword: 1481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 1483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 148477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor case MMToken::UmbrellaKeyword: { 148577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor SourceLocation UmbrellaLoc = consumeToken(); 148677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (Tok.is(MMToken::HeaderKeyword)) 1487bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 148877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor else 148977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor parseUmbrellaDirDecl(UmbrellaLoc); 1490a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 149177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 1492176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1493176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case MMToken::ExcludeKeyword: 1494176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 14952b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor break; 1496176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1497176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case MMToken::PrivateKeyword: 1498176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1499bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl break; 1500176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1501489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor case MMToken::HeaderKeyword: 1502176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1503a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1504b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1505b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor case MMToken::LinkKeyword: 1506b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor parseLinkDecl(); 1507b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor break; 1508b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1509a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1510a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1511a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1512a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1513a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1514a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (!Done); 1515a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1516a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 1517a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1518a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else { 1519a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1520a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1521a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1522a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1523a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 15248767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // If the active module is a top-level framework, and there are no link 15258767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // libraries, automatically link against the framework. 15268767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 15278767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor ActiveModule->LinkLibraries.empty()) { 15288767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 15298767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 15308767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 15316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If the module meets all requirements but is still unavailable, mark the 15326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // whole tree as unavailable to prevent it from building. 15336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 15346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->Parent) { 15356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->getTopLevelModule()->markUnavailable(); 15366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->getTopLevelModule()->MissingHeaders.append( 15376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 15386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 15396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1540587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // We're done parsing this module. Pop back to the previous module. 1541587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = PreviousActiveModule; 1542a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1543d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 15445f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// \brief Parse an extern module declaration. 15455f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 15465f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// extern module-declaration: 15475f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 'extern' 'module' module-id string-literal 15485f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jaspervoid ModuleMapParser::parseExternModuleDecl() { 15495f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper assert(Tok.is(MMToken::ExternKeyword)); 15505f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // 'extern' keyword 15515f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15525f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse 'module' keyword. 15535f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (!Tok.is(MMToken::ModuleKeyword)) { 15545f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 15555f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); 15565f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 15575f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 15585f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15595f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // 'module' keyword 15605f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15615f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse the module name. 15625f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ModuleId Id; 15635f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (parseModuleId(Id)) { 15645f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 15655f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 15665f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15675f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15685f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse the referenced module map file name. 15695f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (!Tok.is(MMToken::StringLiteral)) { 15705f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 15715f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 15725f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 15735f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15745f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper std::string FileName = Tok.getString(); 15755f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // filename 15765f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15775f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper StringRef FileNameRef = FileName; 15785f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper SmallString<128> ModuleMapFileName; 15795f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (llvm::sys::path::is_relative(FileNameRef)) { 15805f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ModuleMapFileName += Directory->getName(); 15815f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper llvm::sys::path::append(ModuleMapFileName, FileName); 15823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar FileNameRef = ModuleMapFileName; 15835f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15845f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 15850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Map.parseModuleMapFile( 15860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines File, /*IsSystem=*/false, 15870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 15880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ? Directory 15890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines : File->getDir()); 15905f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper} 15915f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 159251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// \brief Parse a requires declaration. 159351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 159451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// requires-declaration: 159551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 'requires' feature-list 159651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 159751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// feature-list: 15985794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// feature ',' feature-list 15995794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// feature 16005794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// 16015794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// feature: 16025794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// '!'[opt] identifier 160351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregorvoid ModuleMapParser::parseRequiresDecl() { 160451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor assert(Tok.is(MMToken::RequiresKeyword)); 160551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 160651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Parse 'requires' keyword. 160751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 160851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 160951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Parse the feature-list. 161051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor do { 16115794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith bool RequiredState = true; 16125794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith if (Tok.is(MMToken::Exclaim)) { 16135794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith RequiredState = false; 16145794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith consumeToken(); 16155794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith } 16165794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith 161751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Tok.is(MMToken::Identifier)) { 161851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 161951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor HadError = true; 162051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return; 162151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 162251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 162351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Consume the feature name. 162451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor std::string Feature = Tok.getString(); 162551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 162651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 162751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Add this feature. 16285794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith ActiveModule->addRequirement(Feature, RequiredState, 16295794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith Map.LangOpts, *Map.Target); 163051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 163151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Tok.is(MMToken::Comma)) 163251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 163351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 163451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Consume the comma. 163551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 163651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } while (true); 163751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor} 163851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 1639d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// \brief Append to \p Paths the set of paths needed to get to the 1640d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// subframework in which the given module lives. 16415bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramerstatic void appendSubframeworkPaths(Module *Mod, 1642cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVectorImpl<char> &Path) { 1643d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Collect the framework names from the given module to the top-level module. 1644cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<StringRef, 2> Paths; 1645d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor for (; Mod; Mod = Mod->Parent) { 1646d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Mod->IsFramework) 1647d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Paths.push_back(Mod->Name); 1648d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 1649d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1650d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Paths.empty()) 1651d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor return; 1652d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1653d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Add Frameworks/Name.framework for each subframework. 1654ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer for (unsigned I = Paths.size() - 1; I != 0; --I) 1655ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1656d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor} 1657d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1658489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// \brief Parse a header declaration. 1659a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1660489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// header-declaration: 1661176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// 'textual'[opt] 'header' string-literal 1662176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// 'private' 'textual'[opt] 'header' string-literal 1663176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// 'exclude' 'header' string-literal 1664176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// 'umbrella' 'header' string-literal 1665176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// 1666176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// FIXME: Support 'private textual header'. 1667bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowlvoid ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1668bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation LeadingLoc) { 1669176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // We've already consumed the first token. 1670176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1671176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeadingToken == MMToken::PrivateKeyword) { 1672176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Role = ModuleMap::PrivateHeader; 1673176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // 'private' may optionally be followed by 'textual'. 1674176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Tok.is(MMToken::TextualKeyword)) { 1675176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LeadingToken = Tok.Kind; 1676176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines consumeToken(); 1677176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeadingToken == MMToken::TextualKeyword) 1680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1681176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1682176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeadingToken != MMToken::HeaderKeyword) { 1683176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Tok.is(MMToken::HeaderKeyword)) { 1684176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1685176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << (LeadingToken == MMToken::PrivateKeyword ? "private" : 1686176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 1687176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 1688176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 1689176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1690176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines consumeToken(); 1691176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1692489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor 1693a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the header name. 1694a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1695a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1696489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor << "header"; 1697a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1698a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1699a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 17000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Module::UnresolvedHeaderDirective Header; 1701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Header.FileName = Tok.getString(); 1702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Header.FileNameLoc = consumeToken(); 1703489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor 170477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Check whether we already have an umbrella. 1705bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 170777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << ActiveModule->getFullModuleName(); 17088b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 17098b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor return; 17108b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1711a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 17128b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Look for this file. 17136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *File = nullptr; 17146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *BuiltinFile = nullptr; 17150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SmallString<128> RelativePathName; 1716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (llvm::sys::path::is_absolute(Header.FileName)) { 17170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RelativePathName = Header.FileName; 17180e2c34f92f00628d48968dfea096d36381f494cbStephen Hines File = SourceMgr.getFileManager().getFile(RelativePathName); 1719587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1720587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Search for the header file within the search directory. 17210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines SmallString<128> FullPathName(Directory->getName()); 17220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines unsigned FullPathLength = FullPathName.size(); 172318ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor 1724d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (ActiveModule->isPartOfFramework()) { 17250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines appendSubframeworkPaths(ActiveModule, RelativePathName); 1726587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1727587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the public headers. 17280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); 17293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::sys::path::append(FullPathName, RelativePathName); 17300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines File = SourceMgr.getFileManager().getFile(FullPathName); 1731587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1732587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!File) { 1733587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the private headers. 17340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // FIXME: Should we retain the subframework paths here? 17350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RelativePathName.clear(); 17360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines FullPathName.resize(FullPathLength); 17370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::sys::path::append(RelativePathName, "PrivateHeaders", 17380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Header.FileName); 17393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::sys::path::append(FullPathName, RelativePathName); 17400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines File = SourceMgr.getFileManager().getFile(FullPathName); 1741587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1742587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1743587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Lookup for normal headers. 17440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::sys::path::append(RelativePathName, Header.FileName); 17453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::sys::path::append(FullPathName, RelativePathName); 17460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines File = SourceMgr.getFileManager().getFile(FullPathName); 17470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 17482f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If this is a system module with a top-level header, this header 17492f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // may have a counterpart (or replacement) in the set of headers 17502f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // supplied by Clang. Find that builtin header. 1751bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1752bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1753651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isBuiltinHeader(Header.FileName)) { 1754f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(BuiltinPathName, Header.FileName); 17562f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 17570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 17582f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If Clang supplies this header but the underlying system does not, 17592f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // just silently swap in our builtin version. Otherwise, we'll end 17602f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // up adding both (later). 17612f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor if (!File && BuiltinFile) { 17622f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor File = BuiltinFile; 17630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines RelativePathName = BuiltinPathName; 17646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuiltinFile = nullptr; 17652f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor } 17662f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor } 1767d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 176818ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } 17690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 17708b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 17718b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Come up with a lazy way to do this. 1772587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (File) { 1773c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (LeadingToken == MMToken::UmbrellaKeyword) { 1774489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor const DirectoryEntry *UmbrellaDir = File->getDir(); 17752b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1776bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 17772b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << UmbrellaModule->getFullModuleName(); 1778489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor HadError = true; 1779489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor } else { 1780489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // Record this umbrella header. 1781489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor Map.setUmbrellaHeader(ActiveModule, File); 1782489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor } 1783176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else if (LeadingToken == MMToken::ExcludeKeyword) { 17840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Module::Header H = {RelativePathName.str(), File}; 17850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Map.excludeHeader(ActiveModule, H); 17868b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 1787176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // If there is a builtin counterpart to this file, add it now, before 1788176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // the "real" header, so we build the built-in one first when building 1789176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // the module. 17900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (BuiltinFile) { 17910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // FIXME: Taking the name from the FileEntry is unstable and can give 17920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // different results depending on how we've previously named that file 17930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // in this build. 17940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Module::Header H = { BuiltinFile->getName(), BuiltinFile }; 17950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Map.addHeader(ActiveModule, H, Role); 17960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 1797176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1798176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Record this header. 17990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Module::Header H = { RelativePathName.str(), File }; 18000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Map.addHeader(ActiveModule, H, Role); 18018b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1802bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } else if (LeadingToken != MMToken::ExcludeKeyword) { 180371f49f5d8fc3c4980bed4bb7790c8d0e50586d3bDouglas Gregor // Ignore excluded header files. They're optional anyway. 1804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If we find a module that has a missing header, we mark this module as 1806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // unavailable and store the header directive for displaying diagnostics. 1807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 18086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->markUnavailable(); 1809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ActiveModule->MissingHeaders.push_back(Header); 181077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 181177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor} 181277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 181377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// \brief Parse an umbrella directory declaration. 181477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// 181577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// umbrella-dir-declaration: 181677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// umbrella string-literal 181777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregorvoid ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 181877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Parse the directory name. 181977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 182077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 182177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << "umbrella"; 182277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 182377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 182477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 182577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 182677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor std::string DirName = Tok.getString(); 182777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor SourceLocation DirNameLoc = consumeToken(); 182877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 182977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Check whether we already have an umbrella. 183077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (ActiveModule->Umbrella) { 183177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 183277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << ActiveModule->getFullModuleName(); 18338b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 183477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 183577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 183677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 183777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Look for this file. 18386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DirectoryEntry *Dir = nullptr; 183977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (llvm::sys::path::is_absolute(DirName)) 184077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Dir = SourceMgr.getFileManager().getDirectory(DirName); 184177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor else { 1842f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PathName; 184377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor PathName = Directory->getName(); 184477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor llvm::sys::path::append(PathName, DirName); 184577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Dir = SourceMgr.getFileManager().getDirectory(PathName); 18468b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 184777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 184877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (!Dir) { 184977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 185077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << DirName; 185177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 185277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 185377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 185477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 185577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 185677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 185777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << OwningModule->getFullModuleName(); 185877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 185977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 186077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 186177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 186277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Record this umbrella directory. 186377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Map.setUmbrellaDir(ActiveModule, Dir); 1864a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1865a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 186690db26000aefe9335370013eec64c85232d80227Douglas Gregor/// \brief Parse a module export declaration. 186790db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 186890db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration: 186990db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 'export' wildcard-module-id 187090db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 187190db26000aefe9335370013eec64c85232d80227Douglas Gregor/// wildcard-module-id: 187290db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier 187390db26000aefe9335370013eec64c85232d80227Douglas Gregor/// '*' 187490db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier '.' wildcard-module-id 187590db26000aefe9335370013eec64c85232d80227Douglas Gregorvoid ModuleMapParser::parseExportDecl() { 187690db26000aefe9335370013eec64c85232d80227Douglas Gregor assert(Tok.is(MMToken::ExportKeyword)); 187790db26000aefe9335370013eec64c85232d80227Douglas Gregor SourceLocation ExportLoc = consumeToken(); 187890db26000aefe9335370013eec64c85232d80227Douglas Gregor 187990db26000aefe9335370013eec64c85232d80227Douglas Gregor // Parse the module-id with an optional wildcard at the end. 188090db26000aefe9335370013eec64c85232d80227Douglas Gregor ModuleId ParsedModuleId; 188190db26000aefe9335370013eec64c85232d80227Douglas Gregor bool Wildcard = false; 188290db26000aefe9335370013eec64c85232d80227Douglas Gregor do { 1883176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Support string-literal module names here. 188490db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Identifier)) { 188590db26000aefe9335370013eec64c85232d80227Douglas Gregor ParsedModuleId.push_back(std::make_pair(Tok.getString(), 188690db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.getLocation())); 188790db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 188890db26000aefe9335370013eec64c85232d80227Douglas Gregor 188990db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Period)) { 189090db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 189190db26000aefe9335370013eec64c85232d80227Douglas Gregor continue; 189290db26000aefe9335370013eec64c85232d80227Douglas Gregor } 189390db26000aefe9335370013eec64c85232d80227Douglas Gregor 189490db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 189590db26000aefe9335370013eec64c85232d80227Douglas Gregor } 189690db26000aefe9335370013eec64c85232d80227Douglas Gregor 189790db26000aefe9335370013eec64c85232d80227Douglas Gregor if(Tok.is(MMToken::Star)) { 189890db26000aefe9335370013eec64c85232d80227Douglas Gregor Wildcard = true; 18990adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor consumeToken(); 190090db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 190190db26000aefe9335370013eec64c85232d80227Douglas Gregor } 190290db26000aefe9335370013eec64c85232d80227Douglas Gregor 1903ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 190490db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 190590db26000aefe9335370013eec64c85232d80227Douglas Gregor return; 190690db26000aefe9335370013eec64c85232d80227Douglas Gregor } while (true); 190790db26000aefe9335370013eec64c85232d80227Douglas Gregor 190890db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::UnresolvedExportDecl Unresolved = { 190990db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportLoc, ParsedModuleId, Wildcard 191090db26000aefe9335370013eec64c85232d80227Douglas Gregor }; 191190db26000aefe9335370013eec64c85232d80227Douglas Gregor ActiveModule->UnresolvedExports.push_back(Unresolved); 191290db26000aefe9335370013eec64c85232d80227Douglas Gregor} 191390db26000aefe9335370013eec64c85232d80227Douglas Gregor 19143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \brief Parse a module use declaration. 1915ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper/// 19163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// use-declaration: 19173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// 'use' wildcard-module-id 1918ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jaspervoid ModuleMapParser::parseUseDecl() { 1919ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper assert(Tok.is(MMToken::UseKeyword)); 19203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar auto KWLoc = consumeToken(); 1921ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper // Parse the module-id. 1922ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper ModuleId ParsedModuleId; 1923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines parseModuleId(ParsedModuleId); 1924ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 19253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (ActiveModule->Parent) 19263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 19273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar else 19283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1929ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper} 1930ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 1931b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// \brief Parse a link declaration. 1932b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// 1933b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// module-declaration: 1934b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// 'link' 'framework'[opt] string-literal 1935b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregorvoid ModuleMapParser::parseLinkDecl() { 1936b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor assert(Tok.is(MMToken::LinkKeyword)); 1937b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor SourceLocation LinkLoc = consumeToken(); 1938b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1939b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor // Parse the optional 'framework' keyword. 1940b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor bool IsFramework = false; 1941b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 1942b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor consumeToken(); 1943b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor IsFramework = true; 1944b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor } 1945b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1946b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor // Parse the library name 1947b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1948b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1949b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor << IsFramework << SourceRange(LinkLoc); 1950b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor HadError = true; 1951b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor return; 1952b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor } 1953b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1954b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor std::string LibraryName = Tok.getString(); 1955b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor consumeToken(); 1956b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1957b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor IsFramework)); 1958b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor} 1959b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 196063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// \brief Parse a configuration macro declaration. 196163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 196263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// module-declaration: 196363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 'config_macros' attributes[opt] config-macro-list? 196463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 196563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// config-macro-list: 196663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// identifier (',' identifier)? 196763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregorvoid ModuleMapParser::parseConfigMacros() { 196863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor assert(Tok.is(MMToken::ConfigMacros)); 196963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor SourceLocation ConfigMacrosLoc = consumeToken(); 197063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 197163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Only top-level modules can have configuration macros. 197263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (ActiveModule->Parent) { 197363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 197463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 197563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 197663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Parse the optional attributes. 197763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attributes Attrs; 197863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor parseOptionalAttributes(Attrs); 197963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (Attrs.IsExhaustive && !ActiveModule->Parent) { 198063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacrosExhaustive = true; 198163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 198263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 198363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // If we don't have an identifier, we're done. 1984176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Support macros with the same name as a keyword here. 198563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Identifier)) 198663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor return; 198763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 198863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Consume the first identifier. 198963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!ActiveModule->Parent) { 199063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 199163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 199263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 199363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 199463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor do { 199563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // If there's a comma, consume it. 199663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Comma)) 199763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 199863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 199963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 200063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // We expect to see a macro name here. 2001176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Support macros with the same name as a keyword here. 200263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Identifier)) { 200363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 200463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 200563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 200663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 200763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Consume the macro name. 200863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!ActiveModule->Parent) { 200963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 201063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 201163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 201263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } while (true); 201363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor} 201463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 2015906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// \brief Format a module-id into a string. 2016906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorstatic std::string formatModuleId(const ModuleId &Id) { 2017906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor std::string result; 2018906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor { 2019906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor llvm::raw_string_ostream OS(result); 2020906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2021906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2022906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (I) 2023906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor OS << "."; 2024906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor OS << Id[I].first; 2025906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 2026906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 2027906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2028906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return result; 2029906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 2030906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2031906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// \brief Parse a conflict declaration. 2032906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// 2033906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// module-declaration: 2034906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// 'conflict' module-id ',' string-literal 2035906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorvoid ModuleMapParser::parseConflict() { 2036906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor assert(Tok.is(MMToken::Conflict)); 2037906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor SourceLocation ConflictLoc = consumeToken(); 2038906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module::UnresolvedConflict Conflict; 2039906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2040906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the module-id. 2041906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (parseModuleId(Conflict.Id)) 2042906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 2043906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2044906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the ','. 2045906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Tok.is(MMToken::Comma)) { 2046906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2047906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << SourceRange(ConflictLoc); 2048906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 2049906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 2050906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor consumeToken(); 2051906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2052906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the message. 2053906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 2054906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2055906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << formatModuleId(Conflict.Id); 2056906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 2057906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 2058906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Message = Tok.getString().str(); 2059906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor consumeToken(); 2060906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2061906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Add this unresolved conflict. 2062906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor ActiveModule->UnresolvedConflicts.push_back(Conflict); 2063906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 2064906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 2065b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// \brief Parse an inferred module declaration (wildcard modules). 206682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 206782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// module-declaration: 206882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 206982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// { inferred-module-member* } 207082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 207182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// inferred-module-member: 207282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'export' '*' 207382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'exclude' identifier 207482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregorvoid ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 20751e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor assert(Tok.is(MMToken::Star)); 20761e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation StarLoc = consumeToken(); 20771e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Failed = false; 207882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 20791e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Inferred modules must be submodules. 208082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!ActiveModule && !Framework) { 20811e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 20821e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Failed = true; 20831e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 208482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 208582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 208682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Inferred modules must have umbrella directories. 20876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Failed && ActiveModule->IsAvailable && 20886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !ActiveModule->getUmbrellaDir()) { 208982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 209082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Failed = true; 209182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 209282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 209382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check for redefinition of an inferred module. 209482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Failed && ActiveModule->InferSubmodules) { 209582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 209682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule->InferredSubmoduleLoc.isValid()) 209782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(ActiveModule->InferredSubmoduleLoc, 209882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor diag::note_mmap_prev_definition); 209982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Failed = true; 210082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 210182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 210282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check for the 'framework' keyword, which is not permitted here. 210382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Framework) { 210482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 210582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Framework = false; 210682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 210782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } else if (Explicit) { 210882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 210982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Explicit = false; 21101e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 211182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 21121e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If there were any problems with this inferred submodule, skip its body. 21131e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Failed) { 21141e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::LBrace)) { 21151e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21161e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor skipUntil(MMToken::RBrace); 21171e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 21181e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21191e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 21201e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 21211e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 21221e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 212382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 212482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Parse optional attributes. 2125ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling Attributes Attrs; 212682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor parseOptionalAttributes(Attrs); 212782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 212882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 212982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Note that we have an inferred submodule. 213082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferSubmodules = true; 213182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferredSubmoduleLoc = StarLoc; 213282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferExplicitSubmodules = Explicit; 213382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } else { 213482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We'll be inferring framework modules for this directory. 213582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].InferModules = true; 21360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Map.InferredDirectories[Directory].Attrs = Attrs; 21376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: Handle the 'framework' keyword. 213982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 214082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 21411e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the opening brace. 21421e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 21431e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 21441e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 21451e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 21461e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 21471e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 21481e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 21491e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the body of the inferred submodule. 21501e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Done = false; 21511e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor do { 21521e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor switch (Tok.Kind) { 21531e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::EndOfFile: 21541e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::RBrace: 21551e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Done = true; 21561e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 215782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 215882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case MMToken::ExcludeKeyword: { 215982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 216082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 21616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << (ActiveModule != nullptr); 216282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 216382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 216482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 216582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 216682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 2167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Support string-literal module names here. 216882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::Identifier)) { 216982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 217082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 217182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 217282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 217382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].ExcludedModules 217482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .push_back(Tok.getString()); 217582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 217682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 217782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 217882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 217982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case MMToken::ExportKeyword: 218082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!ActiveModule) { 218182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 21826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << (ActiveModule != nullptr); 218382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 218482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 218582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 218682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 21871e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21881e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 2189ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferExportWildcard = true; 21901e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else 21911e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), 21921e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor diag::err_mmap_expected_export_wildcard); 21931e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21941e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 219582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 21961e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ExplicitKeyword: 21971e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ModuleKeyword: 21981e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::HeaderKeyword: 2199bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: 22001e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::UmbrellaKeyword: 22011e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor default: 220282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 22036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << (ActiveModule != nullptr); 22041e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 22051e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 22061e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 22071e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } while (!Done); 22081e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 22091e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 22101e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 22111e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else { 22121e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 22131e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 22141e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 22151e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 22161e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor} 22171e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 221882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \brief Parse optional attributes. 221982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 222082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attributes: 222182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute attributes 222282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute 222382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 222482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute: 222582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// [ identifier ] 222682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 222782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \param Attrs Will be filled in with the parsed attributes. 222882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 222982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \returns true if an error occurred, false otherwise. 2230ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendlingbool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 223182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool HadError = false; 223282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 223382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor while (Tok.is(MMToken::LSquare)) { 223482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Consume the '['. 223582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor SourceLocation LSquareLoc = consumeToken(); 223682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 223782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have an attribute name here. 223882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::Identifier)) { 223982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 224082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor skipUntil(MMToken::RSquare); 224182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Tok.is(MMToken::RSquare)) 224282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 224382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor HadError = true; 224482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 224582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 224682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Decode the attribute name. 224782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor AttributeKind Attribute 224882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor = llvm::StringSwitch<AttributeKind>(Tok.getString()) 224963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("exhaustive", AT_exhaustive) 2250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines .Case("extern_c", AT_extern_c) 225182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .Case("system", AT_system) 225282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .Default(AT_unknown); 225382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor switch (Attribute) { 225482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case AT_unknown: 225582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 225682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor << Tok.getString(); 225782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 225882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 225982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case AT_system: 226082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Attrs.IsSystem = true; 226182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 226263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 2263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case AT_extern_c: 2264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Attrs.IsExternC = true; 2265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 2266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 226763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case AT_exhaustive: 226863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attrs.IsExhaustive = true; 226963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 227082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 227182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 227282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 227382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Consume the ']'. 227482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::RSquare)) { 227582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 227682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 227782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor skipUntil(MMToken::RSquare); 227882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor HadError = true; 227982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 228082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 228182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Tok.is(MMToken::RSquare)) 228282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 228382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 228482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 228582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return HadError; 228682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor} 228782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 2288a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module map file. 2289a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 2290a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-map-file: 2291a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration* 2292a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool ModuleMapParser::parseModuleMapFile() { 2293a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 2294a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 2295a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 2296a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return HadError; 2297a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2298587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor case MMToken::ExplicitKeyword: 22995f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper case MMToken::ExternKeyword: 2300a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 2301a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor case MMToken::FrameworkKeyword: 2302a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 2303a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 2304b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 230551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::Comma: 230663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case MMToken::ConfigMacros: 2307906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor case MMToken::Conflict: 23085794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith case MMToken::Exclaim: 23092b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor case MMToken::ExcludeKeyword: 231090db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 2311a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::HeaderKeyword: 2312a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::Identifier: 2313a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 2314b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor case MMToken::LinkKeyword: 2315a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::LSquare: 231690db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Period: 2317bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: 2318a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 2319a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::RSquare: 232051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::RequiresKeyword: 232190db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Star: 2322a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::StringLiteral: 2323176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case MMToken::TextualKeyword: 2324a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::UmbrellaKeyword: 2325ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper case MMToken::UseKeyword: 2326a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2327a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 2328a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 2329a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 2330a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 2331a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 2332a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 2333a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 23340e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 23350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines const DirectoryEntry *Dir) { 23367005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor llvm::DenseMap<const FileEntry *, bool>::iterator Known 23377005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor = ParsedModuleMap.find(File); 23387005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (Known != ParsedModuleMap.end()) 23397005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return Known->second; 23407005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 23416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Target && "Missing target information"); 2342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter); 2344ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2345a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Buffer) 23467005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return ParsedModuleMap[File] = true; 2347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2348a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse this module map file. 2349ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 23506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 23518f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor BuiltinIncludeDir, IsSystem); 2352a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Result = Parser.parseModuleMapFile(); 23537005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor ParsedModuleMap[File] = Result; 2354a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 2355a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 2356