ModuleMap.cpp revision 5f0a3524d184f7fcda856aaa17686064e45cacd3
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"); 450adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor return Module::ExportDecl(0, 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) 62906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 63906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << Id[0].first << Mod->getFullModuleName(); 64906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 65906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return 0; 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) 73906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 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 77906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return 0; 7890db26000aefe9335370013eec64c85232d80227Douglas Gregor } 79906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 8090db26000aefe9335370013eec64c85232d80227Douglas Gregor Context = Sub; 8190db26000aefe9335370013eec64c85232d80227Douglas Gregor } 82906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 83906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return Context; 8490db26000aefe9335370013eec64c85232d80227Douglas Gregor} 8590db26000aefe9335370013eec64c85232d80227Douglas Gregor 86a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas GregorModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC, 8755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis const LangOptions &LangOpts, const TargetInfo *Target, 8855ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HeaderSearch &HeaderInfo) 8955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo), 90d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis BuiltinIncludeDir(0), CompilingModule(0) 9151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor{ 92c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 93c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( 9402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor new DiagnosticsEngine(DiagIDs, new DiagnosticOptions)); 95a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor Diags->setClient(new ForwardingDiagnosticConsumer(DC), 96a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor /*ShouldOwnClient=*/true); 97a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceMgr = new SourceManager(*Diags, FileMgr); 98a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 99a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 100a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorModuleMap::~ModuleMap() { 10109fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 10209fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor IEnd = Modules.end(); 10309fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor I != IEnd; ++I) { 10409fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor delete I->getValue(); 10509fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor } 10609fe1bb696847e6f1b482e5ac40029d53a2402dfDouglas Gregor 107a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor delete SourceMgr; 108a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 109a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 110dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregorvoid ModuleMap::setTarget(const TargetInfo &Target) { 111dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor assert((!this->Target || this->Target == &Target) && 112dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor "Improper target override"); 113dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor this->Target = &Target; 114dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor} 115dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor 1168b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor/// \brief "Sanitize" a filename so that it can be used as an identifier. 1178b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregorstatic StringRef sanitizeFilenameAsIdentifier(StringRef Name, 1188b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallVectorImpl<char> &Buffer) { 1198b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor if (Name.empty()) 1208b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor return Name; 1218b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1223f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (!isValidIdentifier(Name)) { 1238b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor // If we don't already have something with the form of an identifier, 1248b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor // create a buffer with the sanitized name. 1258b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.clear(); 1263f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isDigit(Name[0])) 1278b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1288b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.reserve(Buffer.size() + Name.size()); 1298b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor for (unsigned I = 0, N = Name.size(); I != N; ++I) { 1303f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isIdentifierBody(Name[I])) 1318b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back(Name[I]); 1328b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor else 1338b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1348b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1358b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1368b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Name = StringRef(Buffer.data(), Buffer.size()); 1378b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1388b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1398b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor while (llvm::StringSwitch<bool>(Name) 1408b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 1418b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 1428b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor#include "clang/Basic/TokenKinds.def" 1438b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor .Default(false)) { 1448b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor if (Name.data() != Buffer.data()) 1458b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.append(Name.begin(), Name.end()); 1468b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Buffer.push_back('_'); 1478b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor Name = StringRef(Buffer.data(), Buffer.size()); 1488b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor } 1498b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 1508b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor return Name; 1518b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor} 1528b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor 153db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// \brief Determine whether the given file name is the name of a builtin 154db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// header, supplied by Clang to replace, override, or augment existing system 155db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor/// headers. 156db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregorstatic bool isBuiltinHeader(StringRef FileName) { 157db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor return llvm::StringSwitch<bool>(FileName) 158db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("float.h", true) 159db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("iso646.h", true) 160db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("limits.h", true) 161db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdalign.h", true) 162db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdarg.h", true) 163db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdbool.h", true) 164db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stddef.h", true) 165db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("stdint.h", true) 166db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("tgmath.h", true) 167db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Case("unwind.h", true) 168db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor .Default(false); 169db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor} 170db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 171bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence CrowlModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) { 1722b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor HeadersMap::iterator Known = Headers.find(File); 17351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (Known != Headers.end()) { 1742b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor // If a header is not available, don't report that it maps to anything. 1752b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (!Known->second.isAvailable()) 176bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return KnownHeader(); 17751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 178bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return Known->second; 17951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 180db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 181db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor // If we've found a builtin header within Clang's builtin include directory, 182db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor // load all of the module maps to see if it will get associated with a 183db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor // specific module (e.g., in /usr/include). 184db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor if (File->getDir() == BuiltinIncludeDir && 185db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 18630a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor HeaderInfo.loadTopLevelSystemModules(); 187db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 188db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor // Check again. 189db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor Known = Headers.find(File); 190db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor if (Known != Headers.end()) { 191db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor // If a header is not available, don't report that it maps to anything. 192db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor if (!Known->second.isAvailable()) 193bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return KnownHeader(); 194db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor 195bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return Known->second; 196db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor } 197db3910be2e30b3fa00474f0e1c0780f544469deeDouglas Gregor } 19865f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 199adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor const DirectoryEntry *Dir = File->getDir(); 200cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> SkippedDirs; 201713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 202aa60f9cee8fa29cac1848de75ad48cdc0520e993Douglas Gregor // Note: as an egregious but useful hack we use the real path here, because 203aa60f9cee8fa29cac1848de75ad48cdc0520e993Douglas Gregor // frameworks moving from top-level frameworks to embedded frameworks tend 204aa60f9cee8fa29cac1848de75ad48cdc0520e993Douglas Gregor // to be symlinked from the top-level location to the embedded location, 205aa60f9cee8fa29cac1848de75ad48cdc0520e993Douglas Gregor // and we need to resolve lookups as if we had found the embedded location. 206713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir); 207e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 208e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Keep walking up the directory hierarchy, looking for a directory with 209e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // an umbrella header. 210e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor do { 211e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 212e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor = UmbrellaDirs.find(Dir); 213adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor if (KnownDir != UmbrellaDirs.end()) { 214adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor Module *Result = KnownDir->second; 2159f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor 2169f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor // Search up the module stack until we find a module with an umbrella 21710694cee2588442bee1e717f5042c58ffee25279Douglas Gregor // directory. 2189f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor Module *UmbrellaModule = Result; 21910694cee2588442bee1e717f5042c58ffee25279Douglas Gregor while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 2209f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor UmbrellaModule = UmbrellaModule->Parent; 22151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 2229f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferSubmodules) { 223e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Infer submodules for each of the directories we found between 224e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // the directory of the umbrella header and the directory where 225e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // the actual header is located. 22623af6d58e392e18ae2946b799264717f480e6596Douglas Gregor bool Explicit = UmbrellaModule->InferExplicitSubmodules; 227e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 2286a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor for (unsigned I = SkippedDirs.size(); I != 0; --I) { 229e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Find or create the module that corresponds to this directory name. 2308b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 2318b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 2328b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 2338b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 234e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 23523af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Explicit).first; 236e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 237e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Associate the module and the directory. 238e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDirs[SkippedDirs[I-1]] = Result; 239e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 240e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // If inferred submodules export everything they import, add a 241e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // wildcard to the set of exports. 2429f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 243e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 244e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 245e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 246e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Infer a submodule with the same name as this header file. 2478b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 2488b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 2498b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(File->getName()), NameBuf); 250e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 25123af6d58e392e18ae2946b799264717f480e6596Douglas Gregor Explicit).first; 252c1d22393628a145e54396c0ac66e9625d13a7658Argyrios Kyrtzidis Result->addTopHeader(File); 253e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 254e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // If inferred submodules export everything they import, add a 255e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // wildcard to the set of exports. 2569f74f4f05c407b59f7639606bb0f4ec377b4e126Douglas Gregor if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 257e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 258e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } else { 259e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Record each of the directories we stepped through as being part of 260e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // the module we found, since the umbrella header covers them all. 261e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 262e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor UmbrellaDirs[SkippedDirs[I]] = Result; 263e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } 264adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 265bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Headers[File] = KnownHeader(Result, NormalHeader); 26651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 26751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // If a header corresponds to an unavailable module, don't report 26851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // that it maps to anything. 26951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Result->isAvailable()) 270bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return KnownHeader(); 27151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 272bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return Headers[File]; 273adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor } 274adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 275adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor SkippedDirs.push_back(Dir); 276e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 277e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Retrieve our parent path. 278e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 279e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor if (DirName.empty()) 280e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor break; 281e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 282e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // Resolve the parent path to a directory entry. 283e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Dir = SourceMgr->getFileManager().getDirectory(DirName); 284e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor } while (Dir); 285adb979924ade3e25342c38a5b564400b4e0540c1Douglas Gregor 286bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return KnownHeader(); 28765f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor} 28865f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 2890be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidisbool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 2900be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis HeadersMap::const_iterator Known = Headers.find(Header); 29151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (Known != Headers.end()) 2922b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor return !Known->second.isAvailable(); 29351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 29451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor const DirectoryEntry *Dir = Header->getDir(); 295cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> SkippedDirs; 29651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor StringRef DirName = Dir->getName(); 29751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 29851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Keep walking up the directory hierarchy, looking for a directory with 29951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // an umbrella header. 30051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor do { 3010be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 30251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor = UmbrellaDirs.find(Dir); 30351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (KnownDir != UmbrellaDirs.end()) { 30451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Module *Found = KnownDir->second; 30551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found->isAvailable()) 30651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return true; 30751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 30851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Search up the module stack until we find a module with an umbrella 30951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // directory. 31051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Module *UmbrellaModule = Found; 31151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 31251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor UmbrellaModule = UmbrellaModule->Parent; 31351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 31451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (UmbrellaModule->InferSubmodules) { 31551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor for (unsigned I = SkippedDirs.size(); I != 0; --I) { 31651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Find or create the module that corresponds to this directory name. 3178b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 3188b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 3198b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 3208b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 32151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Found = lookupModuleQualified(Name, Found); 32251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found) 32351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 32451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found->isAvailable()) 32551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return true; 32651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 32751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 32851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Infer a submodule with the same name as this header file. 3298b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 3308b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor StringRef Name = sanitizeFilenameAsIdentifier( 3318b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(Header->getName()), 3328b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor NameBuf); 33351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Found = lookupModuleQualified(Name, Found); 33451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Found) 33551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 33651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 33751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 33851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return !Found->isAvailable(); 33951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 34051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 34151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor SkippedDirs.push_back(Dir); 34251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 34351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Retrieve our parent path. 34451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 34551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (DirName.empty()) 34651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 34751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 34851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Resolve the parent path to a directory entry. 34951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Dir = SourceMgr->getFileManager().getDirectory(DirName); 35051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } while (Dir); 35151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 35251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return false; 35351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor} 35451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 3550be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::findModule(StringRef Name) const { 3560be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 357484535e45b4d301847a157e943c7823da5d40884Douglas Gregor if (Known != Modules.end()) 358484535e45b4d301847a157e943c7823da5d40884Douglas Gregor return Known->getValue(); 359484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 360484535e45b4d301847a157e943c7823da5d40884Douglas Gregor return 0; 361484535e45b4d301847a157e943c7823da5d40884Douglas Gregor} 362484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 3630be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::lookupModuleUnqualified(StringRef Name, 3640be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis Module *Context) const { 36590db26000aefe9335370013eec64c85232d80227Douglas Gregor for(; Context; Context = Context->Parent) { 36690db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Context)) 36790db26000aefe9335370013eec64c85232d80227Douglas Gregor return Sub; 36890db26000aefe9335370013eec64c85232d80227Douglas Gregor } 36990db26000aefe9335370013eec64c85232d80227Douglas Gregor 37090db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 37190db26000aefe9335370013eec64c85232d80227Douglas Gregor} 37290db26000aefe9335370013eec64c85232d80227Douglas Gregor 3730be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModule *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 37490db26000aefe9335370013eec64c85232d80227Douglas Gregor if (!Context) 37590db26000aefe9335370013eec64c85232d80227Douglas Gregor return findModule(Name); 37690db26000aefe9335370013eec64c85232d80227Douglas Gregor 377b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor return Context->findSubmodule(Name); 37890db26000aefe9335370013eec64c85232d80227Douglas Gregor} 37990db26000aefe9335370013eec64c85232d80227Douglas Gregor 3801a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorstd::pair<Module *, bool> 381392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas GregorModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 382392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor bool IsExplicit) { 383392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Try to find an existing module with this name. 384b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (Module *Sub = lookupModuleQualified(Name, Parent)) 385b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor return std::make_pair(Sub, false); 386392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 387392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor // Create a new module with this name. 388392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 389392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor IsExplicit); 390d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis if (!Parent) { 391392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor Modules[Name] = Result; 392d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis if (!LangOpts.CurrentModule.empty() && !CompilingModule && 393d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis Name == LangOpts.CurrentModule) { 394d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis CompilingModule = Result; 395d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis } 396d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis } 397392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor return std::make_pair(Result, true); 398392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor} 399392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor 40082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregorbool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, 4010be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis StringRef Name, bool &IsSystem) const { 40282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have already looked into the parent directory 40382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // for a module map. 4040be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 40582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 40682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) 40782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return false; 40882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 40982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!inferred->second.InferModules) 41082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return false; 41182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 41282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We're allowed to infer for this directory, but make sure it's okay 41382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // to infer this particular module. 41482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool canInfer = std::find(inferred->second.ExcludedModules.begin(), 41582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred->second.ExcludedModules.end(), 41682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Name) == inferred->second.ExcludedModules.end(); 41782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 41882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (canInfer && inferred->second.InferSystemModules) 41982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor IsSystem = true; 42082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 42182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return canInfer; 42282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor} 42382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 4248767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor/// \brief For a framework module, infer the framework against which we 4258767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor/// should link. 4268767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregorstatic void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 4278767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor FileManager &FileMgr) { 4288767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor assert(Mod->IsFramework && "Can only infer linking for framework modules"); 4298767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor assert(!Mod->isSubFramework() && 4308767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor "Can only infer linking for top-level frameworks"); 4318767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 4328767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor SmallString<128> LibName; 4338767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor LibName += FrameworkDir->getName(); 4348767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor llvm::sys::path::append(LibName, Mod->Name); 4358767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (FileMgr.getFile(LibName)) { 4368767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 4378767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor /*IsFramework=*/true)); 4388767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 4398767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor} 4408767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 4411a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule * 44282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas GregorModuleMap::inferFrameworkModule(StringRef ModuleName, 443ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const DirectoryEntry *FrameworkDir, 444a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor bool IsSystem, 445ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Module *Parent) { 4462821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Check whether we've already found this module. 447ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 448ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor return Mod; 449ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor 450ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor FileManager &FileMgr = SourceMgr->getFileManager(); 45182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 45282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // If the framework has a parent path from which we're allowed to infer 45382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // a framework module, do so. 45482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Parent) { 4557005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether we're allowed to infer a module map. 456713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 4577005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Note: as an egregious but useful hack we use the real path here, because 4587005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // we might be looking at an embedded framework that symlinks out to a 4597005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // top-level framework, and we need to infer as if we were naming the 4607005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // top-level framework. 461713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef FrameworkDirName 462713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor = SourceMgr->getFileManager().getCanonicalName(FrameworkDir); 4637005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 46482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool canInfer = false; 4657005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 46682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Figure out the parent path. 4677005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 46882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 46982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have already looked into the parent directory 47082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // for a module map. 4710be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios Kyrtzidis llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 47282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 47382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) { 47482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We haven't looked here before. Load a module map, if there is 47582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // one. 47682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor SmallString<128> ModMapPath = Parent; 47782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor llvm::sys::path::append(ModMapPath, "module.map"); 47882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) { 4798f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor parseModuleMapFile(ModMapFile, IsSystem); 48082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.find(ParentDir); 48182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 48282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 48382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred == InferredDirectories.end()) 48482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred = InferredDirectories.insert( 48582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor std::make_pair(ParentDir, InferredDirectory())).first; 48682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 48782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 48882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred->second.InferModules) { 48982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We're allowed to infer for this directory, but make sure it's okay 49082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // to infer this particular module. 4917005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef Name = llvm::sys::path::stem(FrameworkDirName); 49282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor canInfer = std::find(inferred->second.ExcludedModules.begin(), 49382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor inferred->second.ExcludedModules.end(), 49482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Name) == inferred->second.ExcludedModules.end(); 49582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 49682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (inferred->second.InferSystemModules) 49782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor IsSystem = true; 49882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 49982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 50082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 50182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 50282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // If we're not allowed to infer a framework module, don't. 50382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!canInfer) 50482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return 0; 50582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 50682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 50782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 5082821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Look for an umbrella header. 509f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 510ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 511ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 5122821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 5132821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // FIXME: If there's no umbrella header, we could probably scan the 5142821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // framework to load *everything*. But, it's not clear that this is a good 5152821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // idea. 5162821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor if (!UmbrellaHeader) 5172821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return 0; 5182821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 519ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Module *Result = new Module(ModuleName, SourceLocation(), Parent, 520ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor /*IsFramework=*/true, /*IsExplicit=*/false); 521a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (IsSystem) 522a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Result->IsSystem = IsSystem; 523a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 524b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (!Parent) 525ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Modules[ModuleName] = Result; 526b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor 527489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // umbrella header "umbrella-header-name" 52810694cee2588442bee1e717f5042c58ffee25279Douglas Gregor Result->Umbrella = UmbrellaHeader; 529bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader); 5303cee31e4d7c23d3d5d0b8927998577b9f75087d7Douglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 531209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor 532209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor // export * 533209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor Result->Exports.push_back(Module::ExportDecl(0, true)); 534209977c4d809914a20fd44873876c76cf972a56dDouglas Gregor 535e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor // module * { export * } 536e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferSubmodules = true; 537e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor Result->InferExportWildcard = true; 538e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 539ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // Look for subframeworks. 540ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor llvm::error_code EC; 541f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> SubframeworksDirName 54252b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor = StringRef(FrameworkDir->getName()); 543ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 544f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> SubframeworksDirNameNative; 54552b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor llvm::sys::path::native(SubframeworksDirName.str(), 54652b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor SubframeworksDirNameNative); 54752b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor for (llvm::sys::fs::directory_iterator 54852b1ed3685c80cb436f2a616c3c13a066f9d1e31Douglas Gregor Dir(SubframeworksDirNameNative.str(), EC), DirEnd; 549ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 550ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (!StringRef(Dir->path()).endswith(".framework")) 551ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor continue; 55298cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 553ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor if (const DirectoryEntry *SubframeworkDir 554ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor = FileMgr.getDirectory(Dir->path())) { 55598cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // Note: as an egregious but useful hack, we use the real path here and 55698cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // check whether it is actually a subdirectory of the parent directory. 55798cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // This will not be the case if the 'subframework' is actually a symlink 55898cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor // out to a top-level framework. 559713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 560713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor bool FoundParent = false; 561713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor do { 562713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor // Get the parent directory name. 563713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor SubframeworkDirName 564713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor = llvm::sys::path::parent_path(SubframeworkDirName); 565713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (SubframeworkDirName.empty()) 566713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor break; 567713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor 568713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 569713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor FoundParent = true; 570713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor break; 571713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor } 572713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor } while (true); 57398cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 574713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor if (!FoundParent) 575713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor continue; 57698cfcbf2aeff03d40575ab79b03e6baeff4e3570Douglas Gregor 577ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor // FIXME: Do we want to warn about subframeworks without umbrella headers? 5788b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SmallString<32> NameBuf; 5798b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor inferFrameworkModule(sanitizeFilenameAsIdentifier( 5808b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor llvm::sys::path::stem(Dir->path()), NameBuf), 5818b48e087bc0e022703d235fa6382551cfaa57ae6Douglas Gregor SubframeworkDir, IsSystem, Result); 582ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 583ac252a3b0f8101a7274309e4a5cf2d5f0fdba675Douglas Gregor } 5843a110f75acafc992cb664200cebec90520986715Douglas Gregor 5858767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // If the module is a top-level framework, automatically link against the 5868767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // framework. 5878767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (!Result->isSubFramework()) { 5888767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor inferFrameworkLink(Result, FrameworkDir, FileMgr); 5898767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 5908767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 5912821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Result; 5922821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 5932821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 594e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregorvoid ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 595bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader); 59610694cee2588442bee1e717f5042c58ffee25279Douglas Gregor Mod->Umbrella = UmbrellaHeader; 5976a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 598e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 599e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 60077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregorvoid ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 60177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Mod->Umbrella = UmbrellaDir; 60277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor UmbrellaDirs[UmbrellaDir] = Mod; 60377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor} 60477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 6052b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregorvoid ModuleMap::addHeader(Module *Mod, const FileEntry *Header, 606bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleHeaderRole Role) { 607bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Role == ExcludedHeader) { 6082b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor Mod->ExcludedHeaders.push_back(Header); 60955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } else { 610bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Role == PrivateHeader) 611bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Mod->PrivateHeaders.push_back(Header); 612bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl else 613bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Mod->NormalHeaders.push_back(Header); 614d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 615bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); 61655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } 617bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Headers[Header] = KnownHeader(Mod, Role); 618e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor} 619e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor 620f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregorconst FileEntry * 6210be5e567e3a48592fd6b11f88cc77efb20c76f26Argyrios KyrtzidisModuleMap::getContainingModuleMapFile(Module *Module) const { 622f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor if (Module->DefinitionLoc.isInvalid() || !SourceMgr) 623f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor return 0; 624f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 625f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor return SourceMgr->getFileEntryForID( 626f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor SourceMgr->getFileID(Module->DefinitionLoc)); 627f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor} 628f9e357d8a66c606a86a6e1aef678898b8843bd30Douglas Gregor 629a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMap::dump() { 630a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Modules:"; 631a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 632a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MEnd = Modules.end(); 633a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor M != MEnd; ++M) 634804c3bfee22076f232dddf4839439119cfdee2b6Douglas Gregor M->getValue()->print(llvm::errs(), 2); 635a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 636a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << "Headers:"; 6372b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 638a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor H != HEnd; ++H) { 639a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::errs() << " \"" << H->first->getName() << "\" -> " 6402b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << H->second.getModule()->getFullModuleName() << "\n"; 641a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 642a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 643a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 64490db26000aefe9335370013eec64c85232d80227Douglas Gregorbool ModuleMap::resolveExports(Module *Mod, bool Complain) { 64590db26000aefe9335370013eec64c85232d80227Douglas Gregor bool HadError = false; 64690db26000aefe9335370013eec64c85232d80227Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 64790db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 64890db26000aefe9335370013eec64c85232d80227Douglas Gregor Complain); 6490adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor if (Export.getPointer() || Export.getInt()) 65090db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->Exports.push_back(Export); 65190db26000aefe9335370013eec64c85232d80227Douglas Gregor else 65290db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 65390db26000aefe9335370013eec64c85232d80227Douglas Gregor } 65490db26000aefe9335370013eec64c85232d80227Douglas Gregor Mod->UnresolvedExports.clear(); 65590db26000aefe9335370013eec64c85232d80227Douglas Gregor return HadError; 65690db26000aefe9335370013eec64c85232d80227Douglas Gregor} 65790db26000aefe9335370013eec64c85232d80227Douglas Gregor 658906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorbool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 659906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor bool HadError = false; 660906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 661906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 662906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod, Complain); 663906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!OtherMod) { 664906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor HadError = true; 665906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor continue; 666906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 667906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 668906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module::Conflict Conflict; 669906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Other = OtherMod; 670906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Message = Mod->UnresolvedConflicts[I].Message; 671906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod->Conflicts.push_back(Conflict); 672906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 673906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Mod->UnresolvedConflicts.clear(); 674906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return HadError; 675906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 676906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 67755988680ece66b8e505ee136b35e74fcb1173aeeDouglas GregorModule *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 67855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (Loc.isInvalid()) 67955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return 0; 68055988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 68155988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor // Use the expansion location to determine which module we're in. 68255988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 68355988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor if (!ExpansionLoc.isFileID()) 68455988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor return 0; 68555988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 68655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 68755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor const SourceManager &SrcMgr = Loc.getManager(); 68855988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor FileID ExpansionFileID = ExpansionLoc.getFileID(); 68955988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 690303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor while (const FileEntry *ExpansionFile 691303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor = SrcMgr.getFileEntryForID(ExpansionFileID)) { 692303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // Find the module that owns this header (if any). 693bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 694303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor return Mod; 695303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor 696303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // No module owns this header, so look up the inclusion chain to see if 697303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor // any included header has an associated module. 698303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 699303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor if (IncludeLoc.isInvalid()) 700303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor return 0; 701303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor 702303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 703303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor } 704303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor 705303aae98a5a27f2595d023c0b4e1484bf2c0ee57Douglas Gregor return 0; 70655988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor} 70755988680ece66b8e505ee136b35e74fcb1173aeeDouglas Gregor 708a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 709a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor// Module map file parser 710a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor//----------------------------------------------------------------------------// 711a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 712a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregornamespace clang { 713a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief A token in a module map file. 714a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor struct MMToken { 715a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor enum TokenKind { 71651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Comma, 71763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ConfigMacros, 718906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict, 719a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor EndOfFile, 720a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HeaderKeyword, 721a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Identifier, 7222b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor ExcludeKeyword, 723a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ExplicitKeyword, 72490db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportKeyword, 7255f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ExternKeyword, 726a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor FrameworkKeyword, 727b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor LinkKeyword, 728a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleKeyword, 72990db26000aefe9335370013eec64c85232d80227Douglas Gregor Period, 730bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl PrivateKeyword, 731a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor UmbrellaKeyword, 73251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor RequiresKeyword, 73390db26000aefe9335370013eec64c85232d80227Douglas Gregor Star, 734a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLiteral, 735a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LBrace, 736a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor RBrace, 737a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor LSquare, 738a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor RSquare 739a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } Kind; 740a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 741a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Location; 742a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned StringLength; 743a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const char *StringData; 744a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 745a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void clear() { 746a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Kind = EndOfFile; 747a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Location = 0; 748a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLength = 0; 749a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringData = 0; 750a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 751a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 752a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool is(TokenKind K) const { return Kind == K; } 753a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 754a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation getLocation() const { 755a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return SourceLocation::getFromRawEncoding(Location); 756a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 757a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 758a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef getString() const { 759a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return StringRef(StringData, StringLength); 760a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 761a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 76282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 76382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor /// \brief The set of attributes that can be attached to a module. 764ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling struct Attributes { 76563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attributes() : IsSystem(), IsExhaustive() { } 76682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 76782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor /// \brief Whether this is a system module. 76882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor unsigned IsSystem : 1; 76963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 77063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor /// \brief Whether this is an exhaustive set of configuration macros. 77163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor unsigned IsExhaustive : 1; 77282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor }; 773a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 77482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 775a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor class ModuleMapParser { 776a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Lexer &L; 777a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceManager &SourceMgr; 7789a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 7799a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor /// \brief Default target information, used only for string literal 7809a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor /// parsing. 7819a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor const TargetInfo *Target; 7829a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 783a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags; 784a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModuleMap ⤅ 785a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 7868b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor /// \brief The directory that this module map resides in. 7878b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor const DirectoryEntry *Directory; 7882f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 7892f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor /// \brief The directory containing Clang-supplied headers. 7902f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const DirectoryEntry *BuiltinIncludeDir; 7912f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 7928f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor /// \brief Whether this module map is in a system header directory. 7938f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem; 7948f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor 795a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Whether an error occurred. 796a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool HadError; 7979a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor 798a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Stores string data for the various string literals referenced 799a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// during parsing. 800a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::BumpPtrAllocator StringData; 801a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 802a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The current token. 803a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor MMToken Tok; 804a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 805a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief The active module. 8061a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Module *ActiveModule; 807a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 808a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Consume the current token and return its location. 809a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation consumeToken(); 810a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 811a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// \brief Skip tokens until we reach the a token with the given kind 812a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /// (or the end of the file). 813a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void skipUntil(MMToken::TokenKind K); 814587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 815cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 816587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor bool parseModuleId(ModuleId &Id); 817a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor void parseModuleDecl(); 8185f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper void parseExternModuleDecl(); 81951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor void parseRequiresDecl(); 820bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl void parseHeaderDecl(clang::MMToken::TokenKind, 821bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation LeadingLoc); 82277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 82390db26000aefe9335370013eec64c85232d80227Douglas Gregor void parseExportDecl(); 824b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor void parseLinkDecl(); 82563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor void parseConfigMacros(); 826906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor void parseConflict(); 82782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor void parseInferredModuleDecl(bool Framework, bool Explicit); 828ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling bool parseOptionalAttributes(Attributes &Attrs); 82982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 8306a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor const DirectoryEntry *getOverriddenHeaderSearchDir(); 8316a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor 832a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor public: 833a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 8349a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor const TargetInfo *Target, 835a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DiagnosticsEngine &Diags, 8368b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor ModuleMap &Map, 8372f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const DirectoryEntry *Directory, 8388f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor const DirectoryEntry *BuiltinIncludeDir, 8398f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem) 8409a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 8418f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 8428f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor IsSystem(IsSystem), HadError(false), ActiveModule(0) 843a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor { 844a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 845a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 846a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 847a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 848a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool parseModuleMapFile(); 849a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor }; 850a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 851a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 852a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas GregorSourceLocation ModuleMapParser::consumeToken() { 853a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorretry: 854a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation Result = Tok.getLocation(); 855a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.clear(); 856a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 857a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Token LToken; 858a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor L.LexFromRawLexer(LToken); 859a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Location = LToken.getLocation().getRawEncoding(); 860a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (LToken.getKind()) { 861a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::raw_identifier: 862a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringData = LToken.getRawIdentifierData(); 863a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringLength = LToken.getLength(); 864a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 86563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("config_macros", MMToken::ConfigMacros) 866906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor .Case("conflict", MMToken::Conflict) 8672b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor .Case("exclude", MMToken::ExcludeKeyword) 868a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("explicit", MMToken::ExplicitKeyword) 86990db26000aefe9335370013eec64c85232d80227Douglas Gregor .Case("export", MMToken::ExportKeyword) 8705f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper .Case("extern", MMToken::ExternKeyword) 871a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor .Case("framework", MMToken::FrameworkKeyword) 87263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("header", MMToken::HeaderKeyword) 873b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor .Case("link", MMToken::LinkKeyword) 874a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("module", MMToken::ModuleKeyword) 875bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl .Case("private", MMToken::PrivateKeyword) 87651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor .Case("requires", MMToken::RequiresKeyword) 877a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Case("umbrella", MMToken::UmbrellaKeyword) 878a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor .Default(MMToken::Identifier); 879a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 88051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 88151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case tok::comma: 88251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Tok.Kind = MMToken::Comma; 88351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 88451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 885a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::eof: 886a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::EndOfFile; 887a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 888a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 889a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::l_brace: 890a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::LBrace; 891a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 892a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 893a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case tok::l_square: 894a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Tok.Kind = MMToken::LSquare; 895a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 896a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 89790db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::period: 89890db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Period; 89990db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 90090db26000aefe9335370013eec64c85232d80227Douglas Gregor 901a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::r_brace: 902a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::RBrace; 903a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 904a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 905a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case tok::r_square: 906a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor Tok.Kind = MMToken::RSquare; 907a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 908a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 90990db26000aefe9335370013eec64c85232d80227Douglas Gregor case tok::star: 91090db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.Kind = MMToken::Star; 91190db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 91290db26000aefe9335370013eec64c85232d80227Douglas Gregor 913a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::string_literal: { 91499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (LToken.hasUDSuffix()) { 91599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 91699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith HadError = true; 91799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith goto retry; 91899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 91999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith 920a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the string literal. 921a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor LangOptions LangOpts; 922a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 923a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (StringLiteral.hadError) 924a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 925a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 926a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Copy the string literal into our string data allocator. 927a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned Length = StringLiteral.GetStringLength(); 928a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor char *Saved = StringData.Allocate<char>(Length + 1); 929a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor memcpy(Saved, StringLiteral.GetString().data(), Length); 930a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Saved[Length] = 0; 931a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 932a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Form the token. 933a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.Kind = MMToken::StringLiteral; 934a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringData = Saved; 935a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Tok.StringLength = Length; 936a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 937a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 938a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 939a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case tok::comment: 940a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 941a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 942a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 943a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 944a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 945a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor goto retry; 946a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 947a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 948a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 949a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 950a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 951a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::skipUntil(MMToken::TokenKind K) { 952a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor unsigned braceDepth = 0; 953a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor unsigned squareDepth = 0; 954a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 955a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 956a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 957a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 958a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 959a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 960a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 961a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 962a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 963a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ++braceDepth; 964a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 965a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 966a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::LSquare: 967a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 968a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor return; 969a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 970a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor ++squareDepth; 971a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 972a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 973a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 974a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (braceDepth > 0) 975a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor --braceDepth; 976a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else if (Tok.is(K)) 977a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 978a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 979a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 980a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::RSquare: 981a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (squareDepth > 0) 982a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor --squareDepth; 983a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor else if (Tok.is(K)) 984a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor return; 985a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor break; 986a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 987a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 988a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 989a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 990a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 991a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 992a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 993a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 994a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 995a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 996a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 997587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \brief Parse a module-id. 998587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 999587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// module-id: 1000587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier 1001587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// identifier '.' module-id 1002587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// 1003587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// \returns true if an error occurred, false otherwise. 1004587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregorbool ModuleMapParser::parseModuleId(ModuleId &Id) { 1005587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.clear(); 1006587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor do { 1007587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Tok.is(MMToken::Identifier)) { 1008587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1009587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 1010587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1011587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1012587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return true; 1013587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1014587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1015587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!Tok.is(MMToken::Period)) 1016587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor break; 1017587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1018587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor consumeToken(); 1019587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } while (true); 1020587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1021587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return false; 1022587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor} 1023587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1024a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregornamespace { 1025a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief Enumerates the known attributes. 1026a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor enum AttributeKind { 1027a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief An unknown attribute. 1028a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor AT_unknown, 1029a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor /// \brief The 'system' attribute. 103063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor AT_system, 103163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor /// \brief The 'exhaustive' attribute. 103263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor AT_exhaustive 1033a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor }; 1034a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor} 1035a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1036a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module declaration. 1037a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1038a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration: 10395f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 'extern' 'module' module-id string-literal 1040a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1041a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// { module-member* } 1042a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor/// 1043a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-member: 104451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// requires-declaration 1045a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// header-declaration 1046587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor/// submodule-declaration 104790db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration 1048b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// link-declaration 10491e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// 10501e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// submodule-declaration: 10511e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// module-declaration 10521e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor/// inferred-submodule-declaration 1053a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorvoid ModuleMapParser::parseModuleDecl() { 1054a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 10555f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 10565f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (Tok.is(MMToken::ExternKeyword)) { 10575f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper parseExternModuleDecl(); 10585f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 10595f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 10605f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 1061d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'explicit' or 'framework' keyword, if present. 1062587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ExplicitLoc; 1063a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Explicit = false; 1064d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor bool Framework = false; 1065a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 1066a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor // Parse 'explicit' keyword, if present. 1067d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::ExplicitKeyword)) { 1068587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = consumeToken(); 1069a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Explicit = true; 1070a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1071d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1072d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Parse 'framework' keyword, if present. 1073d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 1074d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor consumeToken(); 1075d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Framework = true; 1076d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 1077a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1078a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse 'module' keyword. 1079a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::ModuleKeyword)) { 1080e6fb9876970e2dc55f091522644efa16caa9ba06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1081a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1082a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1083a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1084a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1085a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); // 'module' keyword 10861e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 10871e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If we have a wildcard for the module name, this is an inferred submodule. 10881e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse it. 10891e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 109082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return parseInferredModuleDecl(Framework, Explicit); 1091a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1092a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the module name. 1093587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleId Id; 1094587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (parseModuleId(Id)) { 1095587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1096587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1097587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 109882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 1099587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 1100587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 1101587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1102587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor << SourceRange(Id.front().second, Id.back().second); 1103587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1104587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1105587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1106587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1107587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else if (Id.size() == 1 && Explicit) { 1108587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Top-level modules can't be explicit. 1109587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1110587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Explicit = false; 1111587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ExplicitLoc = SourceLocation(); 1112a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1113a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1114587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1115587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Module *PreviousActiveModule = ActiveModule; 1116587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Id.size() > 1) { 1117587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // This module map defines a submodule. Go find the module of which it 1118587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // is a submodule. 1119587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = 0; 1120587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1121587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1122587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = Next; 1123587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor continue; 1124587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1125587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1126587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ActiveModule) { 1127587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1128587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor << Id[I].first << ActiveModule->getTopLevelModule(); 1129587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1130587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1131587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1132587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor HadError = true; 1133587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return; 1134587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1135587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1136587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1137587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor StringRef ModuleName = Id.back().first; 1138587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor SourceLocation ModuleNameLoc = Id.back().second; 1139a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1140a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor // Parse the optional attribute list. 1141ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling Attributes Attrs; 114282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor parseOptionalAttributes(Attrs); 1143a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor 1144a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the opening brace. 1145a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 1146a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1147a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 1148a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1149a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1150a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1151a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 1152a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1153a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this (sub)module has already been defined. 1154b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1155c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1156c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor // Skip the module definition. 1157c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor skipUntil(MMToken::RBrace); 1158c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor if (Tok.is(MMToken::RBrace)) 1159c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor consumeToken(); 1160c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor else { 1161c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1162c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1163c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor HadError = true; 1164c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor } 1165c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor return; 1166c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor } 1167c634f50c5cc892b899659c1743d696766c82afcdDouglas Gregor 1168a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1169a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor << ModuleName; 1170b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1171a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1172a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Skip the module definition. 1173a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor skipUntil(MMToken::RBrace); 1174a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 1175a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1176a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1177a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1178a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1179a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1180a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1181a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Start defining this module. 1182b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1183b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor Explicit).first; 1184b7a7819473709c01ea024a2dc15e99d38f0f8760Douglas Gregor ActiveModule->DefinitionLoc = ModuleNameLoc; 11858f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (Attrs.IsSystem || IsSystem) 1186a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor ActiveModule->IsSystem = true; 1187a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1188a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Done = false; 1189a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1190a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1191a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1192a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 1193a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Done = true; 1194a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 119563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 119663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case MMToken::ConfigMacros: 119763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor parseConfigMacros(); 119863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 119963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 1200906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor case MMToken::Conflict: 1201906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor parseConflict(); 1202906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor break; 1203906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1204a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ExplicitKeyword: 12055f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper case MMToken::ExternKeyword: 1206d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor case MMToken::FrameworkKeyword: 1207a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 1208a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 1209a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 12105f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 121190db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 121290db26000aefe9335370013eec64c85232d80227Douglas Gregor parseExportDecl(); 121390db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 121490db26000aefe9335370013eec64c85232d80227Douglas Gregor 121551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::RequiresKeyword: 121651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor parseRequiresDecl(); 121751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 121851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 121977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor case MMToken::UmbrellaKeyword: { 122077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor SourceLocation UmbrellaLoc = consumeToken(); 122177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (Tok.is(MMToken::HeaderKeyword)) 1222bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 122377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor else 122477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor parseUmbrellaDirDecl(UmbrellaLoc); 1225a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 122677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 1227a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 12282b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor case MMToken::ExcludeKeyword: { 12292b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor SourceLocation ExcludeLoc = consumeToken(); 12302b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (Tok.is(MMToken::HeaderKeyword)) { 1231bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc); 12322b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor } else { 12332b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 12342b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << "exclude"; 12352b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor } 12362b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor break; 12372b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor } 12382b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor 1239bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: { 1240bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation PrivateLoc = consumeToken(); 1241bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (Tok.is(MMToken::HeaderKeyword)) { 1242bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc); 1243bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } else { 1244bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1245bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl << "private"; 1246bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } 1247bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl break; 1248bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } 1249bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl 1250489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor case MMToken::HeaderKeyword: 1251bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation()); 1252a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1253b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1254b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor case MMToken::LinkKeyword: 1255b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor parseLinkDecl(); 1256b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor break; 1257b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1258a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor default: 1259a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1260a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1261a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1262a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1263a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (!Done); 1264a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1265a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (Tok.is(MMToken::RBrace)) 1266a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 1267a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor else { 1268a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1269a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1270a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1271a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1272a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 12738767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // If the active module is a top-level framework, and there are no link 12748767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor // libraries, automatically link against the framework. 12758767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 12768767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor ActiveModule->LinkLibraries.empty()) { 12778767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 12788767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor } 12798767dc29ec23f96e71658f760333bdf5d87283d5Douglas Gregor 1280587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // We're done parsing this module. Pop back to the previous module. 1281587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ActiveModule = PreviousActiveModule; 1282a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1283d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 12845f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// \brief Parse an extern module declaration. 12855f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 12865f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// extern module-declaration: 12875f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper/// 'extern' 'module' module-id string-literal 12885f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jaspervoid ModuleMapParser::parseExternModuleDecl() { 12895f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper assert(Tok.is(MMToken::ExternKeyword)); 12905f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // 'extern' keyword 12915f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 12925f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse 'module' keyword. 12935f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (!Tok.is(MMToken::ModuleKeyword)) { 12945f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 12955f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); 12965f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 12975f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 12985f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 12995f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // 'module' keyword 13005f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 13015f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse the module name. 13025f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ModuleId Id; 13035f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (parseModuleId(Id)) { 13045f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 13055f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 13065f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 13075f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 13085f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper // Parse the referenced module map file name. 13095f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (!Tok.is(MMToken::StringLiteral)) { 13105f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 13115f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper HadError = true; 13125f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper return; 13135f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 13145f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper std::string FileName = Tok.getString(); 13155f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper consumeToken(); // filename 13165f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 13175f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper StringRef FileNameRef = FileName; 13185f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper SmallString<128> ModuleMapFileName; 13195f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (llvm::sys::path::is_relative(FileNameRef)) { 13205f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper ModuleMapFileName += Directory->getName(); 13215f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper llvm::sys::path::append(ModuleMapFileName, FileName); 13225f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper FileNameRef = ModuleMapFileName.str(); 13235f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper } 13245f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 13255f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper Map.parseModuleMapFile(File, /*IsSystem=*/false); 13265f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper} 13275f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper 132851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// \brief Parse a requires declaration. 132951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 133051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// requires-declaration: 133151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 'requires' feature-list 133251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// 133351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// feature-list: 133451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// identifier ',' feature-list 133551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor/// identifier 133651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregorvoid ModuleMapParser::parseRequiresDecl() { 133751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor assert(Tok.is(MMToken::RequiresKeyword)); 133851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 133951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Parse 'requires' keyword. 134051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 134151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 134251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Parse the feature-list. 134351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor do { 134451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Tok.is(MMToken::Identifier)) { 134551f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 134651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor HadError = true; 134751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return; 134851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } 134951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 135051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Consume the feature name. 135151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor std::string Feature = Tok.getString(); 135251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 135351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 135451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Add this feature. 1355dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); 135651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 135751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (!Tok.is(MMToken::Comma)) 135851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor break; 135951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 136051f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor // Consume the comma. 136151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor consumeToken(); 136251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor } while (true); 136351f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor} 136451f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor 1365d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// \brief Append to \p Paths the set of paths needed to get to the 1366d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor/// subframework in which the given module lives. 13675bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramerstatic void appendSubframeworkPaths(Module *Mod, 1368cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVectorImpl<char> &Path) { 1369d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Collect the framework names from the given module to the top-level module. 1370cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<StringRef, 2> Paths; 1371d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor for (; Mod; Mod = Mod->Parent) { 1372d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Mod->IsFramework) 1373d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor Paths.push_back(Mod->Name); 1374d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 1375d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1376d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (Paths.empty()) 1377d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor return; 1378d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1379d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor // Add Frameworks/Name.framework for each subframework. 1380ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer for (unsigned I = Paths.size() - 1; I != 0; --I) 1381ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1382d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor} 1383d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor 1384489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// \brief Parse a header declaration. 1385a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1386489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// header-declaration: 1387489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor/// 'umbrella'[opt] 'header' string-literal 13882b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor/// 'exclude'[opt] 'header' string-literal 1389bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowlvoid ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1390bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl SourceLocation LeadingLoc) { 1391489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor assert(Tok.is(MMToken::HeaderKeyword)); 1392489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor consumeToken(); 1393489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor 1394a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse the header name. 1395a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1396a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1397489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor << "header"; 1398a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 1399a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return; 1400a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1401587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor std::string FileName = Tok.getString(); 1402a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor SourceLocation FileNameLoc = consumeToken(); 1403489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor 140477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Check whether we already have an umbrella. 1405bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 140677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash) 140777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << ActiveModule->getFullModuleName(); 14088b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 14098b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor return; 14108b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1411a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 14128b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Look for this file. 1413587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor const FileEntry *File = 0; 14142f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor const FileEntry *BuiltinFile = 0; 1415f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PathName; 1416587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (llvm::sys::path::is_absolute(FileName)) { 1417587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor PathName = FileName; 1418587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 14196a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) { 14206a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor PathName = Dir->getName(); 14216a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor llvm::sys::path::append(PathName, FileName); 14226a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 1423587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1424587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Search for the header file within the search directory. 14256a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor PathName = Directory->getName(); 1426587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor unsigned PathLength = PathName.size(); 142718ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor 1428d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor if (ActiveModule->isPartOfFramework()) { 1429d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor appendSubframeworkPaths(ActiveModule, PathName); 1430587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1431587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the public headers. 1432ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(PathName, "Headers", FileName); 1433587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 1434587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1435587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (!File) { 1436587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether this file is in the private headers. 1437587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor PathName.resize(PathLength); 1438ceb6dc8e5afbd8e4dad7aaa1948994965fd8ff2eBenjamin Kramer llvm::sys::path::append(PathName, "PrivateHeaders", FileName); 1439587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 1440587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1441587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } else { 1442587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Lookup for normal headers. 1443587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(PathName, FileName); 1444587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor File = SourceMgr.getFileManager().getFile(PathName); 14452f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 14462f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If this is a system module with a top-level header, this header 14472f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // may have a counterpart (or replacement) in the set of headers 14482f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // supplied by Clang. Find that builtin header. 1449bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1450bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1451bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl isBuiltinHeader(FileName)) { 1452f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 14532f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor llvm::sys::path::append(BuiltinPathName, FileName); 14542f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 14552f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 14562f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If Clang supplies this header but the underlying system does not, 14572f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // just silently swap in our builtin version. Otherwise, we'll end 14582f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // up adding both (later). 14592f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor if (!File && BuiltinFile) { 14602f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor File = BuiltinFile; 14612f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor BuiltinFile = 0; 14622f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor } 14632f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor } 1464d620a84a01cc232a9449dbcc2c40bd43ca314fc9Douglas Gregor } 146518ee547b6926cacefa15eed8ca60ff73d22e279bDouglas Gregor } 1466a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor 14678b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 14688b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor // Come up with a lazy way to do this. 1469587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (File) { 14702b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) { 14718b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 14722b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << FileName << OwningModule.getModule()->getFullModuleName(); 14738b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 1474bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } else if (LeadingToken == MMToken::UmbrellaKeyword) { 1475489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor const DirectoryEntry *UmbrellaDir = File->getDir(); 14762b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1477bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 14782b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor << UmbrellaModule->getFullModuleName(); 1479489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor HadError = true; 1480489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor } else { 1481489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // Record this umbrella header. 1482489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor Map.setUmbrellaHeader(ActiveModule, File); 1483489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor } 14848b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } else { 1485489ad43b77c10a98df80f1395de81e3f52697e76Douglas Gregor // Record this header. 1486bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1487bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl if (LeadingToken == MMToken::ExcludeKeyword) 1488bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Role = ModuleMap::ExcludedHeader; 1489bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl else if (LeadingToken == MMToken::PrivateKeyword) 1490bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Role = ModuleMap::PrivateHeader; 1491bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl else 1492bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl assert(LeadingToken == MMToken::HeaderKeyword); 1493bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl 1494bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Map.addHeader(ActiveModule, File, Role); 14952f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor 14962f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor // If there is a builtin counterpart to this file, add it now. 14972f04f1843ca0ffca13b8b0d4dadd1f50dffb38b8Douglas Gregor if (BuiltinFile) 1498bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl Map.addHeader(ActiveModule, BuiltinFile, Role); 14998b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 1500bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl } else if (LeadingToken != MMToken::ExcludeKeyword) { 150171f49f5d8fc3c4980bed4bb7790c8d0e50586d3bDouglas Gregor // Ignore excluded header files. They're optional anyway. 150271f49f5d8fc3c4980bed4bb7790c8d0e50586d3bDouglas Gregor 15038b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 1504bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl << (LeadingToken == MMToken::UmbrellaKeyword) << FileName; 150577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 150677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 150777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor} 150877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 150977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// \brief Parse an umbrella directory declaration. 151077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// 151177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// umbrella-dir-declaration: 151277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor/// umbrella string-literal 151377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregorvoid ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 151477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Parse the directory name. 151577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 151677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 151777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << "umbrella"; 151877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 151977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 152077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 152177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 152277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor std::string DirName = Tok.getString(); 152377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor SourceLocation DirNameLoc = consumeToken(); 152477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 152577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Check whether we already have an umbrella. 152677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (ActiveModule->Umbrella) { 152777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 152877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << ActiveModule->getFullModuleName(); 15298b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor HadError = true; 153077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 153177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 153277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 153377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Look for this file. 153477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor const DirectoryEntry *Dir = 0; 153577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (llvm::sys::path::is_absolute(DirName)) 153677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Dir = SourceMgr.getFileManager().getDirectory(DirName); 153777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor else { 1538f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PathName; 153977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor PathName = Directory->getName(); 154077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor llvm::sys::path::append(PathName, DirName); 154177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Dir = SourceMgr.getFileManager().getDirectory(PathName); 15428b6d3deb5af464e1afbbeccdec369c5d4252b1a0Douglas Gregor } 154377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 154477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (!Dir) { 154577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 154677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << DirName; 154777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 154877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 154977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 155077d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 155177d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 155277d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 155377d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor << OwningModule->getFullModuleName(); 155477d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor HadError = true; 155577d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor return; 155677d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor } 155777d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor 155877d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor // Record this umbrella directory. 155977d029f6a24dbf70d97e61757945df53fb250ea0Douglas Gregor Map.setUmbrellaDir(ActiveModule, Dir); 1560a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1561a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 156290db26000aefe9335370013eec64c85232d80227Douglas Gregor/// \brief Parse a module export declaration. 156390db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 156490db26000aefe9335370013eec64c85232d80227Douglas Gregor/// export-declaration: 156590db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 'export' wildcard-module-id 156690db26000aefe9335370013eec64c85232d80227Douglas Gregor/// 156790db26000aefe9335370013eec64c85232d80227Douglas Gregor/// wildcard-module-id: 156890db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier 156990db26000aefe9335370013eec64c85232d80227Douglas Gregor/// '*' 157090db26000aefe9335370013eec64c85232d80227Douglas Gregor/// identifier '.' wildcard-module-id 157190db26000aefe9335370013eec64c85232d80227Douglas Gregorvoid ModuleMapParser::parseExportDecl() { 157290db26000aefe9335370013eec64c85232d80227Douglas Gregor assert(Tok.is(MMToken::ExportKeyword)); 157390db26000aefe9335370013eec64c85232d80227Douglas Gregor SourceLocation ExportLoc = consumeToken(); 157490db26000aefe9335370013eec64c85232d80227Douglas Gregor 157590db26000aefe9335370013eec64c85232d80227Douglas Gregor // Parse the module-id with an optional wildcard at the end. 157690db26000aefe9335370013eec64c85232d80227Douglas Gregor ModuleId ParsedModuleId; 157790db26000aefe9335370013eec64c85232d80227Douglas Gregor bool Wildcard = false; 157890db26000aefe9335370013eec64c85232d80227Douglas Gregor do { 157990db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Identifier)) { 158090db26000aefe9335370013eec64c85232d80227Douglas Gregor ParsedModuleId.push_back(std::make_pair(Tok.getString(), 158190db26000aefe9335370013eec64c85232d80227Douglas Gregor Tok.getLocation())); 158290db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 158390db26000aefe9335370013eec64c85232d80227Douglas Gregor 158490db26000aefe9335370013eec64c85232d80227Douglas Gregor if (Tok.is(MMToken::Period)) { 158590db26000aefe9335370013eec64c85232d80227Douglas Gregor consumeToken(); 158690db26000aefe9335370013eec64c85232d80227Douglas Gregor continue; 158790db26000aefe9335370013eec64c85232d80227Douglas Gregor } 158890db26000aefe9335370013eec64c85232d80227Douglas Gregor 158990db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 159090db26000aefe9335370013eec64c85232d80227Douglas Gregor } 159190db26000aefe9335370013eec64c85232d80227Douglas Gregor 159290db26000aefe9335370013eec64c85232d80227Douglas Gregor if(Tok.is(MMToken::Star)) { 159390db26000aefe9335370013eec64c85232d80227Douglas Gregor Wildcard = true; 15940adaa880993ad23186c87c7f98e7a3fd2697742cDouglas Gregor consumeToken(); 159590db26000aefe9335370013eec64c85232d80227Douglas Gregor break; 159690db26000aefe9335370013eec64c85232d80227Douglas Gregor } 159790db26000aefe9335370013eec64c85232d80227Douglas Gregor 159890db26000aefe9335370013eec64c85232d80227Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id); 159990db26000aefe9335370013eec64c85232d80227Douglas Gregor HadError = true; 160090db26000aefe9335370013eec64c85232d80227Douglas Gregor return; 160190db26000aefe9335370013eec64c85232d80227Douglas Gregor } while (true); 160290db26000aefe9335370013eec64c85232d80227Douglas Gregor 160390db26000aefe9335370013eec64c85232d80227Douglas Gregor Module::UnresolvedExportDecl Unresolved = { 160490db26000aefe9335370013eec64c85232d80227Douglas Gregor ExportLoc, ParsedModuleId, Wildcard 160590db26000aefe9335370013eec64c85232d80227Douglas Gregor }; 160690db26000aefe9335370013eec64c85232d80227Douglas Gregor ActiveModule->UnresolvedExports.push_back(Unresolved); 160790db26000aefe9335370013eec64c85232d80227Douglas Gregor} 160890db26000aefe9335370013eec64c85232d80227Douglas Gregor 1609b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// \brief Parse a link declaration. 1610b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// 1611b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// module-declaration: 1612b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// 'link' 'framework'[opt] string-literal 1613b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregorvoid ModuleMapParser::parseLinkDecl() { 1614b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor assert(Tok.is(MMToken::LinkKeyword)); 1615b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor SourceLocation LinkLoc = consumeToken(); 1616b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1617b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor // Parse the optional 'framework' keyword. 1618b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor bool IsFramework = false; 1619b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor if (Tok.is(MMToken::FrameworkKeyword)) { 1620b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor consumeToken(); 1621b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor IsFramework = true; 1622b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor } 1623b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1624b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor // Parse the library name 1625b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1626b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1627b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor << IsFramework << SourceRange(LinkLoc); 1628b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor HadError = true; 1629b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor return; 1630b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor } 1631b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 1632b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor std::string LibraryName = Tok.getString(); 1633b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor consumeToken(); 1634b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1635b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor IsFramework)); 1636b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor} 1637b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 163863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// \brief Parse a configuration macro declaration. 163963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 164063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// module-declaration: 164163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 'config_macros' attributes[opt] config-macro-list? 164263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// 164363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// config-macro-list: 164463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor/// identifier (',' identifier)? 164563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregorvoid ModuleMapParser::parseConfigMacros() { 164663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor assert(Tok.is(MMToken::ConfigMacros)); 164763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor SourceLocation ConfigMacrosLoc = consumeToken(); 164863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 164963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Only top-level modules can have configuration macros. 165063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (ActiveModule->Parent) { 165163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 165263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 165363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 165463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Parse the optional attributes. 165563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attributes Attrs; 165663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor parseOptionalAttributes(Attrs); 165763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (Attrs.IsExhaustive && !ActiveModule->Parent) { 165863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacrosExhaustive = true; 165963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 166063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 166163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // If we don't have an identifier, we're done. 166263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Identifier)) 166363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor return; 166463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 166563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Consume the first identifier. 166663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!ActiveModule->Parent) { 166763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 166863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 166963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 167063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 167163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor do { 167263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // If there's a comma, consume it. 167363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Comma)) 167463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 167563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 167663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 167763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // We expect to see a macro name here. 167863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!Tok.is(MMToken::Identifier)) { 167963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 168063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 168163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 168263a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 168363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor // Consume the macro name. 168463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor if (!ActiveModule->Parent) { 168563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 168663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } 168763a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor consumeToken(); 168863a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor } while (true); 168963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor} 169063a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 1691906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// \brief Format a module-id into a string. 1692906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorstatic std::string formatModuleId(const ModuleId &Id) { 1693906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor std::string result; 1694906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor { 1695906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor llvm::raw_string_ostream OS(result); 1696906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1697906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 1698906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (I) 1699906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor OS << "."; 1700906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor OS << Id[I].first; 1701906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1702906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1703906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1704906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return result; 1705906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 1706906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1707906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// \brief Parse a conflict declaration. 1708906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// 1709906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// module-declaration: 1710906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor/// 'conflict' module-id ',' string-literal 1711906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregorvoid ModuleMapParser::parseConflict() { 1712906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor assert(Tok.is(MMToken::Conflict)); 1713906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor SourceLocation ConflictLoc = consumeToken(); 1714906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Module::UnresolvedConflict Conflict; 1715906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1716906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the module-id. 1717906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (parseModuleId(Conflict.Id)) 1718906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 1719906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1720906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the ','. 1721906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Tok.is(MMToken::Comma)) { 1722906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 1723906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << SourceRange(ConflictLoc); 1724906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 1725906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1726906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor consumeToken(); 1727906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1728906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Parse the message. 1729906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor if (!Tok.is(MMToken::StringLiteral)) { 1730906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 1731906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor << formatModuleId(Conflict.Id); 1732906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor return; 1733906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor } 1734906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor Conflict.Message = Tok.getString().str(); 1735906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor consumeToken(); 1736906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1737906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor // Add this unresolved conflict. 1738906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor ActiveModule->UnresolvedConflicts.push_back(Conflict); 1739906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor} 1740906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor 1741b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor/// \brief Parse an inferred module declaration (wildcard modules). 174282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 174382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// module-declaration: 174482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 174582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// { inferred-module-member* } 174682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 174782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// inferred-module-member: 174882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'export' '*' 174982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 'exclude' identifier 175082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregorvoid ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 17511e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor assert(Tok.is(MMToken::Star)); 17521e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation StarLoc = consumeToken(); 17531e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Failed = false; 175482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 17551e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Inferred modules must be submodules. 175682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!ActiveModule && !Framework) { 17571e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 17581e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Failed = true; 17591e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 176082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 176182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 176282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Inferred modules must have umbrella directories. 176382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Failed && !ActiveModule->getUmbrellaDir()) { 176482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 176582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Failed = true; 176682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 176782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 176882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check for redefinition of an inferred module. 176982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Failed && ActiveModule->InferSubmodules) { 177082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 177182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule->InferredSubmoduleLoc.isValid()) 177282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(ActiveModule->InferredSubmoduleLoc, 177382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor diag::note_mmap_prev_definition); 177482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Failed = true; 177582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 177682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 177782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check for the 'framework' keyword, which is not permitted here. 177882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Framework) { 177982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 178082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Framework = false; 178182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 178282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } else if (Explicit) { 178382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 178482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Explicit = false; 17851e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 178682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 17871e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // If there were any problems with this inferred submodule, skip its body. 17881e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Failed) { 17891e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::LBrace)) { 17901e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 17911e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor skipUntil(MMToken::RBrace); 17921e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 17931e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 17941e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 17951e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 17961e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 17971e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 179882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 179982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Parse optional attributes. 1800ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling Attributes Attrs; 180182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor parseOptionalAttributes(Attrs); 180282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 180382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 180482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Note that we have an inferred submodule. 180582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferSubmodules = true; 180682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferredSubmoduleLoc = StarLoc; 180782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor ActiveModule->InferExplicitSubmodules = Explicit; 180882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } else { 180982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // We'll be inferring framework modules for this directory. 181082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].InferModules = true; 181182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; 181282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 181382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 18141e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the opening brace. 18151e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (!Tok.is(MMToken::LBrace)) { 18161e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 18171e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 18181e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor return; 18191e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 18201e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor SourceLocation LBraceLoc = consumeToken(); 18211e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 18221e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor // Parse the body of the inferred submodule. 18231e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor bool Done = false; 18241e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor do { 18251e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor switch (Tok.Kind) { 18261e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::EndOfFile: 18271e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::RBrace: 18281e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Done = true; 18291e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 183082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 183182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case MMToken::ExcludeKeyword: { 183282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (ActiveModule) { 183382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1834b7ac5ac3faf70146707683a2ae041e8d53c3562aDouglas Gregor << (ActiveModule != 0); 183582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 183682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 183782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 183882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 183982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 184082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::Identifier)) { 184182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 184282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 184382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 184482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 184582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Map.InferredDirectories[Directory].ExcludedModules 184682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .push_back(Tok.getString()); 184782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 184882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 184982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 185082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 185182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case MMToken::ExportKeyword: 185282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!ActiveModule) { 185382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1854b7ac5ac3faf70146707683a2ae041e8d53c3562aDouglas Gregor << (ActiveModule != 0); 185582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 185682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 185782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 185882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 18591e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 18601e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::Star)) 1861ef85b56bfee855823756a6f46ee50a8c7cc5f3a6Douglas Gregor ActiveModule->InferExportWildcard = true; 18621e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else 18631e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), 18641e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor diag::err_mmap_expected_export_wildcard); 18651e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 18661e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 186782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 18681e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ExplicitKeyword: 18691e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::ModuleKeyword: 18701e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::HeaderKeyword: 1871bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: 18721e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor case MMToken::UmbrellaKeyword: 18731e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor default: 187482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 1875b7ac5ac3faf70146707683a2ae041e8d53c3562aDouglas Gregor << (ActiveModule != 0); 18761e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 18771e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor break; 18781e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 18791e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } while (!Done); 18801e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 18811e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor if (Tok.is(MMToken::RBrace)) 18821e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor consumeToken(); 18831e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor else { 18841e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 18851e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 18861e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor HadError = true; 18871e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor } 18881e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor} 18891e12368db12005ddd92fd9188c86383fe30ef443Douglas Gregor 189082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \brief Parse optional attributes. 189182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 189282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attributes: 189382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute attributes 189482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute 189582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 189682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// attribute: 189782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// [ identifier ] 189882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 189982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \param Attrs Will be filled in with the parsed attributes. 190082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// 190182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor/// \returns true if an error occurred, false otherwise. 1902ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendlingbool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 190382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor bool HadError = false; 190482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 190582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor while (Tok.is(MMToken::LSquare)) { 190682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Consume the '['. 190782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor SourceLocation LSquareLoc = consumeToken(); 190882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 190982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Check whether we have an attribute name here. 191082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::Identifier)) { 191182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 191282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor skipUntil(MMToken::RSquare); 191382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Tok.is(MMToken::RSquare)) 191482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 191582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor HadError = true; 191682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 191782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 191882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Decode the attribute name. 191982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor AttributeKind Attribute 192082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor = llvm::StringSwitch<AttributeKind>(Tok.getString()) 192163a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor .Case("exhaustive", AT_exhaustive) 192282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .Case("system", AT_system) 192382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor .Default(AT_unknown); 192482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor switch (Attribute) { 192582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case AT_unknown: 192682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 192782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor << Tok.getString(); 192882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 192982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 193082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor case AT_system: 193182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Attrs.IsSystem = true; 193282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor break; 193363a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor 193463a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case AT_exhaustive: 193563a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor Attrs.IsExhaustive = true; 193663a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor break; 193782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 193882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 193982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 194082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor // Consume the ']'. 194182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (!Tok.is(MMToken::RSquare)) { 194282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 194382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 194482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor skipUntil(MMToken::RSquare); 194582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor HadError = true; 194682e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 194782e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 194882e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor if (Tok.is(MMToken::RSquare)) 194982e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor consumeToken(); 195082e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor } 195182e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 195282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor return HadError; 195382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor} 195482e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 19556a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor/// \brief If there is a specific header search directory due the presence 19566a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor/// of an umbrella directory, retrieve that directory. Otherwise, returns null. 19576a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregorconst DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() { 19586a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) { 19596a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor // If we have an umbrella directory, use that. 19606a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor if (Mod->hasUmbrellaDir()) 19616a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor return Mod->getUmbrellaDir(); 19626a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor 19636a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor // If we have a framework directory, stop looking. 19646a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor if (Mod->IsFramework) 19656a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor return 0; 19666a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor } 19676a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor 19686a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor return 0; 19696a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor} 19706a1db484f32eb791840dd55a8d45c86ff5bd0834Douglas Gregor 1971a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// \brief Parse a module map file. 1972a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// 1973a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-map-file: 1974a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor/// module-declaration* 1975a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool ModuleMapParser::parseModuleMapFile() { 1976a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1977a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor switch (Tok.Kind) { 1978a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::EndOfFile: 1979a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return HadError; 1980a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1981587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor case MMToken::ExplicitKeyword: 19825f0a3524d184f7fcda856aaa17686064e45cacd3Daniel Jasper case MMToken::ExternKeyword: 1983a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::ModuleKeyword: 1984a865405e4155e8ea83d7ff1a1d8316907c300897Douglas Gregor case MMToken::FrameworkKeyword: 1985a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor parseModuleDecl(); 1986a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 1987b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor 198851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::Comma: 198963a726870b486e0470c3a4b11cf62bab8be00b73Douglas Gregor case MMToken::ConfigMacros: 1990906d66acc5cf2679453e10a4f0a67feedd765b21Douglas Gregor case MMToken::Conflict: 19912b49d1f0ad790a8a5d514af1be211591a746cb73Douglas Gregor case MMToken::ExcludeKeyword: 199290db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::ExportKeyword: 1993a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::HeaderKeyword: 1994a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::Identifier: 1995a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::LBrace: 1996b6cbe517237c3c223beb064d60d5b49e56d65c06Douglas Gregor case MMToken::LinkKeyword: 1997a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::LSquare: 199890db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Period: 1999bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl case MMToken::PrivateKeyword: 2000a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::RBrace: 2001a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor case MMToken::RSquare: 200251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor case MMToken::RequiresKeyword: 200390db26000aefe9335370013eec64c85232d80227Douglas Gregor case MMToken::Star: 2004a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::StringLiteral: 2005a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor case MMToken::UmbrellaKeyword: 2006a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2007a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor HadError = true; 2008a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor consumeToken(); 2009a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor break; 2010a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 2011a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 2012a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 2013a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 20148f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregorbool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { 20157005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor llvm::DenseMap<const FileEntry *, bool>::iterator Known 20167005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor = ParsedModuleMap.find(File); 20177005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (Known != ParsedModuleMap.end()) 20187005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return Known->second; 20197005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 2020dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor assert(Target != 0 && "Missing target information"); 2021a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 2022a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 2023a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Buffer) 20247005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return ParsedModuleMap[File] = true; 2025a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2026a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Parse this module map file. 202751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts); 202851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor Diags->getClient()->BeginSourceFile(MMapLangOpts); 20299a022bb007a3e77e1ac1330f955a239cfb1dd0fbDouglas Gregor ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(), 20308f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor BuiltinIncludeDir, IsSystem); 2031a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor bool Result = Parser.parseModuleMapFile(); 2032a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor Diags->getClient()->EndSourceFile(); 20337005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor ParsedModuleMap[File] = Result; 2034a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return Result; 2035a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 2036