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" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/LexDiagnostic.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/LiteralSupport.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringRef.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h" 27a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/Allocator.h" 28ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor#include "llvm/Support/FileSystem.h" 29a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/Host.h" 308229d22e6449851b89361bf2f41804557328be63Rafael Espindola#include "llvm/Support/Path.h" 31a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "llvm/Support/raw_ostream.h" 3298cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor#include <stdlib.h> 333cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#if defined(LLVM_ON_UNIX) 34adeb7822cb7947194fef0e12d2d6583ccb8240b5Dmitri Gribenko#include <limits.h> 353cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#endif 36a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorusing namespace clang; 37a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 3890db26000aefe9335370013eec64c85232d80227Douglas GregorModule::ExportDecl 3990db26000aefe9335370013eec64c85232d80227Douglas GregorModuleMap::resolveExport(Module *Mod, 4090db26000aefe9335370013eec64c85232d80227Douglas Gregor const Module::UnresolvedExportDecl &Unresolved, 410be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis bool Complain) const { 420adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor // We may have just a wildcard. 430adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Unresolved.Id.empty()) { 440adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor assert(Unresolved.Wildcard && "Invalid unresolved export"); 456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Module::ExportDecl(nullptr, true); 460adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor } 470adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor 48906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Resolve the module-id. 49906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 50906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Context) 51906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Module::ExportDecl(); 52906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 53906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Module::ExportDecl(Context, Unresolved.Wildcard); 54906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 55906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 56906d66acc5cf2679453e10a4f0a67feedd765b21Douglas GregorModule *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 57906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor bool Complain) const { 5890db26000aefe9335370013eec64c85232d80227Douglas Gregor // Find the starting module. 59906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 6090db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) { 6190db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Complain) 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 63906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << Id[0].first << Mod->getFullModuleName(); 64906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6690db26000aefe9335370013eec64c85232d80227Douglas Gregor } 6790db26000aefe9335370013eec64c85232d80227Douglas Gregor 6890db26000aefe9335370013eec64c85232d80227Douglas Gregor // Dig into the module path. 69906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 1, N = Id.size(); I != N; ++I) { 70906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *Sub = lookupModuleQualified(Id[I].first, Context); 7190db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Sub) { 7290db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Complain) 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 74906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << Id[I].first << Context->getFullModuleName() 75906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << SourceRange(Id[0].second, Id[I-1].second); 76906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 7890db26000aefe9335370013eec64c85232d80227Douglas Gregor } 79906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 8090db26000aefe9335370013eec64c85232d80227Douglas Gregor Context = Sub; 8190db26000aefe9335370013eec64c85232d80227Douglas Gregor } 82906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 83906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Context; 8490db26000aefe9335370013eec64c85232d80227Douglas Gregor} 8590db26000aefe9335370013eec64c85232d80227Douglas Gregor 86651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 8755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis const LangOptions &LangOpts, const TargetInfo *Target, 8855ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HeaderSearch &HeaderInfo) 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), 916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CompilingModule(nullptr), SourceModule(nullptr) {} 92a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 93a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorModuleMap::~ModuleMap() { 9409fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 9509fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor IEnd = Modules.end(); 9609fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor I != IEnd; ++I) { 9709fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor delete I->getValue(); 9809fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor } 99a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 100a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 101dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregorvoid ModuleMap::setTarget(const TargetInfo &Target) { 102dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor assert((!this->Target || this->Target == &Target) && 103dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor "Improper target override"); 104dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor this->Target = &Target; 105dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor} 106dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor 1078b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor/// \brief "Sanitize" a filename so that it can be used as an identifier. 1088b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregorstatic StringRef sanitizeFilenameAsIdentifier(StringRef Name, 1098b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallVectorImpl<char> &Buffer) { 1108b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor if (Name.empty()) 1118b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor return Name; 1128b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1133f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (!isValidIdentifier(Name)) { 1148b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor // If we don't already have something with the form of an identifier, 1158b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor // create a buffer with the sanitized name. 1168b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.clear(); 1173f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isDigit(Name[0])) 1188b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1198b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.reserve(Buffer.size() + Name.size()); 1208b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor for (unsigned I = 0, N = Name.size(); I != N; ++I) { 1213f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isIdentifierBody(Name[I])) 1228b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back(Name[I]); 1238b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor else 1248b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1258b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1268b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1278b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Name = StringRef(Buffer.data(), Buffer.size()); 1288b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1298b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1308b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor while (llvm::StringSwitch<bool>(Name) 1318b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 1328b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 1338b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#include "clang/Basic/TokenKinds.def" 1348b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor .Default(false)) { 1358b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor if (Name.data() != Buffer.data()) 1368b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.append(Name.begin(), Name.end()); 1378b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1388b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Name = StringRef(Buffer.data(), Buffer.size()); 1398b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1408b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1418b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor return Name; 1428b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor} 1438b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 144db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// \brief Determine whether the given file name is the name of a builtin 145db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// header, supplied by Clang to replace, override, or augment existing system 146db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// headers. 147db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregorstatic bool isBuiltinHeader(StringRef FileName) { 148db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor return llvm::StringSwitch<bool>(FileName) 149db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("float.h", true) 150db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("iso646.h", true) 151db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("limits.h", true) 152db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdalign.h", true) 153db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdarg.h", true) 154db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdbool.h", true) 155db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stddef.h", true) 156db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdint.h", true) 157db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("tgmath.h", true) 158db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("unwind.h", true) 159db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Default(false); 160db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor} 161db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 162651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModuleMap::HeadersMap::iterator 163651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModuleMap::findKnownHeader(const FileEntry *File) { 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeadersMap::iterator Known = Headers.find(File); 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir && 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderInfo.loadTopLevelSystemModules(); 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Headers.find(File); 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Known; 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::KnownHeader 1746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, 1756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { 1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DirectoryEntry *Dir = File->getDir(); 1776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Dir && "file in no directory"); 1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Note: as an egregious but useful hack we use the real path here, because 1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // frameworks moving from top-level frameworks to embedded frameworks tend 1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // to be symlinked from the top-level location to the embedded location, 1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // and we need to resolve lookups as if we had found the embedded location. 1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Keep walking up the directory hierarchy, looking for a directory with 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // an umbrella header. 1876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines do { 1886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto KnownDir = UmbrellaDirs.find(Dir); 1896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (KnownDir != UmbrellaDirs.end()) 1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return KnownHeader(KnownDir->second, NormalHeader); 1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntermediateDirs.push_back(Dir); 1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Retrieve our parent path. 1956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DirName = llvm::sys::path::parent_path(DirName); 1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (DirName.empty()) 1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Resolve the parent path to a directory entry. 2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Dir = SourceMgr.getFileManager().getDirectory(DirName); 2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } while (Dir); 2026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return KnownHeader(); 2036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'. 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool directlyUses(const Module *RequestingModule, 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Module *RequestedModule) { 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return std::find(RequestingModule->DirectUses.begin(), 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RequestingModule->DirectUses.end(), 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RequestedModule) != RequestingModule->DirectUses.end(); 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool violatesPrivateInclude(Module *RequestingModule, 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *IncFileEnt, 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ModuleMap::ModuleHeaderRole Role, 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Module *RequestedModule) { 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines #ifndef NDEBUG 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check for consistency between the module header role 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // as obtained from the lookup and as obtained from the module. 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // This check is not cheap, so enable it only for debugging. 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallVectorImpl<const FileEntry *> &PvtHdrs 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines = RequestedModule->PrivateHeaders; 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallVectorImpl<const FileEntry *>::iterator Look 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt); 225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsPrivate = Look != PvtHdrs.end(); 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((IsPrivate && Role == ModuleMap::PrivateHeader) 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines || (!IsPrivate && Role != ModuleMap::PrivateHeader)); 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines #endif 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Role == ModuleMap::PrivateHeader && 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RequestedModule->getTopLevelModule() != RequestingModule; 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic Module *getTopLevelOrNull(Module *M) { 2346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return M ? M->getTopLevelModule() : nullptr; 2356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 2366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation FilenameLoc, 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Filename, 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *File) { 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // No errors for indirect modules. This may be a bit of a problem for modules 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // with no source files. 2436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (RequestingModule) 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines resolveUses(RequestingModule, /*Complain=*/false); 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Excluded = false; 2506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *Private = nullptr; 2516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *NotUsed = nullptr; 2526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeadersMap::iterator Known = findKnownHeader(File); 2546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Known != Headers.end()) { 2556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (const KnownHeader &Header : Known->second) { 2566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Excluded headers don't really belong to a module. 2576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Header.getRole() == ModuleMap::ExcludedHeader) { 2586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Excluded = true; 2596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 2606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If 'File' is part of 'RequestingModule' we can definitely include it. 2636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Header.getModule() == RequestingModule) 2646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Remember private headers for later printing of a diagnostic. 2676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (violatesPrivateInclude(RequestingModule, File, Header.getRole(), 2686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Header.getModule())) { 2696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Private = Header.getModule(); 2706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 2716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If uses need to be specified explicitly, we are only allowed to return 2746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // modules that are explicitly used by the requesting module. 2756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RequestingModule && LangOpts.ModulesDeclUse && 2766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !directlyUses(RequestingModule, Header.getModule())) { 2776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NotUsed = Header.getModule(); 2786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 2796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // We have found a module that we can happily use. 2826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 283651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We have found a header, but it is private. 2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Private) { 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module) 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Filename; 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We have found a module, but we don't use it. 2946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (NotUsed) { 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << RequestingModule->getFullModuleName() << Filename; 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Excluded || isHeaderInUmbrellaDirs(File)) 3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 3026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // At this point, only non-modular includes remain. 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (LangOpts.ModulesStrictDeclUse) { 3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) 3076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << RequestingModule->getFullModuleName() << Filename; 3086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (RequestingModule) { 3096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? 3106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::warn_non_modular_include_in_framework_module : 3116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::warn_non_modular_include_in_module; 3126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName(); 3136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 316c641709607d45bf97772e925647db6c94866c50aDaniel JasperModuleMap::KnownHeader 317c641709607d45bf97772e925647db6c94866c50aDaniel JasperModuleMap::findModuleForHeader(const FileEntry *File, 318c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Module *RequestingModule) { 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeadersMap::iterator Known = findKnownHeader(File); 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 32151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (Known != Headers.end()) { 322c641709607d45bf97772e925647db6c94866c50aDaniel Jasper ModuleMap::KnownHeader Result = KnownHeader(); 323c641709607d45bf97772e925647db6c94866c50aDaniel Jasper 324c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // Iterate over all modules that 'File' is part of to find the best fit. 325c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 326c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = Known->second.end(); 327c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Cannot use a module if the header is excluded in it. 329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I->getRole() == ModuleMap::ExcludedHeader) 330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Cannot use a module if it is unavailable. 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!I->getModule()->isAvailable()) 334c641709607d45bf97772e925647db6c94866c50aDaniel Jasper continue; 33551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 336c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // If 'File' is part of 'RequestingModule', 'RequestingModule' is the 337c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // module we are looking for. 338c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (I->getModule() == RequestingModule) 339c641709607d45bf97772e925647db6c94866c50aDaniel Jasper return *I; 340c641709607d45bf97772e925647db6c94866c50aDaniel Jasper 341c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // If uses need to be specified explicitly, we are only allowed to return 342c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // modules that are explicitly used by the requesting module. 343c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (RequestingModule && LangOpts.ModulesDeclUse && 344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !directlyUses(RequestingModule, I->getModule())) 345c641709607d45bf97772e925647db6c94866c50aDaniel Jasper continue; 346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 347c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Result = *I; 348c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // If 'File' is a public header of this module, this is as good as we 349c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // are going to get. 350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: If we have a RequestingModule, we should prefer the header from 351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // that module. 352c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (I->getRole() == ModuleMap::NormalHeader) 353c641709607d45bf97772e925647db6c94866c50aDaniel Jasper break; 354c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 355c641709607d45bf97772e925647db6c94866c50aDaniel Jasper return Result; 35651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 357db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 358cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> SkippedDirs; 3596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); 3606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (H) { 3616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *Result = H.getModule(); 3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Search up the module stack until we find a module with an umbrella 3646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // directory. 3656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *UmbrellaModule = Result; 3666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 3676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UmbrellaModule = UmbrellaModule->Parent; 3686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (UmbrellaModule->InferSubmodules) { 3706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Infer submodules for each of the directories we found between 3716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the directory of the umbrella header and the directory where 3726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the actual header is located. 3736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Explicit = UmbrellaModule->InferExplicitSubmodules; 3746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned I = SkippedDirs.size(); I != 0; --I) { 3766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Find or create the module that corresponds to this directory name. 3778b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 3788b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 3796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf); 3806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap, 3816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*IsFramework=*/false, Explicit).first; 3826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->IsInferred = true; 3836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Associate the module and the directory. 3856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UmbrellaDirs[SkippedDirs[I-1]] = Result; 3866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If inferred submodules export everything they import, add a 388e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // wildcard to the set of exports. 3899f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 3906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 391e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 39251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 3936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Infer a submodule with the same name as this header file. 3946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallString<32> NameBuf; 3956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef Name = sanitizeFilenameAsIdentifier( 3966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::path::stem(File->getName()), NameBuf); 3976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap, 3986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*IsFramework=*/false, Explicit).first; 3996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->IsInferred = true; 4006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->addTopHeader(File); 4016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If inferred submodules export everything they import, add a 4036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // wildcard to the set of exports. 4046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 4056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 4066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 4076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Record each of the directories we stepped through as being part of 4086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the module we found, since the umbrella header covers them all. 4096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 4106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UmbrellaDirs[SkippedDirs[I]] = Result; 411adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor } 4126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Headers[File].push_back(KnownHeader(Result, NormalHeader)); 4146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If a header corresponds to an unavailable module, don't report 4166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // that it maps to anything. 4176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Result->isAvailable()) 4186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return KnownHeader(); 4196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Headers[File].back(); 4216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 422adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 423bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return KnownHeader(); 42465f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor} 42565f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 4260be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidisbool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 4276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return isHeaderUnavailableInModule(Header, nullptr); 4286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool 4316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, 4326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Module *RequestingModule) const { 4330be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis HeadersMap::const_iterator Known = Headers.find(Header); 434c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (Known != Headers.end()) { 435c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (SmallVectorImpl<KnownHeader>::const_iterator 436c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I = Known->second.begin(), 437c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = Known->second.end(); 438c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 4396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (I->isAvailable() && (!RequestingModule || 4406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines I->getModule()->isSubModuleOf(RequestingModule))) 441c641709607d45bf97772e925647db6c94866c50aDaniel Jasper return false; 442c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 443c641709607d45bf97772e925647db6c94866c50aDaniel Jasper return true; 444c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 4456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 44651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor const DirectoryEntry *Dir = Header->getDir(); 447cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> SkippedDirs; 44851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor StringRef DirName = Dir->getName(); 44951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 4506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto IsUnavailable = [&](const Module *M) { 4516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return !M->isAvailable() && (!RequestingModule || 4526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines M->isSubModuleOf(RequestingModule)); 4536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }; 4546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 45551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Keep walking up the directory hierarchy, looking for a directory with 45651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // an umbrella header. 4576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines do { 4580be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 45951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor = UmbrellaDirs.find(Dir); 46051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (KnownDir != UmbrellaDirs.end()) { 46151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Module *Found = KnownDir->second; 4626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (IsUnavailable(Found)) 46351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return true; 46451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 46551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Search up the module stack until we find a module with an umbrella 46651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // directory. 46751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Module *UmbrellaModule = Found; 46851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 46951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor UmbrellaModule = UmbrellaModule->Parent; 47051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 47151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (UmbrellaModule->InferSubmodules) { 47251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor for (unsigned I = SkippedDirs.size(); I != 0; --I) { 47351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Find or create the module that corresponds to this directory name. 4748b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 4758b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 4768b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 4778b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 47851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Found = lookupModuleQualified(Name, Found); 47951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found) 48051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 4816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (IsUnavailable(Found)) 48251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return true; 48351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 48451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 48551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Infer a submodule with the same name as this header file. 4868b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 4878b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 4888b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(Header->getName()), 4898b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 49051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Found = lookupModuleQualified(Name, Found); 49151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found) 49251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 49351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 49451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 4956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return IsUnavailable(Found); 49651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 49751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 49851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor SkippedDirs.push_back(Dir); 49951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 50051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Retrieve our parent path. 50151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 50251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (DirName.empty()) 50351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 50451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 50551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Resolve the parent path to a directory entry. 506ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Dir = SourceMgr.getFileManager().getDirectory(DirName); 50751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } while (Dir); 50851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 50951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 51051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor} 51151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 5120be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::findModule(StringRef Name) const { 5130be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 514484535e45b4d301847a157e943c7823da5d40884Douglas Gregor if (Known != Modules.end()) 515484535e45b4d301847a157e943c7823da5d40884Douglas Gregor return Known->getValue(); 5166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 518484535e45b4d301847a157e943c7823da5d40884Douglas Gregor} 519484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 5200be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::lookupModuleUnqualified(StringRef Name, 5210be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis Module *Context) const { 52290db26000aefe9335370013eec64c85232d80227Douglas Gregor for(; Context; Context = Context->Parent) { 52390db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Context)) 52490db26000aefe9335370013eec64c85232d80227Douglas Gregor return Sub; 52590db26000aefe9335370013eec64c85232d80227Douglas Gregor } 52690db26000aefe9335370013eec64c85232d80227Douglas Gregor 52790db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 52890db26000aefe9335370013eec64c85232d80227Douglas Gregor} 52990db26000aefe9335370013eec64c85232d80227Douglas Gregor 5300be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 53190db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) 53290db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 53390db26000aefe9335370013eec64c85232d80227Douglas Gregor 534b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor return Context->findSubmodule(Name); 53590db26000aefe9335370013eec64c85232d80227Douglas Gregor} 53690db26000aefe9335370013eec64c85232d80227Douglas Gregor 5371a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorstd::pair<Module *, bool> 5386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesModuleMap::findOrCreateModule(StringRef Name, Module *Parent, 5396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMap, bool IsFramework, 540392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor bool IsExplicit) { 541392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Try to find an existing module with this name. 542b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Parent)) 543b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor return std::make_pair(Sub, false); 544392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 545392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Create a new module with this name. 5466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap, 5476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IsFramework, IsExplicit); 548ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper if (LangOpts.CurrentModule == Name) { 549ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModule = Result; 550ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModuleName = Name; 551ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper } 552d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis if (!Parent) { 553392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Modules[Name] = Result; 554d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis if (!LangOpts.CurrentModule.empty() && !CompilingModule && 555d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis Name == LangOpts.CurrentModule) { 556d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis CompilingModule = Result; 557d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis } 558d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis } 559392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor return std::make_pair(Result, true); 560392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor} 561392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 56282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregorbool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 5630be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis StringRef Name, bool &IsSystem) const { 56482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have already looked into the parent directory 56582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // for a module map. 5660be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 56782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 56882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) 56982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return false; 57082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 57182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!inferred->second.InferModules) 57282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return false; 57382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 57482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We're allowed to infer for this directory, but make sure it's okay 57582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // to infer this particular module. 57682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 57782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred->second.ExcludedModules.end(), 57882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Name) == inferred->second.ExcludedModules.end(); 57982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 58082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (canInfer && inferred->second.InferSystemModules) 58182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor IsSystem = true; 58282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 58382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return canInfer; 58482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor} 58582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 5868767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor/// \brief For a framework module, infer the framework against which we 5878767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor/// should link. 5888767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregorstatic void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 5898767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor FileManager &FileMgr) { 5908767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor assert(Mod->IsFramework && "Can only infer linking for framework modules"); 5918767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor assert(!Mod->isSubFramework() && 5928767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor "Can only infer linking for top-level frameworks"); 5938767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 5948767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor SmallString<128> LibName; 5958767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor LibName += FrameworkDir->getName(); 5968767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor llvm::sys::path::append(LibName, Mod->Name); 5978767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (FileMgr.getFile(LibName)) { 5988767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 5998767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor /*IsFramework=*/true)); 6008767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 6018767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor} 6028767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 6031a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule * 60482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas GregorModuleMap::inferFrameworkModule(StringRef ModuleName, 605ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const DirectoryEntry *FrameworkDir, 606a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor bool IsSystem, 607ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Module *Parent) { 6082821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Check whether we've already found this module. 609ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 610ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor return Mod; 611ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 612ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek FileManager &FileMgr = SourceMgr.getFileManager(); 61382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 61482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // If the framework has a parent path from which we're allowed to infer 61582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // a framework module, do so. 6166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMapFile = nullptr; 61782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Parent) { 6187005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether we're allowed to infer a module map. 619713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 6207005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Note: as an egregious but useful hack we use the real path here, because 6217005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // we might be looking at an embedded framework that symlinks out to a 6227005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // top-level framework, and we need to infer as if we were naming the 6237005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // top-level framework. 624713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef FrameworkDirName 625ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek = SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 6267005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 62782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool canInfer = false; 6287005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 62982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Figure out the parent path. 6307005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 63182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 63282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have already looked into the parent directory 63382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // for a module map. 6340be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 63582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 63682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) { 63782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We haven't looked here before. Load a module map, if there is 63882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // one. 639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsFrameworkDir = Parent.endswith(".framework"); 640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FileEntry *ModMapFile = 641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { 6428f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor parseModuleMapFile(ModMapFile, IsSystem); 64382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 64482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 64582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 64682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) 64782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.insert( 64882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor std::make_pair(ParentDir, InferredDirectory())).first; 64982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 65082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 65182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred->second.InferModules) { 65282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We're allowed to infer for this directory, but make sure it's okay 65382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // to infer this particular module. 6547005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef Name = llvm::sys::path::stem(FrameworkDirName); 65582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor canInfer = std::find(inferred->second.ExcludedModules.begin(), 65682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred->second.ExcludedModules.end(), 65782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Name) == inferred->second.ExcludedModules.end(); 65882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 65982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred->second.InferSystemModules) 66082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor IsSystem = true; 6616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapFile = inferred->second.ModuleMapFile; 66282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 66382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 66482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 66582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 66682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // If we're not allowed to infer a framework module, don't. 66782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!canInfer) 6686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else 6706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapFile = Parent->ModuleMap; 67182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 67282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 6732821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Look for an umbrella header. 674f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 675ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 676ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 6772821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 6782821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // FIXME: If there's no umbrella header, we could probably scan the 6792821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // framework to load *everything*. But, it's not clear that this is a good 6802821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // idea. 6812821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor if (!UmbrellaHeader) 6826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile, 685ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor /*IsFramework=*/true, /*IsExplicit=*/false); 686ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper if (LangOpts.CurrentModule == ModuleName) { 687ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModule = Result; 688ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper SourceModuleName = ModuleName; 689ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper } 690a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (IsSystem) 691a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Result->IsSystem = IsSystem; 692a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 693b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (!Parent) 694ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Modules[ModuleName] = Result; 695b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor 696489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // umbrella header "umbrella-header-name" 69710694cee2588442bee1e717f5042c58ffee25279Douglas Gregor Result->Umbrella = UmbrellaHeader; 698c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); 6993cee31e4d7c23d3d5d0b8927998577b9f75087d7Douglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 700209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor 701209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor // export * 7026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 7036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 704e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // module * { export * } 705e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferSubmodules = true; 706e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferExportWildcard = true; 707e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 708ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // Look for subframeworks. 709ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 710f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> SubframeworksDirName 71152b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor = StringRef(FrameworkDir->getName()); 712ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 7130f599acfd685437d1344f82ce363f994b0729a2fBenjamin Kramer llvm::sys::path::native(SubframeworksDirName); 71452b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor for (llvm::sys::fs::directory_iterator 7150f599acfd685437d1344f82ce363f994b0729a2fBenjamin Kramer Dir(SubframeworksDirName.str(), EC), DirEnd; 716ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 717ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (!StringRef(Dir->path()).endswith(".framework")) 718ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor continue; 71998cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 720ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (const DirectoryEntry *SubframeworkDir 721ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor = FileMgr.getDirectory(Dir->path())) { 72298cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // Note: as an egregious but useful hack, we use the real path here and 72398cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // check whether it is actually a subdirectory of the parent directory. 72498cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // This will not be the case if the 'subframework' is actually a symlink 72598cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // out to a top-level framework. 726713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 727713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor bool FoundParent = false; 728713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor do { 729713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor // Get the parent directory name. 730713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor SubframeworkDirName 731713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor = llvm::sys::path::parent_path(SubframeworkDirName); 732713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (SubframeworkDirName.empty()) 733713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor break; 734713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 735713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 736713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor FoundParent = true; 737713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor break; 738713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor } 739713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor } while (true); 74098cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 741713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (!FoundParent) 742713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor continue; 74398cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 744ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // FIXME: Do we want to warn about subframeworks without umbrella headers? 7458b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 7468b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor inferFrameworkModule(sanitizeFilenameAsIdentifier( 7478b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(Dir->path()), NameBuf), 7488b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SubframeworkDir, IsSystem, Result); 749ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 750ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 7513a110f75acafc992cb664200cebec90520986715Douglas Gregor 7528767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // If the module is a top-level framework, automatically link against the 7538767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // framework. 7548767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (!Result->isSubFramework()) { 7558767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor inferFrameworkLink(Result, FrameworkDir, FileMgr); 7568767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 7578767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 7582821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Result; 7592821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 7602821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 761e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregorvoid ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 762c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 76310694cee2588442bee1e717f5042c58ffee25279Douglas Gregor Mod->Umbrella = UmbrellaHeader; 7646a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 765e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 766e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 76777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregorvoid ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 76877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Mod->Umbrella = UmbrellaDir; 76977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor UmbrellaDirs[UmbrellaDir] = Mod; 77077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor} 77177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 7722b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregorvoid ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 773bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleHeaderRole Role) { 774bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Role == ExcludedHeader) { 7752b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor Mod->ExcludedHeaders.push_back(Header); 77655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } else { 777bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Role == PrivateHeader) 778bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Mod->PrivateHeaders.push_back(Header); 779bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl else 780bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Mod->NormalHeaders.push_back(Header); 781d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 782bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); 78355ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } 784c641709607d45bf97772e925647db6c94866c50aDaniel Jasper Headers[Header].push_back(KnownHeader(Mod, Role)); 785e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 786e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 787f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregorconst FileEntry * 7880be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModuleMap::getContainingModuleMapFile(Module *Module) const { 789ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek if (Module->DefinitionLoc.isInvalid()) 7906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 791f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 792ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek return SourceMgr.getFileEntryForID( 793ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek SourceMgr.getFileID(Module->DefinitionLoc)); 794f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor} 795f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 796a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMap::dump() { 797a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Modules:"; 798a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 799a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MEnd = Modules.end(); 800a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor M != MEnd; ++M) 801804c3bfee22076f232dddf4839439119cfdee2b6Douglas Gregor M->getValue()->print(llvm::errs(), 2); 802a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 803a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Headers:"; 8042b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 805a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor H != HEnd; ++H) { 806c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << " \"" << H->first->getName() << "\" -> "; 807c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 808c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = H->second.end(); 809c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 810c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (I != H->second.begin()) 811c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << ","; 812c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << I->getModule()->getFullModuleName(); 813c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 814c641709607d45bf97772e925647db6c94866c50aDaniel Jasper llvm::errs() << "\n"; 815a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 816a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 817a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 81890db26000aefe9335370013eec64c85232d80227Douglas Gregorbool ModuleMap::resolveExports(Module *Mod, bool Complain) { 81990db26000aefe9335370013eec64c85232d80227Douglas Gregor bool HadError = false; 82090db26000aefe9335370013eec64c85232d80227Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 82190db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 82290db26000aefe9335370013eec64c85232d80227Douglas Gregor Complain); 8230adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Export.getPointer() || Export.getInt()) 82490db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->Exports.push_back(Export); 82590db26000aefe9335370013eec64c85232d80227Douglas Gregor else 82690db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 82790db26000aefe9335370013eec64c85232d80227Douglas Gregor } 82890db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->UnresolvedExports.clear(); 82990db26000aefe9335370013eec64c85232d80227Douglas Gregor return HadError; 83090db26000aefe9335370013eec64c85232d80227Douglas Gregor} 83190db26000aefe9335370013eec64c85232d80227Douglas Gregor 832ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasperbool ModuleMap::resolveUses(Module *Mod, bool Complain) { 833ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper bool HadError = false; 834ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 835ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Module *DirectUse = 836ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 837ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper if (DirectUse) 838ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Mod->DirectUses.push_back(DirectUse); 839ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper else 840ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper HadError = true; 841ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper } 842ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Mod->UnresolvedDirectUses.clear(); 843ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper return HadError; 844ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper} 845ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 846906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorbool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 847906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor bool HadError = false; 848906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 849906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 850906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod, Complain); 851906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!OtherMod) { 852906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor HadError = true; 853906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor continue; 854906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 855906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 856906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module::Conflict Conflict; 857906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Other = OtherMod; 858906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Message = Mod->UnresolvedConflicts[I].Message; 859906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod->Conflicts.push_back(Conflict); 860906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 861906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod->UnresolvedConflicts.clear(); 862906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return HadError; 863906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 864906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 86555988680ece66b8e505ee136b35e74fcb1173aeeDouglas GregorModule *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 86655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (Loc.isInvalid()) 8676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 86955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Use the expansion location to determine which module we're in. 87055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 87155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (!ExpansionLoc.isFileID()) 8726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 87455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor const SourceManager &SrcMgr = Loc.getManager(); 87555988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FileID ExpansionFileID = ExpansionLoc.getFileID(); 87655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 877303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor while (const FileEntry *ExpansionFile 878303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor = SrcMgr.getFileEntryForID(ExpansionFileID)) { 879303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // Find the module that owns this header (if any). 880bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 881303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor return Mod; 882303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor 883303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // No module owns this header, so look up the inclusion chain to see if 884303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // any included header has an associated module. 885303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 886303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor if (IncludeLoc.isInvalid()) 8876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 889303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 890303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor } 8916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 89355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor} 89455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 895a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 896a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// Module map file parser 897a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 898a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 899a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregornamespace clang { 900a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief A token in a module map file. 901a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor struct MMToken { 902a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor enum TokenKind { 90351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Comma, 90463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ConfigMacros, 905906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict, 906a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor EndOfFile, 907a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HeaderKeyword, 908a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Identifier, 9095794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith Exclaim, 9102b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor ExcludeKeyword, 911a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ExplicitKeyword, 91290db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportKeyword, 9135f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ExternKeyword, 914a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor FrameworkKeyword, 915b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor LinkKeyword, 916a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleKeyword, 91790db26000aefe9335370013eec64c85232d80227Douglas Gregor Period, 918bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl PrivateKeyword, 919a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor UmbrellaKeyword, 920ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper UseKeyword, 92151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor RequiresKeyword, 92290db26000aefe9335370013eec64c85232d80227Douglas Gregor Star, 923a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLiteral, 924a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LBrace, 925a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor RBrace, 926a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor LSquare, 927a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor RSquare 928a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } Kind; 929a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 930a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Location; 931a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned StringLength; 932a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const char *StringData; 933a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 934a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void clear() { 935a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Kind = EndOfFile; 936a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Location = 0; 937a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLength = 0; 9386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringData = nullptr; 939a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 940a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 941a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool is(TokenKind K) const { return Kind == K; } 942a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 943a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation getLocation() const { 944a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return SourceLocation::getFromRawEncoding(Location); 945a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 946a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 947a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef getString() const { 948a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return StringRef(StringData, StringLength); 949a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 950a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 95182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 95282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor /// \brief The set of attributes that can be attached to a module. 953ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling struct Attributes { 954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Attributes() : IsSystem(), IsExternC(), IsExhaustive() { } 95582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 95682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor /// \brief Whether this is a system module. 95782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor unsigned IsSystem : 1; 95863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 959651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Whether this is an extern "C" module. 960651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned IsExternC : 1; 961651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 96263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor /// \brief Whether this is an exhaustive set of configuration macros. 96363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor unsigned IsExhaustive : 1; 96482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor }; 965a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 96682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 967a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor class ModuleMapParser { 968a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Lexer &L; 969a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceManager &SourceMgr; 9709a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 9719a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor /// \brief Default target information, used only for string literal 9729a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor /// parsing. 9739a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor const TargetInfo *Target; 9749a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 975a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags; 976a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleMap ⤅ 9776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief The current module map file. 9796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMapFile; 980a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 9818b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor /// \brief The directory that this module map resides in. 9828b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor const DirectoryEntry *Directory; 9832f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 9842f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor /// \brief The directory containing Clang-supplied headers. 9852f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const DirectoryEntry *BuiltinIncludeDir; 9862f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 9878f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor /// \brief Whether this module map is in a system header directory. 9888f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem; 9898f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor 990a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Whether an error occurred. 991a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool HadError; 9929a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 993a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Stores string data for the various string literals referenced 994a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// during parsing. 995a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::BumpPtrAllocator StringData; 996a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 997a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The current token. 998a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MMToken Tok; 999a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1000a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The active module. 10011a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Module *ActiveModule; 1002a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1003a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Consume the current token and return its location. 1004a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation consumeToken(); 1005a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1006a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Skip tokens until we reach the a token with the given kind 1007a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// (or the end of the file). 1008a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void skipUntil(MMToken::TokenKind K); 1009587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1010cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1011587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor bool parseModuleId(ModuleId &Id); 1012a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void parseModuleDecl(); 10135f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper void parseExternModuleDecl(); 101451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor void parseRequiresDecl(); 1015bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl void parseHeaderDecl(clang::MMToken::TokenKind, 1016bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation LeadingLoc); 101777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 101890db26000aefe9335370013eec64c85232d80227Douglas Gregor void parseExportDecl(); 1019ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper void parseUseDecl(); 1020b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor void parseLinkDecl(); 102163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor void parseConfigMacros(); 1022906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor void parseConflict(); 102382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor void parseInferredModuleDecl(bool Framework, bool Explicit); 1024ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling bool parseOptionalAttributes(Attributes &Attrs); 10256a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor 1026a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor public: 1027a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 10289a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor const TargetInfo *Target, 1029a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags, 10308b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor ModuleMap &Map, 10316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMapFile, 10322f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const DirectoryEntry *Directory, 10338f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor const DirectoryEntry *BuiltinIncludeDir, 10348f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem) 10359a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 10366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapFile(ModuleMapFile), Directory(Directory), 10376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem), 10386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HadError(false), ActiveModule(nullptr) 1039a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor { 1040a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 1041a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1042a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1043a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1044a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool parseModuleMapFile(); 1045a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 1046a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1047a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1048a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorSourceLocation ModuleMapParser::consumeToken() { 1049a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorretry: 1050a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation Result = Tok.getLocation(); 1051a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 1052a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1053a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Token LToken; 1054a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor L.LexFromRawLexer(LToken); 1055a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Location = LToken.getLocation().getRawEncoding(); 1056a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (LToken.getKind()) { 10576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case tok::raw_identifier: { 10586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef RI = LToken.getRawIdentifier(); 10596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tok.StringData = RI.data(); 10606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tok.StringLength = RI.size(); 10616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 106263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("config_macros", MMToken::ConfigMacros) 1063906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor .Case("conflict", MMToken::Conflict) 10642b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor .Case("exclude", MMToken::ExcludeKeyword) 1065a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("explicit", MMToken::ExplicitKeyword) 106690db26000aefe9335370013eec64c85232d80227Douglas Gregor .Case("export", MMToken::ExportKeyword) 10675f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper .Case("extern", MMToken::ExternKeyword) 1068a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor .Case("framework", MMToken::FrameworkKeyword) 106963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("header", MMToken::HeaderKeyword) 1070b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor .Case("link", MMToken::LinkKeyword) 1071a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("module", MMToken::ModuleKeyword) 1072bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl .Case("private", MMToken::PrivateKeyword) 107351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor .Case("requires", MMToken::RequiresKeyword) 1074a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("umbrella", MMToken::UmbrellaKeyword) 1075ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper .Case("use", MMToken::UseKeyword) 1076a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Default(MMToken::Identifier); 1077a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 10786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 107951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 108051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case tok::comma: 108151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Tok.Kind = MMToken::Comma; 108251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 108351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 1084a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::eof: 1085a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::EndOfFile; 1086a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1087a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1088a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::l_brace: 1089a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::LBrace; 1090a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1091a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1092a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case tok::l_square: 1093a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Tok.Kind = MMToken::LSquare; 1094a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1095a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 109690db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::period: 109790db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Period; 109890db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 109990db26000aefe9335370013eec64c85232d80227Douglas Gregor 1100a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::r_brace: 1101a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::RBrace; 1102a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1103a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1104a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case tok::r_square: 1105a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Tok.Kind = MMToken::RSquare; 1106a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1107a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 110890db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::star: 110990db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Star; 111090db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 111190db26000aefe9335370013eec64c85232d80227Douglas Gregor 11125794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith case tok::exclaim: 11135794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith Tok.Kind = MMToken::Exclaim; 11145794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith break; 11155794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith 1116a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::string_literal: { 111799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (LToken.hasUDSuffix()) { 111899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 111999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith HadError = true; 112099831e4677a7e2e051af636221694d60ba31fcdbRichard Smith goto retry; 112199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 112299831e4677a7e2e051af636221694d60ba31fcdbRichard Smith 1123a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the string literal. 1124a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LangOptions LangOpts; 1125ef8225444452a1486bd721f3285301fe84643b00Stephen Hines StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1126a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (StringLiteral.hadError) 1127a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 1128a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1129a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Copy the string literal into our string data allocator. 1130a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Length = StringLiteral.GetStringLength(); 1131a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor char *Saved = StringData.Allocate<char>(Length + 1); 1132a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor memcpy(Saved, StringLiteral.GetString().data(), Length); 1133a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Saved[Length] = 0; 1134a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1135a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Form the token. 1136a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::StringLiteral; 1137a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringData = Saved; 1138a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringLength = Length; 1139a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1140a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1141a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1142a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::comment: 1143a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 1144a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1145a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1146a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1147a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1148a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 1149a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1150a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1151a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 1152a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1153a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1154a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1155a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned braceDepth = 0; 1156a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor unsigned squareDepth = 0; 1157a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1158a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1159a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1160a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1161a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1162a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 1163a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1164a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1165a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1166a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ++braceDepth; 1167a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1168a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1169a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::LSquare: 1170a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1171a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor return; 1172a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1173a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor ++squareDepth; 1174a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1175a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1176a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 1177a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (braceDepth > 0) 1178a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor --braceDepth; 1179a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else if (Tok.is(K)) 1180a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1181a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1182a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1183a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::RSquare: 1184a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (squareDepth > 0) 1185a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor --squareDepth; 1186a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor else if (Tok.is(K)) 1187a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor return; 1188a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 1189a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1190a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1191a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1192a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1193a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1194a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1195a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1196a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1197a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 1198a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1199a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1200587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \brief Parse a module-id. 1201587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 1202587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// module-id: 1203587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier 1204587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier '.' module-id 1205587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 1206587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \returns true if an error occurred, false otherwise. 1207587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregorbool ModuleMapParser::parseModuleId(ModuleId &Id) { 1208587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.clear(); 1209587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor do { 1210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1211587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1212587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 1213587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1214587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1215587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return true; 1216587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1217587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1218587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!Tok.is(MMToken::Period)) 1219587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor break; 1220587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1221587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 1222587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } while (true); 1223587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1224587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return false; 1225587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor} 1226587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1227a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregornamespace { 1228a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief Enumerates the known attributes. 1229a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor enum AttributeKind { 1230a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief An unknown attribute. 1231a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor AT_unknown, 1232a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief The 'system' attribute. 123363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor AT_system, 1234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief The 'extern_c' attribute. 1235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AT_extern_c, 123663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor /// \brief The 'exhaustive' attribute. 123763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor AT_exhaustive 1238a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor }; 1239a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor} 1240a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1241a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module declaration. 1242a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1243a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration: 12445f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 'extern' 'module' module-id string-literal 1245a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1246a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// { module-member* } 1247a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// 1248a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-member: 124951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// requires-declaration 1250a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// header-declaration 1251587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// submodule-declaration 125290db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration 1253b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// link-declaration 12541e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// 12551e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// submodule-declaration: 12561e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// module-declaration 12571e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// inferred-submodule-declaration 1258a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::parseModuleDecl() { 1259a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 12605f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 12615f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (Tok.is(MMToken::ExternKeyword)) { 12625f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper parseExternModuleDecl(); 12635f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 12645f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 12655f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 1266d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'explicit' or 'framework' keyword, if present. 1267587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ExplicitLoc; 1268a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Explicit = false; 1269d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor bool Framework = false; 1270a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 1271a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor // Parse 'explicit' keyword, if present. 1272d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::ExplicitKeyword)) { 1273587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = consumeToken(); 1274a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Explicit = true; 1275a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1276d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1277d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'framework' keyword, if present. 1278d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 1279d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor consumeToken(); 1280d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Framework = true; 1281d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 1282a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1283a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse 'module' keyword. 1284a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::ModuleKeyword)) { 1285e6fb9876970e2dc55f091522644efa16caa9ba06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1286a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1287a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1288a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1289a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1290a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); // 'module' keyword 12911e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 12921e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If we have a wildcard for the module name, this is an inferred submodule. 12931e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse it. 12941e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 129582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return parseInferredModuleDecl(Framework, Explicit); 1296a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1297a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the module name. 1298587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleId Id; 1299587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (parseModuleId(Id)) { 1300587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1301587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1302587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 130382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 1304587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 1305587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 1306587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1307587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor << SourceRange(Id.front().second, Id.back().second); 1308587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1309587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1310587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1311587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1312587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else if (Id.size() == 1 && Explicit) { 1313587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Top-level modules can't be explicit. 1314587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1315587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Explicit = false; 1316587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = SourceLocation(); 1317a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1318a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1319587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1320587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Module *PreviousActiveModule = ActiveModule; 1321587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 1322587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // This module map defines a submodule. Go find the module of which it 1323587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // is a submodule. 13246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule = nullptr; 1325587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1326587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1327587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = Next; 1328587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor continue; 1329587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1330587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1331587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 1332587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << Id[I].first 1334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << ActiveModule->getTopLevelModule()->getFullModuleName(); 1335587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1336587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1337587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1338587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1339587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1340587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1341587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1342587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1343587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor StringRef ModuleName = Id.back().first; 1344587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ModuleNameLoc = Id.back().second; 1345a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1346a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor // Parse the optional attribute list. 1347ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling Attributes Attrs; 134882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor parseOptionalAttributes(Attrs); 1349a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1350a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the opening brace. 1351a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 1352a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1353a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 1354a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1355a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1356a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1357a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 1358a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1359a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this (sub)module has already been defined. 1360b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1361c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1362c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor // Skip the module definition. 1363c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor skipUntil(MMToken::RBrace); 1364c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor if (Tok.is(MMToken::RBrace)) 1365c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor consumeToken(); 1366c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor else { 1367c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1368c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1369c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor HadError = true; 1370c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor } 1371c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor return; 1372c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor } 1373c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor 1374a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1375a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 1376b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1377a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1378a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Skip the module definition. 1379a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor skipUntil(MMToken::RBrace); 1380a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 1381a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1382a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1383a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1384a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1385a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1386a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 13876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If this is a submodule, use the parent's module map, since we don't want 13886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // the private module map file. 13896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap 13906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : ModuleMapFile; 13916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1392a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Start defining this module. 13936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap, 13946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Framework, Explicit).first; 1395b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor ActiveModule->DefinitionLoc = ModuleNameLoc; 13968f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (Attrs.IsSystem || IsSystem) 1397a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor ActiveModule->IsSystem = true; 1398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Attrs.IsExternC) 1399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ActiveModule->IsExternC = true; 1400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1401a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Done = false; 1402a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1403a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1404a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1405a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 1406a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Done = true; 1407a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 140863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 140963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case MMToken::ConfigMacros: 141063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor parseConfigMacros(); 141163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 141263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 1413906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor case MMToken::Conflict: 1414906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor parseConflict(); 1415906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor break; 1416906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1417a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ExplicitKeyword: 14185f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper case MMToken::ExternKeyword: 1419d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor case MMToken::FrameworkKeyword: 1420a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 1421a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 1422a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 14235f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 142490db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 142590db26000aefe9335370013eec64c85232d80227Douglas Gregor parseExportDecl(); 142690db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 1427ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 1428ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper case MMToken::UseKeyword: 1429ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper parseUseDecl(); 1430ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper break; 143190db26000aefe9335370013eec64c85232d80227Douglas Gregor 143251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::RequiresKeyword: 143351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor parseRequiresDecl(); 143451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 143551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 143677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor case MMToken::UmbrellaKeyword: { 143777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor SourceLocation UmbrellaLoc = consumeToken(); 143877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (Tok.is(MMToken::HeaderKeyword)) 1439bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 144077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor else 144177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor parseUmbrellaDirDecl(UmbrellaLoc); 1442a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 144377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 1444a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 14452b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor case MMToken::ExcludeKeyword: { 14462b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor SourceLocation ExcludeLoc = consumeToken(); 14472b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (Tok.is(MMToken::HeaderKeyword)) { 1448bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc); 14492b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor } else { 14502b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 14512b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << "exclude"; 14522b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor } 14532b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor break; 14542b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor } 14552b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor 1456bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: { 1457bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation PrivateLoc = consumeToken(); 1458bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Tok.is(MMToken::HeaderKeyword)) { 1459bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc); 1460bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } else { 1461bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1462bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl << "private"; 1463bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } 1464bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl break; 1465bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } 1466bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl 1467489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor case MMToken::HeaderKeyword: 1468bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation()); 1469a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1470b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1471b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor case MMToken::LinkKeyword: 1472b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor parseLinkDecl(); 1473b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor break; 1474b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1475a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1476a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1477a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1478a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1479a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1480a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (!Done); 1481a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1482a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 1483a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1484a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else { 1485a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1486a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1487a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1488a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1489a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 14908767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // If the active module is a top-level framework, and there are no link 14918767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // libraries, automatically link against the framework. 14928767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 14938767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor ActiveModule->LinkLibraries.empty()) { 14948767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 14958767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 14968767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 14976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If the module meets all requirements but is still unavailable, mark the 14986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // whole tree as unavailable to prevent it from building. 14996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 15006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->Parent) { 15016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->getTopLevelModule()->markUnavailable(); 15026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->getTopLevelModule()->MissingHeaders.append( 15036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 15046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 15056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1506587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // We're done parsing this module. Pop back to the previous module. 1507587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = PreviousActiveModule; 1508a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1509d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 15105f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// \brief Parse an extern module declaration. 15115f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 15125f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// extern module-declaration: 15135f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 'extern' 'module' module-id string-literal 15145f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jaspervoid ModuleMapParser::parseExternModuleDecl() { 15155f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper assert(Tok.is(MMToken::ExternKeyword)); 15165f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // 'extern' keyword 15175f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15185f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse 'module' keyword. 15195f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (!Tok.is(MMToken::ModuleKeyword)) { 15205f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 15215f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); 15225f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 15235f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 15245f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15255f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // 'module' keyword 15265f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15275f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse the module name. 15285f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ModuleId Id; 15295f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (parseModuleId(Id)) { 15305f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 15315f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 15325f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15335f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15345f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse the referenced module map file name. 15355f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (!Tok.is(MMToken::StringLiteral)) { 15365f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 15375f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 15385f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 15395f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15405f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper std::string FileName = Tok.getString(); 15415f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // filename 15425f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 15435f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper StringRef FileNameRef = FileName; 15445f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper SmallString<128> ModuleMapFileName; 15455f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (llvm::sys::path::is_relative(FileNameRef)) { 15465f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ModuleMapFileName += Directory->getName(); 15475f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper llvm::sys::path::append(ModuleMapFileName, FileName); 15485f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper FileNameRef = ModuleMapFileName.str(); 15495f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 15505f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 15515f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Map.parseModuleMapFile(File, /*IsSystem=*/false); 15525f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper} 15535f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 155451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// \brief Parse a requires declaration. 155551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 155651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// requires-declaration: 155751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 'requires' feature-list 155851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 155951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// feature-list: 15605794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// feature ',' feature-list 15615794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// feature 15625794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// 15635794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// feature: 15645794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith/// '!'[opt] identifier 156551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregorvoid ModuleMapParser::parseRequiresDecl() { 156651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor assert(Tok.is(MMToken::RequiresKeyword)); 156751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 156851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Parse 'requires' keyword. 156951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 157051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 157151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Parse the feature-list. 157251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor do { 15735794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith bool RequiredState = true; 15745794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith if (Tok.is(MMToken::Exclaim)) { 15755794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith RequiredState = false; 15765794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith consumeToken(); 15775794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith } 15785794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith 157951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Tok.is(MMToken::Identifier)) { 158051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 158151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor HadError = true; 158251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return; 158351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 158451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 158551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Consume the feature name. 158651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor std::string Feature = Tok.getString(); 158751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 158851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 158951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Add this feature. 15905794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith ActiveModule->addRequirement(Feature, RequiredState, 15915794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith Map.LangOpts, *Map.Target); 159251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 159351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Tok.is(MMToken::Comma)) 159451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 159551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 159651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Consume the comma. 159751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 159851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } while (true); 159951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor} 160051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 1601d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// \brief Append to \p Paths the set of paths needed to get to the 1602d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// subframework in which the given module lives. 16035bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramerstatic void appendSubframeworkPaths(Module *Mod, 1604cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVectorImpl<char> &Path) { 1605d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Collect the framework names from the given module to the top-level module. 1606cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<StringRef, 2> Paths; 1607d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor for (; Mod; Mod = Mod->Parent) { 1608d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Mod->IsFramework) 1609d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Paths.push_back(Mod->Name); 1610d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 1611d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1612d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Paths.empty()) 1613d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor return; 1614d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1615d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Add Frameworks/Name.framework for each subframework. 1616ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer for (unsigned I = Paths.size() - 1; I != 0; --I) 1617ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1618d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor} 1619d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1620489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// \brief Parse a header declaration. 1621a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1622489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// header-declaration: 1623489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// 'umbrella'[opt] 'header' string-literal 16242b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor/// 'exclude'[opt] 'header' string-literal 1625bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowlvoid ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1626bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation LeadingLoc) { 1627489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor assert(Tok.is(MMToken::HeaderKeyword)); 1628489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor consumeToken(); 1629489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor 1630a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the header name. 1631a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1632a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1633489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor << "header"; 1634a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1635a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1636a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Module::HeaderDirective Header; 1638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Header.FileName = Tok.getString(); 1639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Header.FileNameLoc = consumeToken(); 1640489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor 164177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Check whether we already have an umbrella. 1642bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 164477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << ActiveModule->getFullModuleName(); 16458b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 16468b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor return; 16478b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1648a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 16498b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Look for this file. 16506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *File = nullptr; 16516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *BuiltinFile = nullptr; 1652f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PathName; 1653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (llvm::sys::path::is_absolute(Header.FileName)) { 1654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathName = Header.FileName; 1655587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 1656587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1657587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Search for the header file within the search directory. 16586a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor PathName = Directory->getName(); 1659587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor unsigned PathLength = PathName.size(); 166018ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor 1661d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (ActiveModule->isPartOfFramework()) { 1662d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor appendSubframeworkPaths(ActiveModule, PathName); 1663587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1664587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the public headers. 1665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(PathName, "Headers", Header.FileName); 1666587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 1667587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1668587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!File) { 1669587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the private headers. 1670587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor PathName.resize(PathLength); 1671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName); 1672587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 1673587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1674587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1675587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Lookup for normal headers. 1676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(PathName, Header.FileName); 1677587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 16782f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 16792f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If this is a system module with a top-level header, this header 16802f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // may have a counterpart (or replacement) in the set of headers 16812f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // supplied by Clang. Find that builtin header. 1682bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1683bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isBuiltinHeader(Header.FileName)) { 1685f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(BuiltinPathName, Header.FileName); 16872f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 16882f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 16892f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If Clang supplies this header but the underlying system does not, 16902f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // just silently swap in our builtin version. Otherwise, we'll end 16912f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // up adding both (later). 16922f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor if (!File && BuiltinFile) { 16932f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor File = BuiltinFile; 16946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuiltinFile = nullptr; 16952f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor } 16962f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor } 1697d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 169818ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } 1699a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 17008b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 17018b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Come up with a lazy way to do this. 1702587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (File) { 1703c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (LeadingToken == MMToken::UmbrellaKeyword) { 1704489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor const DirectoryEntry *UmbrellaDir = File->getDir(); 17052b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1706bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 17072b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << UmbrellaModule->getFullModuleName(); 1708489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor HadError = true; 1709489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor } else { 1710489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // Record this umbrella header. 1711489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor Map.setUmbrellaHeader(ActiveModule, File); 1712489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor } 17138b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 1714489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // Record this header. 1715bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1716bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (LeadingToken == MMToken::ExcludeKeyword) 1717bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Role = ModuleMap::ExcludedHeader; 1718bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl else if (LeadingToken == MMToken::PrivateKeyword) 1719bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Role = ModuleMap::PrivateHeader; 1720bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl else 1721bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl assert(LeadingToken == MMToken::HeaderKeyword); 1722bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl 1723bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Map.addHeader(ActiveModule, File, Role); 17242f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 17252f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If there is a builtin counterpart to this file, add it now. 17262f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor if (BuiltinFile) 1727bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Map.addHeader(ActiveModule, BuiltinFile, Role); 17288b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1729bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } else if (LeadingToken != MMToken::ExcludeKeyword) { 173071f49f5d8fc3c4980bed4bb7790c8d0e50586d3bDouglas Gregor // Ignore excluded header files. They're optional anyway. 1731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If we find a module that has a missing header, we mark this module as 1733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // unavailable and store the header directive for displaying diagnostics. 1734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 17356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ActiveModule->markUnavailable(); 1736651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ActiveModule->MissingHeaders.push_back(Header); 173777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 173877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor} 173977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 174077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// \brief Parse an umbrella directory declaration. 174177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// 174277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// umbrella-dir-declaration: 174377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// umbrella string-literal 174477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregorvoid ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 174577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Parse the directory name. 174677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 174777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 174877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << "umbrella"; 174977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 175077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 175177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 175277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 175377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor std::string DirName = Tok.getString(); 175477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor SourceLocation DirNameLoc = consumeToken(); 175577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 175677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Check whether we already have an umbrella. 175777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (ActiveModule->Umbrella) { 175877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 175977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << ActiveModule->getFullModuleName(); 17608b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 176177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 176277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 176377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 176477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Look for this file. 17656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DirectoryEntry *Dir = nullptr; 176677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (llvm::sys::path::is_absolute(DirName)) 176777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Dir = SourceMgr.getFileManager().getDirectory(DirName); 176877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor else { 1769f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PathName; 177077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor PathName = Directory->getName(); 177177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor llvm::sys::path::append(PathName, DirName); 177277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Dir = SourceMgr.getFileManager().getDirectory(PathName); 17738b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 177477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 177577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (!Dir) { 177677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 177777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << DirName; 177877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 177977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 178077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 178177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 178277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 178377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 178477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << OwningModule->getFullModuleName(); 178577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 178677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 178777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 178877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 178977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Record this umbrella directory. 179077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Map.setUmbrellaDir(ActiveModule, Dir); 1791a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1792a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 179390db26000aefe9335370013eec64c85232d80227Douglas Gregor/// \brief Parse a module export declaration. 179490db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 179590db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration: 179690db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 'export' wildcard-module-id 179790db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 179890db26000aefe9335370013eec64c85232d80227Douglas Gregor/// wildcard-module-id: 179990db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier 180090db26000aefe9335370013eec64c85232d80227Douglas Gregor/// '*' 180190db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier '.' wildcard-module-id 180290db26000aefe9335370013eec64c85232d80227Douglas Gregorvoid ModuleMapParser::parseExportDecl() { 180390db26000aefe9335370013eec64c85232d80227Douglas Gregor assert(Tok.is(MMToken::ExportKeyword)); 180490db26000aefe9335370013eec64c85232d80227Douglas Gregor SourceLocation ExportLoc = consumeToken(); 180590db26000aefe9335370013eec64c85232d80227Douglas Gregor 180690db26000aefe9335370013eec64c85232d80227Douglas Gregor // Parse the module-id with an optional wildcard at the end. 180790db26000aefe9335370013eec64c85232d80227Douglas Gregor ModuleId ParsedModuleId; 180890db26000aefe9335370013eec64c85232d80227Douglas Gregor bool Wildcard = false; 180990db26000aefe9335370013eec64c85232d80227Douglas Gregor do { 181090db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Identifier)) { 181190db26000aefe9335370013eec64c85232d80227Douglas Gregor ParsedModuleId.push_back(std::make_pair(Tok.getString(), 181290db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.getLocation())); 181390db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 181490db26000aefe9335370013eec64c85232d80227Douglas Gregor 181590db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Period)) { 181690db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 181790db26000aefe9335370013eec64c85232d80227Douglas Gregor continue; 181890db26000aefe9335370013eec64c85232d80227Douglas Gregor } 181990db26000aefe9335370013eec64c85232d80227Douglas Gregor 182090db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 182190db26000aefe9335370013eec64c85232d80227Douglas Gregor } 182290db26000aefe9335370013eec64c85232d80227Douglas Gregor 182390db26000aefe9335370013eec64c85232d80227Douglas Gregor if(Tok.is(MMToken::Star)) { 182490db26000aefe9335370013eec64c85232d80227Douglas Gregor Wildcard = true; 18250adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor consumeToken(); 182690db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 182790db26000aefe9335370013eec64c85232d80227Douglas Gregor } 182890db26000aefe9335370013eec64c85232d80227Douglas Gregor 1829ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 183090db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 183190db26000aefe9335370013eec64c85232d80227Douglas Gregor return; 183290db26000aefe9335370013eec64c85232d80227Douglas Gregor } while (true); 183390db26000aefe9335370013eec64c85232d80227Douglas Gregor 183490db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::UnresolvedExportDecl Unresolved = { 183590db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportLoc, ParsedModuleId, Wildcard 183690db26000aefe9335370013eec64c85232d80227Douglas Gregor }; 183790db26000aefe9335370013eec64c85232d80227Douglas Gregor ActiveModule->UnresolvedExports.push_back(Unresolved); 183890db26000aefe9335370013eec64c85232d80227Douglas Gregor} 183990db26000aefe9335370013eec64c85232d80227Douglas Gregor 1840ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper/// \brief Parse a module uses declaration. 1841ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper/// 1842ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper/// uses-declaration: 1843ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper/// 'uses' wildcard-module-id 1844ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jaspervoid ModuleMapParser::parseUseDecl() { 1845ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper assert(Tok.is(MMToken::UseKeyword)); 1846ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper consumeToken(); 1847ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper // Parse the module-id. 1848ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper ModuleId ParsedModuleId; 1849651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines parseModuleId(ParsedModuleId); 1850ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 1851ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1852ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper} 1853ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper 1854b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// \brief Parse a link declaration. 1855b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// 1856b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// module-declaration: 1857b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// 'link' 'framework'[opt] string-literal 1858b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregorvoid ModuleMapParser::parseLinkDecl() { 1859b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor assert(Tok.is(MMToken::LinkKeyword)); 1860b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor SourceLocation LinkLoc = consumeToken(); 1861b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1862b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor // Parse the optional 'framework' keyword. 1863b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor bool IsFramework = false; 1864b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 1865b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor consumeToken(); 1866b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor IsFramework = true; 1867b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor } 1868b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1869b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor // Parse the library name 1870b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1871b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1872b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor << IsFramework << SourceRange(LinkLoc); 1873b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor HadError = true; 1874b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor return; 1875b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor } 1876b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1877b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor std::string LibraryName = Tok.getString(); 1878b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor consumeToken(); 1879b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1880b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor IsFramework)); 1881b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor} 1882b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 188363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// \brief Parse a configuration macro declaration. 188463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 188563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// module-declaration: 188663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 'config_macros' attributes[opt] config-macro-list? 188763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 188863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// config-macro-list: 188963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// identifier (',' identifier)? 189063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregorvoid ModuleMapParser::parseConfigMacros() { 189163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor assert(Tok.is(MMToken::ConfigMacros)); 189263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor SourceLocation ConfigMacrosLoc = consumeToken(); 189363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 189463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Only top-level modules can have configuration macros. 189563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (ActiveModule->Parent) { 189663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 189763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 189863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 189963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Parse the optional attributes. 190063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attributes Attrs; 190163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor parseOptionalAttributes(Attrs); 190263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (Attrs.IsExhaustive && !ActiveModule->Parent) { 190363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacrosExhaustive = true; 190463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 190563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 190663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // If we don't have an identifier, we're done. 190763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Identifier)) 190863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor return; 190963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 191063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Consume the first identifier. 191163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!ActiveModule->Parent) { 191263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 191363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 191463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 191563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 191663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor do { 191763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // If there's a comma, consume it. 191863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Comma)) 191963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 192063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 192163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 192263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // We expect to see a macro name here. 192363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Identifier)) { 192463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 192563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 192663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 192763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 192863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Consume the macro name. 192963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!ActiveModule->Parent) { 193063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 193163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 193263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 193363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } while (true); 193463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor} 193563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 1936906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// \brief Format a module-id into a string. 1937906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorstatic std::string formatModuleId(const ModuleId &Id) { 1938906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor std::string result; 1939906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor { 1940906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor llvm::raw_string_ostream OS(result); 1941906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1942906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 1943906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (I) 1944906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor OS << "."; 1945906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor OS << Id[I].first; 1946906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1947906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1948906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1949906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return result; 1950906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 1951906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1952906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// \brief Parse a conflict declaration. 1953906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// 1954906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// module-declaration: 1955906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// 'conflict' module-id ',' string-literal 1956906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorvoid ModuleMapParser::parseConflict() { 1957906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor assert(Tok.is(MMToken::Conflict)); 1958906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor SourceLocation ConflictLoc = consumeToken(); 1959906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module::UnresolvedConflict Conflict; 1960906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1961906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the module-id. 1962906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (parseModuleId(Conflict.Id)) 1963906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 1964906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1965906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the ','. 1966906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Tok.is(MMToken::Comma)) { 1967906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 1968906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << SourceRange(ConflictLoc); 1969906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 1970906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1971906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor consumeToken(); 1972906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1973906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the message. 1974906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1975906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 1976906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << formatModuleId(Conflict.Id); 1977906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 1978906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1979906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Message = Tok.getString().str(); 1980906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor consumeToken(); 1981906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1982906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Add this unresolved conflict. 1983906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor ActiveModule->UnresolvedConflicts.push_back(Conflict); 1984906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 1985906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1986b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// \brief Parse an inferred module declaration (wildcard modules). 198782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 198882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// module-declaration: 198982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 199082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// { inferred-module-member* } 199182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 199282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// inferred-module-member: 199382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'export' '*' 199482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'exclude' identifier 199582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregorvoid ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 19961e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor assert(Tok.is(MMToken::Star)); 19971e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation StarLoc = consumeToken(); 19981e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Failed = false; 199982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 20001e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Inferred modules must be submodules. 200182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!ActiveModule && !Framework) { 20021e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 20031e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Failed = true; 20041e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 200582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 200682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 200782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Inferred modules must have umbrella directories. 20086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Failed && ActiveModule->IsAvailable && 20096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !ActiveModule->getUmbrellaDir()) { 201082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 201182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Failed = true; 201282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 201382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 201482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check for redefinition of an inferred module. 201582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Failed && ActiveModule->InferSubmodules) { 201682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 201782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule->InferredSubmoduleLoc.isValid()) 201882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(ActiveModule->InferredSubmoduleLoc, 201982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor diag::note_mmap_prev_definition); 202082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Failed = true; 202182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 202282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 202382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check for the 'framework' keyword, which is not permitted here. 202482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Framework) { 202582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 202682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Framework = false; 202782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 202882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } else if (Explicit) { 202982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 203082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Explicit = false; 20311e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 203282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 20331e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If there were any problems with this inferred submodule, skip its body. 20341e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Failed) { 20351e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::LBrace)) { 20361e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 20371e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor skipUntil(MMToken::RBrace); 20381e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 20391e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 20401e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 20411e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 20421e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 20431e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 204482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 204582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Parse optional attributes. 2046ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling Attributes Attrs; 204782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor parseOptionalAttributes(Attrs); 204882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 204982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 205082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Note that we have an inferred submodule. 205182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferSubmodules = true; 205282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferredSubmoduleLoc = StarLoc; 205382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferExplicitSubmodules = Explicit; 205482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } else { 205582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We'll be inferring framework modules for this directory. 205682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].InferModules = true; 205782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 20586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2059651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: Handle the 'framework' keyword. 206082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 206182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 20621e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the opening brace. 20631e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 20641e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 20651e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 20661e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 20671e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 20681e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 20691e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 20701e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the body of the inferred submodule. 20711e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Done = false; 20721e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor do { 20731e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor switch (Tok.Kind) { 20741e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::EndOfFile: 20751e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::RBrace: 20761e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Done = true; 20771e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 207882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 207982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case MMToken::ExcludeKeyword: { 208082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 208182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 20826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << (ActiveModule != nullptr); 208382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 208482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 208582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 208682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 208782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 208882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::Identifier)) { 208982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 209082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 209182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 209282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 209382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].ExcludedModules 209482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .push_back(Tok.getString()); 209582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 209682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 209782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 209882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 209982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case MMToken::ExportKeyword: 210082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!ActiveModule) { 210182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 21026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << (ActiveModule != nullptr); 210382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 210482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 210582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 210682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 21071e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21081e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 2109ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferExportWildcard = true; 21101e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else 21111e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), 21121e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor diag::err_mmap_expected_export_wildcard); 21131e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21141e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 211582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 21161e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ExplicitKeyword: 21171e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ModuleKeyword: 21181e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::HeaderKeyword: 2119bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: 21201e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::UmbrellaKeyword: 21211e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor default: 212282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 21236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << (ActiveModule != nullptr); 21241e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21251e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 21261e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 21271e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } while (!Done); 21281e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 21291e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 21301e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 21311e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else { 21321e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 21331e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 21341e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 21351e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 21361e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor} 21371e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 213882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \brief Parse optional attributes. 213982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 214082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attributes: 214182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute attributes 214282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute 214382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 214482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute: 214582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// [ identifier ] 214682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 214782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \param Attrs Will be filled in with the parsed attributes. 214882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 214982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \returns true if an error occurred, false otherwise. 2150ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendlingbool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 215182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool HadError = false; 215282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 215382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor while (Tok.is(MMToken::LSquare)) { 215482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Consume the '['. 215582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor SourceLocation LSquareLoc = consumeToken(); 215682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 215782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have an attribute name here. 215882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::Identifier)) { 215982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 216082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor skipUntil(MMToken::RSquare); 216182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Tok.is(MMToken::RSquare)) 216282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 216382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor HadError = true; 216482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 216582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 216682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Decode the attribute name. 216782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor AttributeKind Attribute 216882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor = llvm::StringSwitch<AttributeKind>(Tok.getString()) 216963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("exhaustive", AT_exhaustive) 2170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines .Case("extern_c", AT_extern_c) 217182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .Case("system", AT_system) 217282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .Default(AT_unknown); 217382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor switch (Attribute) { 217482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case AT_unknown: 217582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 217682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor << Tok.getString(); 217782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 217882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 217982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case AT_system: 218082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Attrs.IsSystem = true; 218182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 218263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 2183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case AT_extern_c: 2184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Attrs.IsExternC = true; 2185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 2186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 218763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case AT_exhaustive: 218863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attrs.IsExhaustive = true; 218963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 219082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 219182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 219282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 219382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Consume the ']'. 219482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::RSquare)) { 219582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 219682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 219782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor skipUntil(MMToken::RSquare); 219882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor HadError = true; 219982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 220082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 220182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Tok.is(MMToken::RSquare)) 220282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 220382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 220482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 220582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return HadError; 220682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor} 220782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 2208a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module map file. 2209a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 2210a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-map-file: 2211a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration* 2212a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool ModuleMapParser::parseModuleMapFile() { 2213a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 2214a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 2215a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 2216a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return HadError; 2217a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2218587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor case MMToken::ExplicitKeyword: 22195f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper case MMToken::ExternKeyword: 2220a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 2221a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor case MMToken::FrameworkKeyword: 2222a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 2223a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 2224b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 222551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::Comma: 222663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case MMToken::ConfigMacros: 2227906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor case MMToken::Conflict: 22285794b53ad5b38b53c9eaf3a172354e63081ceb2fRichard Smith case MMToken::Exclaim: 22292b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor case MMToken::ExcludeKeyword: 223090db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 2231a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::HeaderKeyword: 2232a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::Identifier: 2233a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 2234b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor case MMToken::LinkKeyword: 2235a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::LSquare: 223690db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Period: 2237bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: 2238a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 2239a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::RSquare: 224051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::RequiresKeyword: 224190db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Star: 2242a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::StringLiteral: 2243a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::UmbrellaKeyword: 2244ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper case MMToken::UseKeyword: 2245a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2246a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 2247a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 2248a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 2249a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 2250a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 2251a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 2252a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 22538f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregorbool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { 22547005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor llvm::DenseMap<const FileEntry *, bool>::iterator Known 22557005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor = ParsedModuleMap.find(File); 22567005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (Known != ParsedModuleMap.end()) 22577005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return Known->second; 22587005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 22596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Target && "Missing target information"); 2260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter); 2262ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2263a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Buffer) 22647005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return ParsedModuleMap[File] = true; 2265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Find the directory for the module. For frameworks, that may require going 2267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // up from the 'Modules' directory. 2268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DirectoryEntry *Dir = File->getDir(); 2269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef DirName(Dir->getName()); 2270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (llvm::sys::path::filename(DirName) == "Modules") { 2271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DirName = llvm::sys::path::parent_path(DirName); 2272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (DirName.endswith(".framework")) 2273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Dir = SourceMgr.getFileManager().getDirectory(DirName); 2274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(Dir && "parent must exist"); 2275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2276a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2277a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse this module map file. 2278ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 22796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 22808f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor BuiltinIncludeDir, IsSystem); 2281a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Result = Parser.parseModuleMapFile(); 22827005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor ParsedModuleMap[File] = Result; 2283a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 2284a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 2285