1*7330f729Sjoerg //===- ModuleMap.cpp - Describe the layout of modules ---------------------===// 2*7330f729Sjoerg // 3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*7330f729Sjoerg // 7*7330f729Sjoerg //===----------------------------------------------------------------------===// 8*7330f729Sjoerg // 9*7330f729Sjoerg // This file defines the ModuleMap implementation, which describes the layout 10*7330f729Sjoerg // of a module as it relates to headers. 11*7330f729Sjoerg // 12*7330f729Sjoerg //===----------------------------------------------------------------------===// 13*7330f729Sjoerg 14*7330f729Sjoerg #include "clang/Lex/ModuleMap.h" 15*7330f729Sjoerg #include "clang/Basic/CharInfo.h" 16*7330f729Sjoerg #include "clang/Basic/Diagnostic.h" 17*7330f729Sjoerg #include "clang/Basic/FileManager.h" 18*7330f729Sjoerg #include "clang/Basic/LLVM.h" 19*7330f729Sjoerg #include "clang/Basic/LangOptions.h" 20*7330f729Sjoerg #include "clang/Basic/Module.h" 21*7330f729Sjoerg #include "clang/Basic/SourceLocation.h" 22*7330f729Sjoerg #include "clang/Basic/SourceManager.h" 23*7330f729Sjoerg #include "clang/Basic/TargetInfo.h" 24*7330f729Sjoerg #include "clang/Lex/HeaderSearch.h" 25*7330f729Sjoerg #include "clang/Lex/HeaderSearchOptions.h" 26*7330f729Sjoerg #include "clang/Lex/LexDiagnostic.h" 27*7330f729Sjoerg #include "clang/Lex/Lexer.h" 28*7330f729Sjoerg #include "clang/Lex/LiteralSupport.h" 29*7330f729Sjoerg #include "clang/Lex/Token.h" 30*7330f729Sjoerg #include "llvm/ADT/DenseMap.h" 31*7330f729Sjoerg #include "llvm/ADT/None.h" 32*7330f729Sjoerg #include "llvm/ADT/STLExtras.h" 33*7330f729Sjoerg #include "llvm/ADT/SmallPtrSet.h" 34*7330f729Sjoerg #include "llvm/ADT/SmallString.h" 35*7330f729Sjoerg #include "llvm/ADT/SmallVector.h" 36*7330f729Sjoerg #include "llvm/ADT/StringMap.h" 37*7330f729Sjoerg #include "llvm/ADT/StringRef.h" 38*7330f729Sjoerg #include "llvm/ADT/StringSwitch.h" 39*7330f729Sjoerg #include "llvm/Support/Allocator.h" 40*7330f729Sjoerg #include "llvm/Support/Compiler.h" 41*7330f729Sjoerg #include "llvm/Support/ErrorHandling.h" 42*7330f729Sjoerg #include "llvm/Support/MemoryBuffer.h" 43*7330f729Sjoerg #include "llvm/Support/Path.h" 44*7330f729Sjoerg #include "llvm/Support/VirtualFileSystem.h" 45*7330f729Sjoerg #include "llvm/Support/raw_ostream.h" 46*7330f729Sjoerg #include <algorithm> 47*7330f729Sjoerg #include <cassert> 48*7330f729Sjoerg #include <cstdint> 49*7330f729Sjoerg #include <cstring> 50*7330f729Sjoerg #include <string> 51*7330f729Sjoerg #include <system_error> 52*7330f729Sjoerg #include <utility> 53*7330f729Sjoerg 54*7330f729Sjoerg using namespace clang; 55*7330f729Sjoerg 56*7330f729Sjoerg void ModuleMapCallbacks::anchor() {} 57*7330f729Sjoerg 58*7330f729Sjoerg void ModuleMap::resolveLinkAsDependencies(Module *Mod) { 59*7330f729Sjoerg auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name); 60*7330f729Sjoerg if (PendingLinkAs != PendingLinkAsModule.end()) { 61*7330f729Sjoerg for (auto &Name : PendingLinkAs->second) { 62*7330f729Sjoerg auto *M = findModule(Name.getKey()); 63*7330f729Sjoerg if (M) 64*7330f729Sjoerg M->UseExportAsModuleLinkName = true; 65*7330f729Sjoerg } 66*7330f729Sjoerg } 67*7330f729Sjoerg } 68*7330f729Sjoerg 69*7330f729Sjoerg void ModuleMap::addLinkAsDependency(Module *Mod) { 70*7330f729Sjoerg if (findModule(Mod->ExportAsModule)) 71*7330f729Sjoerg Mod->UseExportAsModuleLinkName = true; 72*7330f729Sjoerg else 73*7330f729Sjoerg PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name); 74*7330f729Sjoerg } 75*7330f729Sjoerg 76*7330f729Sjoerg Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) { 77*7330f729Sjoerg switch ((int)Role) { 78*7330f729Sjoerg default: llvm_unreachable("unknown header role"); 79*7330f729Sjoerg case NormalHeader: 80*7330f729Sjoerg return Module::HK_Normal; 81*7330f729Sjoerg case PrivateHeader: 82*7330f729Sjoerg return Module::HK_Private; 83*7330f729Sjoerg case TextualHeader: 84*7330f729Sjoerg return Module::HK_Textual; 85*7330f729Sjoerg case PrivateHeader | TextualHeader: 86*7330f729Sjoerg return Module::HK_PrivateTextual; 87*7330f729Sjoerg } 88*7330f729Sjoerg } 89*7330f729Sjoerg 90*7330f729Sjoerg ModuleMap::ModuleHeaderRole 91*7330f729Sjoerg ModuleMap::headerKindToRole(Module::HeaderKind Kind) { 92*7330f729Sjoerg switch ((int)Kind) { 93*7330f729Sjoerg case Module::HK_Normal: 94*7330f729Sjoerg return NormalHeader; 95*7330f729Sjoerg case Module::HK_Private: 96*7330f729Sjoerg return PrivateHeader; 97*7330f729Sjoerg case Module::HK_Textual: 98*7330f729Sjoerg return TextualHeader; 99*7330f729Sjoerg case Module::HK_PrivateTextual: 100*7330f729Sjoerg return ModuleHeaderRole(PrivateHeader | TextualHeader); 101*7330f729Sjoerg case Module::HK_Excluded: 102*7330f729Sjoerg llvm_unreachable("unexpected header kind"); 103*7330f729Sjoerg } 104*7330f729Sjoerg llvm_unreachable("unknown header kind"); 105*7330f729Sjoerg } 106*7330f729Sjoerg 107*7330f729Sjoerg Module::ExportDecl 108*7330f729Sjoerg ModuleMap::resolveExport(Module *Mod, 109*7330f729Sjoerg const Module::UnresolvedExportDecl &Unresolved, 110*7330f729Sjoerg bool Complain) const { 111*7330f729Sjoerg // We may have just a wildcard. 112*7330f729Sjoerg if (Unresolved.Id.empty()) { 113*7330f729Sjoerg assert(Unresolved.Wildcard && "Invalid unresolved export"); 114*7330f729Sjoerg return Module::ExportDecl(nullptr, true); 115*7330f729Sjoerg } 116*7330f729Sjoerg 117*7330f729Sjoerg // Resolve the module-id. 118*7330f729Sjoerg Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 119*7330f729Sjoerg if (!Context) 120*7330f729Sjoerg return {}; 121*7330f729Sjoerg 122*7330f729Sjoerg return Module::ExportDecl(Context, Unresolved.Wildcard); 123*7330f729Sjoerg } 124*7330f729Sjoerg 125*7330f729Sjoerg Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 126*7330f729Sjoerg bool Complain) const { 127*7330f729Sjoerg // Find the starting module. 128*7330f729Sjoerg Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 129*7330f729Sjoerg if (!Context) { 130*7330f729Sjoerg if (Complain) 131*7330f729Sjoerg Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 132*7330f729Sjoerg << Id[0].first << Mod->getFullModuleName(); 133*7330f729Sjoerg 134*7330f729Sjoerg return nullptr; 135*7330f729Sjoerg } 136*7330f729Sjoerg 137*7330f729Sjoerg // Dig into the module path. 138*7330f729Sjoerg for (unsigned I = 1, N = Id.size(); I != N; ++I) { 139*7330f729Sjoerg Module *Sub = lookupModuleQualified(Id[I].first, Context); 140*7330f729Sjoerg if (!Sub) { 141*7330f729Sjoerg if (Complain) 142*7330f729Sjoerg Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 143*7330f729Sjoerg << Id[I].first << Context->getFullModuleName() 144*7330f729Sjoerg << SourceRange(Id[0].second, Id[I-1].second); 145*7330f729Sjoerg 146*7330f729Sjoerg return nullptr; 147*7330f729Sjoerg } 148*7330f729Sjoerg 149*7330f729Sjoerg Context = Sub; 150*7330f729Sjoerg } 151*7330f729Sjoerg 152*7330f729Sjoerg return Context; 153*7330f729Sjoerg } 154*7330f729Sjoerg 155*7330f729Sjoerg /// Append to \p Paths the set of paths needed to get to the 156*7330f729Sjoerg /// subframework in which the given module lives. 157*7330f729Sjoerg static void appendSubframeworkPaths(Module *Mod, 158*7330f729Sjoerg SmallVectorImpl<char> &Path) { 159*7330f729Sjoerg // Collect the framework names from the given module to the top-level module. 160*7330f729Sjoerg SmallVector<StringRef, 2> Paths; 161*7330f729Sjoerg for (; Mod; Mod = Mod->Parent) { 162*7330f729Sjoerg if (Mod->IsFramework) 163*7330f729Sjoerg Paths.push_back(Mod->Name); 164*7330f729Sjoerg } 165*7330f729Sjoerg 166*7330f729Sjoerg if (Paths.empty()) 167*7330f729Sjoerg return; 168*7330f729Sjoerg 169*7330f729Sjoerg // Add Frameworks/Name.framework for each subframework. 170*7330f729Sjoerg for (unsigned I = Paths.size() - 1; I != 0; --I) 171*7330f729Sjoerg llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 172*7330f729Sjoerg } 173*7330f729Sjoerg 174*7330f729Sjoerg const FileEntry *ModuleMap::findHeader( 175*7330f729Sjoerg Module *M, const Module::UnresolvedHeaderDirective &Header, 176*7330f729Sjoerg SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) { 177*7330f729Sjoerg // Search for the header file within the module's home directory. 178*7330f729Sjoerg auto *Directory = M->Directory; 179*7330f729Sjoerg SmallString<128> FullPathName(Directory->getName()); 180*7330f729Sjoerg 181*7330f729Sjoerg auto GetFile = [&](StringRef Filename) -> const FileEntry * { 182*7330f729Sjoerg auto File = SourceMgr.getFileManager().getFile(Filename); 183*7330f729Sjoerg if (!File || 184*7330f729Sjoerg (Header.Size && (*File)->getSize() != *Header.Size) || 185*7330f729Sjoerg (Header.ModTime && (*File)->getModificationTime() != *Header.ModTime)) 186*7330f729Sjoerg return nullptr; 187*7330f729Sjoerg return *File; 188*7330f729Sjoerg }; 189*7330f729Sjoerg 190*7330f729Sjoerg auto GetFrameworkFile = [&]() -> const FileEntry * { 191*7330f729Sjoerg unsigned FullPathLength = FullPathName.size(); 192*7330f729Sjoerg appendSubframeworkPaths(M, RelativePathName); 193*7330f729Sjoerg unsigned RelativePathLength = RelativePathName.size(); 194*7330f729Sjoerg 195*7330f729Sjoerg // Check whether this file is in the public headers. 196*7330f729Sjoerg llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); 197*7330f729Sjoerg llvm::sys::path::append(FullPathName, RelativePathName); 198*7330f729Sjoerg if (auto *File = GetFile(FullPathName)) 199*7330f729Sjoerg return File; 200*7330f729Sjoerg 201*7330f729Sjoerg // Check whether this file is in the private headers. 202*7330f729Sjoerg // Ideally, private modules in the form 'FrameworkName.Private' should 203*7330f729Sjoerg // be defined as 'module FrameworkName.Private', and not as 204*7330f729Sjoerg // 'framework module FrameworkName.Private', since a 'Private.Framework' 205*7330f729Sjoerg // does not usually exist. However, since both are currently widely used 206*7330f729Sjoerg // for private modules, make sure we find the right path in both cases. 207*7330f729Sjoerg if (M->IsFramework && M->Name == "Private") 208*7330f729Sjoerg RelativePathName.clear(); 209*7330f729Sjoerg else 210*7330f729Sjoerg RelativePathName.resize(RelativePathLength); 211*7330f729Sjoerg FullPathName.resize(FullPathLength); 212*7330f729Sjoerg llvm::sys::path::append(RelativePathName, "PrivateHeaders", 213*7330f729Sjoerg Header.FileName); 214*7330f729Sjoerg llvm::sys::path::append(FullPathName, RelativePathName); 215*7330f729Sjoerg return GetFile(FullPathName); 216*7330f729Sjoerg }; 217*7330f729Sjoerg 218*7330f729Sjoerg if (llvm::sys::path::is_absolute(Header.FileName)) { 219*7330f729Sjoerg RelativePathName.clear(); 220*7330f729Sjoerg RelativePathName.append(Header.FileName.begin(), Header.FileName.end()); 221*7330f729Sjoerg return GetFile(Header.FileName); 222*7330f729Sjoerg } 223*7330f729Sjoerg 224*7330f729Sjoerg if (M->isPartOfFramework()) 225*7330f729Sjoerg return GetFrameworkFile(); 226*7330f729Sjoerg 227*7330f729Sjoerg // Lookup for normal headers. 228*7330f729Sjoerg llvm::sys::path::append(RelativePathName, Header.FileName); 229*7330f729Sjoerg llvm::sys::path::append(FullPathName, RelativePathName); 230*7330f729Sjoerg auto *NormalHdrFile = GetFile(FullPathName); 231*7330f729Sjoerg 232*7330f729Sjoerg if (M && !NormalHdrFile && Directory->getName().endswith(".framework")) { 233*7330f729Sjoerg // The lack of 'framework' keyword in a module declaration it's a simple 234*7330f729Sjoerg // mistake we can diagnose when the header exists within the proper 235*7330f729Sjoerg // framework style path. 236*7330f729Sjoerg FullPathName.assign(Directory->getName()); 237*7330f729Sjoerg RelativePathName.clear(); 238*7330f729Sjoerg if (GetFrameworkFile()) { 239*7330f729Sjoerg Diags.Report(Header.FileNameLoc, 240*7330f729Sjoerg diag::warn_mmap_incomplete_framework_module_declaration) 241*7330f729Sjoerg << Header.FileName << M->getFullModuleName(); 242*7330f729Sjoerg NeedsFramework = true; 243*7330f729Sjoerg } 244*7330f729Sjoerg return nullptr; 245*7330f729Sjoerg } 246*7330f729Sjoerg 247*7330f729Sjoerg return NormalHdrFile; 248*7330f729Sjoerg } 249*7330f729Sjoerg 250*7330f729Sjoerg void ModuleMap::resolveHeader(Module *Mod, 251*7330f729Sjoerg const Module::UnresolvedHeaderDirective &Header, 252*7330f729Sjoerg bool &NeedsFramework) { 253*7330f729Sjoerg SmallString<128> RelativePathName; 254*7330f729Sjoerg if (const FileEntry *File = 255*7330f729Sjoerg findHeader(Mod, Header, RelativePathName, NeedsFramework)) { 256*7330f729Sjoerg if (Header.IsUmbrella) { 257*7330f729Sjoerg const DirectoryEntry *UmbrellaDir = File->getDir(); 258*7330f729Sjoerg if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir]) 259*7330f729Sjoerg Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 260*7330f729Sjoerg << UmbrellaMod->getFullModuleName(); 261*7330f729Sjoerg else 262*7330f729Sjoerg // Record this umbrella header. 263*7330f729Sjoerg setUmbrellaHeader(Mod, File, RelativePathName.str()); 264*7330f729Sjoerg } else { 265*7330f729Sjoerg Module::Header H = {RelativePathName.str(), File}; 266*7330f729Sjoerg if (Header.Kind == Module::HK_Excluded) 267*7330f729Sjoerg excludeHeader(Mod, H); 268*7330f729Sjoerg else 269*7330f729Sjoerg addHeader(Mod, H, headerKindToRole(Header.Kind)); 270*7330f729Sjoerg } 271*7330f729Sjoerg } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) { 272*7330f729Sjoerg // There's a builtin header but no corresponding on-disk header. Assume 273*7330f729Sjoerg // this was supposed to modularize the builtin header alone. 274*7330f729Sjoerg } else if (Header.Kind == Module::HK_Excluded) { 275*7330f729Sjoerg // Ignore missing excluded header files. They're optional anyway. 276*7330f729Sjoerg } else { 277*7330f729Sjoerg // If we find a module that has a missing header, we mark this module as 278*7330f729Sjoerg // unavailable and store the header directive for displaying diagnostics. 279*7330f729Sjoerg Mod->MissingHeaders.push_back(Header); 280*7330f729Sjoerg // A missing header with stat information doesn't make the module 281*7330f729Sjoerg // unavailable; this keeps our behavior consistent as headers are lazily 282*7330f729Sjoerg // resolved. (Such a module still can't be built though, except from 283*7330f729Sjoerg // preprocessed source.) 284*7330f729Sjoerg if (!Header.Size && !Header.ModTime) 285*7330f729Sjoerg Mod->markUnavailable(); 286*7330f729Sjoerg } 287*7330f729Sjoerg } 288*7330f729Sjoerg 289*7330f729Sjoerg bool ModuleMap::resolveAsBuiltinHeader( 290*7330f729Sjoerg Module *Mod, const Module::UnresolvedHeaderDirective &Header) { 291*7330f729Sjoerg if (Header.Kind == Module::HK_Excluded || 292*7330f729Sjoerg llvm::sys::path::is_absolute(Header.FileName) || 293*7330f729Sjoerg Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella || 294*7330f729Sjoerg !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory || 295*7330f729Sjoerg !isBuiltinHeader(Header.FileName)) 296*7330f729Sjoerg return false; 297*7330f729Sjoerg 298*7330f729Sjoerg // This is a system module with a top-level header. This header 299*7330f729Sjoerg // may have a counterpart (or replacement) in the set of headers 300*7330f729Sjoerg // supplied by Clang. Find that builtin header. 301*7330f729Sjoerg SmallString<128> Path; 302*7330f729Sjoerg llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName); 303*7330f729Sjoerg auto File = SourceMgr.getFileManager().getFile(Path); 304*7330f729Sjoerg if (!File) 305*7330f729Sjoerg return false; 306*7330f729Sjoerg 307*7330f729Sjoerg auto Role = headerKindToRole(Header.Kind); 308*7330f729Sjoerg Module::Header H = {Path.str(), *File}; 309*7330f729Sjoerg addHeader(Mod, H, Role); 310*7330f729Sjoerg return true; 311*7330f729Sjoerg } 312*7330f729Sjoerg 313*7330f729Sjoerg ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 314*7330f729Sjoerg const LangOptions &LangOpts, const TargetInfo *Target, 315*7330f729Sjoerg HeaderSearch &HeaderInfo) 316*7330f729Sjoerg : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 317*7330f729Sjoerg HeaderInfo(HeaderInfo) { 318*7330f729Sjoerg MMapLangOpts.LineComment = true; 319*7330f729Sjoerg } 320*7330f729Sjoerg 321*7330f729Sjoerg ModuleMap::~ModuleMap() { 322*7330f729Sjoerg for (auto &M : Modules) 323*7330f729Sjoerg delete M.getValue(); 324*7330f729Sjoerg for (auto *M : ShadowModules) 325*7330f729Sjoerg delete M; 326*7330f729Sjoerg } 327*7330f729Sjoerg 328*7330f729Sjoerg void ModuleMap::setTarget(const TargetInfo &Target) { 329*7330f729Sjoerg assert((!this->Target || this->Target == &Target) && 330*7330f729Sjoerg "Improper target override"); 331*7330f729Sjoerg this->Target = &Target; 332*7330f729Sjoerg } 333*7330f729Sjoerg 334*7330f729Sjoerg /// "Sanitize" a filename so that it can be used as an identifier. 335*7330f729Sjoerg static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 336*7330f729Sjoerg SmallVectorImpl<char> &Buffer) { 337*7330f729Sjoerg if (Name.empty()) 338*7330f729Sjoerg return Name; 339*7330f729Sjoerg 340*7330f729Sjoerg if (!isValidIdentifier(Name)) { 341*7330f729Sjoerg // If we don't already have something with the form of an identifier, 342*7330f729Sjoerg // create a buffer with the sanitized name. 343*7330f729Sjoerg Buffer.clear(); 344*7330f729Sjoerg if (isDigit(Name[0])) 345*7330f729Sjoerg Buffer.push_back('_'); 346*7330f729Sjoerg Buffer.reserve(Buffer.size() + Name.size()); 347*7330f729Sjoerg for (unsigned I = 0, N = Name.size(); I != N; ++I) { 348*7330f729Sjoerg if (isIdentifierBody(Name[I])) 349*7330f729Sjoerg Buffer.push_back(Name[I]); 350*7330f729Sjoerg else 351*7330f729Sjoerg Buffer.push_back('_'); 352*7330f729Sjoerg } 353*7330f729Sjoerg 354*7330f729Sjoerg Name = StringRef(Buffer.data(), Buffer.size()); 355*7330f729Sjoerg } 356*7330f729Sjoerg 357*7330f729Sjoerg while (llvm::StringSwitch<bool>(Name) 358*7330f729Sjoerg #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 359*7330f729Sjoerg #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 360*7330f729Sjoerg #include "clang/Basic/TokenKinds.def" 361*7330f729Sjoerg .Default(false)) { 362*7330f729Sjoerg if (Name.data() != Buffer.data()) 363*7330f729Sjoerg Buffer.append(Name.begin(), Name.end()); 364*7330f729Sjoerg Buffer.push_back('_'); 365*7330f729Sjoerg Name = StringRef(Buffer.data(), Buffer.size()); 366*7330f729Sjoerg } 367*7330f729Sjoerg 368*7330f729Sjoerg return Name; 369*7330f729Sjoerg } 370*7330f729Sjoerg 371*7330f729Sjoerg /// Determine whether the given file name is the name of a builtin 372*7330f729Sjoerg /// header, supplied by Clang to replace, override, or augment existing system 373*7330f729Sjoerg /// headers. 374*7330f729Sjoerg bool ModuleMap::isBuiltinHeader(StringRef FileName) { 375*7330f729Sjoerg return llvm::StringSwitch<bool>(FileName) 376*7330f729Sjoerg .Case("float.h", true) 377*7330f729Sjoerg .Case("iso646.h", true) 378*7330f729Sjoerg .Case("limits.h", true) 379*7330f729Sjoerg .Case("stdalign.h", true) 380*7330f729Sjoerg .Case("stdarg.h", true) 381*7330f729Sjoerg .Case("stdatomic.h", true) 382*7330f729Sjoerg .Case("stdbool.h", true) 383*7330f729Sjoerg .Case("stddef.h", true) 384*7330f729Sjoerg .Case("stdint.h", true) 385*7330f729Sjoerg .Case("tgmath.h", true) 386*7330f729Sjoerg .Case("unwind.h", true) 387*7330f729Sjoerg .Default(false); 388*7330f729Sjoerg } 389*7330f729Sjoerg 390*7330f729Sjoerg ModuleMap::HeadersMap::iterator 391*7330f729Sjoerg ModuleMap::findKnownHeader(const FileEntry *File) { 392*7330f729Sjoerg resolveHeaderDirectives(File); 393*7330f729Sjoerg HeadersMap::iterator Known = Headers.find(File); 394*7330f729Sjoerg if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && 395*7330f729Sjoerg Known == Headers.end() && File->getDir() == BuiltinIncludeDir && 396*7330f729Sjoerg ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 397*7330f729Sjoerg HeaderInfo.loadTopLevelSystemModules(); 398*7330f729Sjoerg return Headers.find(File); 399*7330f729Sjoerg } 400*7330f729Sjoerg return Known; 401*7330f729Sjoerg } 402*7330f729Sjoerg 403*7330f729Sjoerg ModuleMap::KnownHeader 404*7330f729Sjoerg ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, 405*7330f729Sjoerg SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { 406*7330f729Sjoerg if (UmbrellaDirs.empty()) 407*7330f729Sjoerg return {}; 408*7330f729Sjoerg 409*7330f729Sjoerg const DirectoryEntry *Dir = File->getDir(); 410*7330f729Sjoerg assert(Dir && "file in no directory"); 411*7330f729Sjoerg 412*7330f729Sjoerg // Note: as an egregious but useful hack we use the real path here, because 413*7330f729Sjoerg // frameworks moving from top-level frameworks to embedded frameworks tend 414*7330f729Sjoerg // to be symlinked from the top-level location to the embedded location, 415*7330f729Sjoerg // and we need to resolve lookups as if we had found the embedded location. 416*7330f729Sjoerg StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 417*7330f729Sjoerg 418*7330f729Sjoerg // Keep walking up the directory hierarchy, looking for a directory with 419*7330f729Sjoerg // an umbrella header. 420*7330f729Sjoerg do { 421*7330f729Sjoerg auto KnownDir = UmbrellaDirs.find(Dir); 422*7330f729Sjoerg if (KnownDir != UmbrellaDirs.end()) 423*7330f729Sjoerg return KnownHeader(KnownDir->second, NormalHeader); 424*7330f729Sjoerg 425*7330f729Sjoerg IntermediateDirs.push_back(Dir); 426*7330f729Sjoerg 427*7330f729Sjoerg // Retrieve our parent path. 428*7330f729Sjoerg DirName = llvm::sys::path::parent_path(DirName); 429*7330f729Sjoerg if (DirName.empty()) 430*7330f729Sjoerg break; 431*7330f729Sjoerg 432*7330f729Sjoerg // Resolve the parent path to a directory entry. 433*7330f729Sjoerg if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName)) 434*7330f729Sjoerg Dir = *DirEntry; 435*7330f729Sjoerg else 436*7330f729Sjoerg Dir = nullptr; 437*7330f729Sjoerg } while (Dir); 438*7330f729Sjoerg return {}; 439*7330f729Sjoerg } 440*7330f729Sjoerg 441*7330f729Sjoerg static bool violatesPrivateInclude(Module *RequestingModule, 442*7330f729Sjoerg const FileEntry *IncFileEnt, 443*7330f729Sjoerg ModuleMap::KnownHeader Header) { 444*7330f729Sjoerg #ifndef NDEBUG 445*7330f729Sjoerg if (Header.getRole() & ModuleMap::PrivateHeader) { 446*7330f729Sjoerg // Check for consistency between the module header role 447*7330f729Sjoerg // as obtained from the lookup and as obtained from the module. 448*7330f729Sjoerg // This check is not cheap, so enable it only for debugging. 449*7330f729Sjoerg bool IsPrivate = false; 450*7330f729Sjoerg SmallVectorImpl<Module::Header> *HeaderList[] = { 451*7330f729Sjoerg &Header.getModule()->Headers[Module::HK_Private], 452*7330f729Sjoerg &Header.getModule()->Headers[Module::HK_PrivateTextual]}; 453*7330f729Sjoerg for (auto *Hs : HeaderList) 454*7330f729Sjoerg IsPrivate |= 455*7330f729Sjoerg std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) { 456*7330f729Sjoerg return H.Entry == IncFileEnt; 457*7330f729Sjoerg }) != Hs->end(); 458*7330f729Sjoerg assert(IsPrivate && "inconsistent headers and roles"); 459*7330f729Sjoerg } 460*7330f729Sjoerg #endif 461*7330f729Sjoerg return !Header.isAccessibleFrom(RequestingModule); 462*7330f729Sjoerg } 463*7330f729Sjoerg 464*7330f729Sjoerg static Module *getTopLevelOrNull(Module *M) { 465*7330f729Sjoerg return M ? M->getTopLevelModule() : nullptr; 466*7330f729Sjoerg } 467*7330f729Sjoerg 468*7330f729Sjoerg void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 469*7330f729Sjoerg bool RequestingModuleIsModuleInterface, 470*7330f729Sjoerg SourceLocation FilenameLoc, 471*7330f729Sjoerg StringRef Filename, 472*7330f729Sjoerg const FileEntry *File) { 473*7330f729Sjoerg // No errors for indirect modules. This may be a bit of a problem for modules 474*7330f729Sjoerg // with no source files. 475*7330f729Sjoerg if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) 476*7330f729Sjoerg return; 477*7330f729Sjoerg 478*7330f729Sjoerg if (RequestingModule) { 479*7330f729Sjoerg resolveUses(RequestingModule, /*Complain=*/false); 480*7330f729Sjoerg resolveHeaderDirectives(RequestingModule); 481*7330f729Sjoerg } 482*7330f729Sjoerg 483*7330f729Sjoerg bool Excluded = false; 484*7330f729Sjoerg Module *Private = nullptr; 485*7330f729Sjoerg Module *NotUsed = nullptr; 486*7330f729Sjoerg 487*7330f729Sjoerg HeadersMap::iterator Known = findKnownHeader(File); 488*7330f729Sjoerg if (Known != Headers.end()) { 489*7330f729Sjoerg for (const KnownHeader &Header : Known->second) { 490*7330f729Sjoerg // Remember private headers for later printing of a diagnostic. 491*7330f729Sjoerg if (violatesPrivateInclude(RequestingModule, File, Header)) { 492*7330f729Sjoerg Private = Header.getModule(); 493*7330f729Sjoerg continue; 494*7330f729Sjoerg } 495*7330f729Sjoerg 496*7330f729Sjoerg // If uses need to be specified explicitly, we are only allowed to return 497*7330f729Sjoerg // modules that are explicitly used by the requesting module. 498*7330f729Sjoerg if (RequestingModule && LangOpts.ModulesDeclUse && 499*7330f729Sjoerg !RequestingModule->directlyUses(Header.getModule())) { 500*7330f729Sjoerg NotUsed = Header.getModule(); 501*7330f729Sjoerg continue; 502*7330f729Sjoerg } 503*7330f729Sjoerg 504*7330f729Sjoerg // We have found a module that we can happily use. 505*7330f729Sjoerg return; 506*7330f729Sjoerg } 507*7330f729Sjoerg 508*7330f729Sjoerg Excluded = true; 509*7330f729Sjoerg } 510*7330f729Sjoerg 511*7330f729Sjoerg // We have found a header, but it is private. 512*7330f729Sjoerg if (Private) { 513*7330f729Sjoerg Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module) 514*7330f729Sjoerg << Filename; 515*7330f729Sjoerg return; 516*7330f729Sjoerg } 517*7330f729Sjoerg 518*7330f729Sjoerg // We have found a module, but we don't use it. 519*7330f729Sjoerg if (NotUsed) { 520*7330f729Sjoerg Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 521*7330f729Sjoerg << RequestingModule->getTopLevelModule()->Name << Filename; 522*7330f729Sjoerg return; 523*7330f729Sjoerg } 524*7330f729Sjoerg 525*7330f729Sjoerg if (Excluded || isHeaderInUmbrellaDirs(File)) 526*7330f729Sjoerg return; 527*7330f729Sjoerg 528*7330f729Sjoerg // At this point, only non-modular includes remain. 529*7330f729Sjoerg 530*7330f729Sjoerg if (RequestingModule && LangOpts.ModulesStrictDeclUse) { 531*7330f729Sjoerg Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 532*7330f729Sjoerg << RequestingModule->getTopLevelModule()->Name << Filename; 533*7330f729Sjoerg } else if (RequestingModule && RequestingModuleIsModuleInterface && 534*7330f729Sjoerg LangOpts.isCompilingModule()) { 535*7330f729Sjoerg // Do not diagnose when we are not compiling a module. 536*7330f729Sjoerg diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? 537*7330f729Sjoerg diag::warn_non_modular_include_in_framework_module : 538*7330f729Sjoerg diag::warn_non_modular_include_in_module; 539*7330f729Sjoerg Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName() 540*7330f729Sjoerg << File->getName(); 541*7330f729Sjoerg } 542*7330f729Sjoerg } 543*7330f729Sjoerg 544*7330f729Sjoerg static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, 545*7330f729Sjoerg const ModuleMap::KnownHeader &Old) { 546*7330f729Sjoerg // Prefer available modules. 547*7330f729Sjoerg if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable()) 548*7330f729Sjoerg return true; 549*7330f729Sjoerg 550*7330f729Sjoerg // Prefer a public header over a private header. 551*7330f729Sjoerg if ((New.getRole() & ModuleMap::PrivateHeader) != 552*7330f729Sjoerg (Old.getRole() & ModuleMap::PrivateHeader)) 553*7330f729Sjoerg return !(New.getRole() & ModuleMap::PrivateHeader); 554*7330f729Sjoerg 555*7330f729Sjoerg // Prefer a non-textual header over a textual header. 556*7330f729Sjoerg if ((New.getRole() & ModuleMap::TextualHeader) != 557*7330f729Sjoerg (Old.getRole() & ModuleMap::TextualHeader)) 558*7330f729Sjoerg return !(New.getRole() & ModuleMap::TextualHeader); 559*7330f729Sjoerg 560*7330f729Sjoerg // Don't have a reason to choose between these. Just keep the first one. 561*7330f729Sjoerg return false; 562*7330f729Sjoerg } 563*7330f729Sjoerg 564*7330f729Sjoerg ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, 565*7330f729Sjoerg bool AllowTextual) { 566*7330f729Sjoerg auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { 567*7330f729Sjoerg if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader) 568*7330f729Sjoerg return {}; 569*7330f729Sjoerg return R; 570*7330f729Sjoerg }; 571*7330f729Sjoerg 572*7330f729Sjoerg HeadersMap::iterator Known = findKnownHeader(File); 573*7330f729Sjoerg if (Known != Headers.end()) { 574*7330f729Sjoerg ModuleMap::KnownHeader Result; 575*7330f729Sjoerg // Iterate over all modules that 'File' is part of to find the best fit. 576*7330f729Sjoerg for (KnownHeader &H : Known->second) { 577*7330f729Sjoerg // Prefer a header from the source module over all others. 578*7330f729Sjoerg if (H.getModule()->getTopLevelModule() == SourceModule) 579*7330f729Sjoerg return MakeResult(H); 580*7330f729Sjoerg if (!Result || isBetterKnownHeader(H, Result)) 581*7330f729Sjoerg Result = H; 582*7330f729Sjoerg } 583*7330f729Sjoerg return MakeResult(Result); 584*7330f729Sjoerg } 585*7330f729Sjoerg 586*7330f729Sjoerg return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File)); 587*7330f729Sjoerg } 588*7330f729Sjoerg 589*7330f729Sjoerg ModuleMap::KnownHeader 590*7330f729Sjoerg ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) { 591*7330f729Sjoerg assert(!Headers.count(File) && "already have a module for this header"); 592*7330f729Sjoerg 593*7330f729Sjoerg SmallVector<const DirectoryEntry *, 2> SkippedDirs; 594*7330f729Sjoerg KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); 595*7330f729Sjoerg if (H) { 596*7330f729Sjoerg Module *Result = H.getModule(); 597*7330f729Sjoerg 598*7330f729Sjoerg // Search up the module stack until we find a module with an umbrella 599*7330f729Sjoerg // directory. 600*7330f729Sjoerg Module *UmbrellaModule = Result; 601*7330f729Sjoerg while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 602*7330f729Sjoerg UmbrellaModule = UmbrellaModule->Parent; 603*7330f729Sjoerg 604*7330f729Sjoerg if (UmbrellaModule->InferSubmodules) { 605*7330f729Sjoerg const FileEntry *UmbrellaModuleMap = 606*7330f729Sjoerg getModuleMapFileForUniquing(UmbrellaModule); 607*7330f729Sjoerg 608*7330f729Sjoerg // Infer submodules for each of the directories we found between 609*7330f729Sjoerg // the directory of the umbrella header and the directory where 610*7330f729Sjoerg // the actual header is located. 611*7330f729Sjoerg bool Explicit = UmbrellaModule->InferExplicitSubmodules; 612*7330f729Sjoerg 613*7330f729Sjoerg for (unsigned I = SkippedDirs.size(); I != 0; --I) { 614*7330f729Sjoerg // Find or create the module that corresponds to this directory name. 615*7330f729Sjoerg SmallString<32> NameBuf; 616*7330f729Sjoerg StringRef Name = sanitizeFilenameAsIdentifier( 617*7330f729Sjoerg llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf); 618*7330f729Sjoerg Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 619*7330f729Sjoerg Explicit).first; 620*7330f729Sjoerg InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 621*7330f729Sjoerg Result->IsInferred = true; 622*7330f729Sjoerg 623*7330f729Sjoerg // Associate the module and the directory. 624*7330f729Sjoerg UmbrellaDirs[SkippedDirs[I-1]] = Result; 625*7330f729Sjoerg 626*7330f729Sjoerg // If inferred submodules export everything they import, add a 627*7330f729Sjoerg // wildcard to the set of exports. 628*7330f729Sjoerg if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 629*7330f729Sjoerg Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 630*7330f729Sjoerg } 631*7330f729Sjoerg 632*7330f729Sjoerg // Infer a submodule with the same name as this header file. 633*7330f729Sjoerg SmallString<32> NameBuf; 634*7330f729Sjoerg StringRef Name = sanitizeFilenameAsIdentifier( 635*7330f729Sjoerg llvm::sys::path::stem(File->getName()), NameBuf); 636*7330f729Sjoerg Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 637*7330f729Sjoerg Explicit).first; 638*7330f729Sjoerg InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 639*7330f729Sjoerg Result->IsInferred = true; 640*7330f729Sjoerg Result->addTopHeader(File); 641*7330f729Sjoerg 642*7330f729Sjoerg // If inferred submodules export everything they import, add a 643*7330f729Sjoerg // wildcard to the set of exports. 644*7330f729Sjoerg if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 645*7330f729Sjoerg Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 646*7330f729Sjoerg } else { 647*7330f729Sjoerg // Record each of the directories we stepped through as being part of 648*7330f729Sjoerg // the module we found, since the umbrella header covers them all. 649*7330f729Sjoerg for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 650*7330f729Sjoerg UmbrellaDirs[SkippedDirs[I]] = Result; 651*7330f729Sjoerg } 652*7330f729Sjoerg 653*7330f729Sjoerg KnownHeader Header(Result, NormalHeader); 654*7330f729Sjoerg Headers[File].push_back(Header); 655*7330f729Sjoerg return Header; 656*7330f729Sjoerg } 657*7330f729Sjoerg 658*7330f729Sjoerg return {}; 659*7330f729Sjoerg } 660*7330f729Sjoerg 661*7330f729Sjoerg ArrayRef<ModuleMap::KnownHeader> 662*7330f729Sjoerg ModuleMap::findAllModulesForHeader(const FileEntry *File) const { 663*7330f729Sjoerg resolveHeaderDirectives(File); 664*7330f729Sjoerg auto It = Headers.find(File); 665*7330f729Sjoerg if (It == Headers.end()) 666*7330f729Sjoerg return None; 667*7330f729Sjoerg return It->second; 668*7330f729Sjoerg } 669*7330f729Sjoerg 670*7330f729Sjoerg bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 671*7330f729Sjoerg return isHeaderUnavailableInModule(Header, nullptr); 672*7330f729Sjoerg } 673*7330f729Sjoerg 674*7330f729Sjoerg bool 675*7330f729Sjoerg ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, 676*7330f729Sjoerg const Module *RequestingModule) const { 677*7330f729Sjoerg resolveHeaderDirectives(Header); 678*7330f729Sjoerg HeadersMap::const_iterator Known = Headers.find(Header); 679*7330f729Sjoerg if (Known != Headers.end()) { 680*7330f729Sjoerg for (SmallVectorImpl<KnownHeader>::const_iterator 681*7330f729Sjoerg I = Known->second.begin(), 682*7330f729Sjoerg E = Known->second.end(); 683*7330f729Sjoerg I != E; ++I) { 684*7330f729Sjoerg 685*7330f729Sjoerg if (I->isAvailable() && 686*7330f729Sjoerg (!RequestingModule || 687*7330f729Sjoerg I->getModule()->isSubModuleOf(RequestingModule))) { 688*7330f729Sjoerg // When no requesting module is available, the caller is looking if a 689*7330f729Sjoerg // header is part a module by only looking into the module map. This is 690*7330f729Sjoerg // done by warn_uncovered_module_header checks; don't consider textual 691*7330f729Sjoerg // headers part of it in this mode, otherwise we get misleading warnings 692*7330f729Sjoerg // that a umbrella header is not including a textual header. 693*7330f729Sjoerg if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader) 694*7330f729Sjoerg continue; 695*7330f729Sjoerg return false; 696*7330f729Sjoerg } 697*7330f729Sjoerg } 698*7330f729Sjoerg return true; 699*7330f729Sjoerg } 700*7330f729Sjoerg 701*7330f729Sjoerg const DirectoryEntry *Dir = Header->getDir(); 702*7330f729Sjoerg SmallVector<const DirectoryEntry *, 2> SkippedDirs; 703*7330f729Sjoerg StringRef DirName = Dir->getName(); 704*7330f729Sjoerg 705*7330f729Sjoerg auto IsUnavailable = [&](const Module *M) { 706*7330f729Sjoerg return !M->isAvailable() && (!RequestingModule || 707*7330f729Sjoerg M->isSubModuleOf(RequestingModule)); 708*7330f729Sjoerg }; 709*7330f729Sjoerg 710*7330f729Sjoerg // Keep walking up the directory hierarchy, looking for a directory with 711*7330f729Sjoerg // an umbrella header. 712*7330f729Sjoerg do { 713*7330f729Sjoerg llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 714*7330f729Sjoerg = UmbrellaDirs.find(Dir); 715*7330f729Sjoerg if (KnownDir != UmbrellaDirs.end()) { 716*7330f729Sjoerg Module *Found = KnownDir->second; 717*7330f729Sjoerg if (IsUnavailable(Found)) 718*7330f729Sjoerg return true; 719*7330f729Sjoerg 720*7330f729Sjoerg // Search up the module stack until we find a module with an umbrella 721*7330f729Sjoerg // directory. 722*7330f729Sjoerg Module *UmbrellaModule = Found; 723*7330f729Sjoerg while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 724*7330f729Sjoerg UmbrellaModule = UmbrellaModule->Parent; 725*7330f729Sjoerg 726*7330f729Sjoerg if (UmbrellaModule->InferSubmodules) { 727*7330f729Sjoerg for (unsigned I = SkippedDirs.size(); I != 0; --I) { 728*7330f729Sjoerg // Find or create the module that corresponds to this directory name. 729*7330f729Sjoerg SmallString<32> NameBuf; 730*7330f729Sjoerg StringRef Name = sanitizeFilenameAsIdentifier( 731*7330f729Sjoerg llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 732*7330f729Sjoerg NameBuf); 733*7330f729Sjoerg Found = lookupModuleQualified(Name, Found); 734*7330f729Sjoerg if (!Found) 735*7330f729Sjoerg return false; 736*7330f729Sjoerg if (IsUnavailable(Found)) 737*7330f729Sjoerg return true; 738*7330f729Sjoerg } 739*7330f729Sjoerg 740*7330f729Sjoerg // Infer a submodule with the same name as this header file. 741*7330f729Sjoerg SmallString<32> NameBuf; 742*7330f729Sjoerg StringRef Name = sanitizeFilenameAsIdentifier( 743*7330f729Sjoerg llvm::sys::path::stem(Header->getName()), 744*7330f729Sjoerg NameBuf); 745*7330f729Sjoerg Found = lookupModuleQualified(Name, Found); 746*7330f729Sjoerg if (!Found) 747*7330f729Sjoerg return false; 748*7330f729Sjoerg } 749*7330f729Sjoerg 750*7330f729Sjoerg return IsUnavailable(Found); 751*7330f729Sjoerg } 752*7330f729Sjoerg 753*7330f729Sjoerg SkippedDirs.push_back(Dir); 754*7330f729Sjoerg 755*7330f729Sjoerg // Retrieve our parent path. 756*7330f729Sjoerg DirName = llvm::sys::path::parent_path(DirName); 757*7330f729Sjoerg if (DirName.empty()) 758*7330f729Sjoerg break; 759*7330f729Sjoerg 760*7330f729Sjoerg // Resolve the parent path to a directory entry. 761*7330f729Sjoerg if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName)) 762*7330f729Sjoerg Dir = *DirEntry; 763*7330f729Sjoerg else 764*7330f729Sjoerg Dir = nullptr; 765*7330f729Sjoerg } while (Dir); 766*7330f729Sjoerg 767*7330f729Sjoerg return false; 768*7330f729Sjoerg } 769*7330f729Sjoerg 770*7330f729Sjoerg Module *ModuleMap::findModule(StringRef Name) const { 771*7330f729Sjoerg llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 772*7330f729Sjoerg if (Known != Modules.end()) 773*7330f729Sjoerg return Known->getValue(); 774*7330f729Sjoerg 775*7330f729Sjoerg return nullptr; 776*7330f729Sjoerg } 777*7330f729Sjoerg 778*7330f729Sjoerg Module *ModuleMap::lookupModuleUnqualified(StringRef Name, 779*7330f729Sjoerg Module *Context) const { 780*7330f729Sjoerg for(; Context; Context = Context->Parent) { 781*7330f729Sjoerg if (Module *Sub = lookupModuleQualified(Name, Context)) 782*7330f729Sjoerg return Sub; 783*7330f729Sjoerg } 784*7330f729Sjoerg 785*7330f729Sjoerg return findModule(Name); 786*7330f729Sjoerg } 787*7330f729Sjoerg 788*7330f729Sjoerg Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 789*7330f729Sjoerg if (!Context) 790*7330f729Sjoerg return findModule(Name); 791*7330f729Sjoerg 792*7330f729Sjoerg return Context->findSubmodule(Name); 793*7330f729Sjoerg } 794*7330f729Sjoerg 795*7330f729Sjoerg std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name, 796*7330f729Sjoerg Module *Parent, 797*7330f729Sjoerg bool IsFramework, 798*7330f729Sjoerg bool IsExplicit) { 799*7330f729Sjoerg // Try to find an existing module with this name. 800*7330f729Sjoerg if (Module *Sub = lookupModuleQualified(Name, Parent)) 801*7330f729Sjoerg return std::make_pair(Sub, false); 802*7330f729Sjoerg 803*7330f729Sjoerg // Create a new module with this name. 804*7330f729Sjoerg Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, 805*7330f729Sjoerg IsExplicit, NumCreatedModules++); 806*7330f729Sjoerg if (!Parent) { 807*7330f729Sjoerg if (LangOpts.CurrentModule == Name) 808*7330f729Sjoerg SourceModule = Result; 809*7330f729Sjoerg Modules[Name] = Result; 810*7330f729Sjoerg ModuleScopeIDs[Result] = CurrentModuleScopeID; 811*7330f729Sjoerg } 812*7330f729Sjoerg return std::make_pair(Result, true); 813*7330f729Sjoerg } 814*7330f729Sjoerg 815*7330f729Sjoerg Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc) { 816*7330f729Sjoerg PendingSubmodules.emplace_back( 817*7330f729Sjoerg new Module("<global>", Loc, nullptr, /*IsFramework*/ false, 818*7330f729Sjoerg /*IsExplicit*/ true, NumCreatedModules++)); 819*7330f729Sjoerg PendingSubmodules.back()->Kind = Module::GlobalModuleFragment; 820*7330f729Sjoerg return PendingSubmodules.back().get(); 821*7330f729Sjoerg } 822*7330f729Sjoerg 823*7330f729Sjoerg Module * 824*7330f729Sjoerg ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent, 825*7330f729Sjoerg SourceLocation Loc) { 826*7330f729Sjoerg auto *Result = 827*7330f729Sjoerg new Module("<private>", Loc, Parent, /*IsFramework*/ false, 828*7330f729Sjoerg /*IsExplicit*/ true, NumCreatedModules++); 829*7330f729Sjoerg Result->Kind = Module::PrivateModuleFragment; 830*7330f729Sjoerg return Result; 831*7330f729Sjoerg } 832*7330f729Sjoerg 833*7330f729Sjoerg Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, 834*7330f729Sjoerg StringRef Name, 835*7330f729Sjoerg Module *GlobalModule) { 836*7330f729Sjoerg assert(LangOpts.CurrentModule == Name && "module name mismatch"); 837*7330f729Sjoerg assert(!Modules[Name] && "redefining existing module"); 838*7330f729Sjoerg 839*7330f729Sjoerg auto *Result = 840*7330f729Sjoerg new Module(Name, Loc, nullptr, /*IsFramework*/ false, 841*7330f729Sjoerg /*IsExplicit*/ false, NumCreatedModules++); 842*7330f729Sjoerg Result->Kind = Module::ModuleInterfaceUnit; 843*7330f729Sjoerg Modules[Name] = SourceModule = Result; 844*7330f729Sjoerg 845*7330f729Sjoerg // Reparent the current global module fragment as a submodule of this module. 846*7330f729Sjoerg for (auto &Submodule : PendingSubmodules) { 847*7330f729Sjoerg Submodule->setParent(Result); 848*7330f729Sjoerg Submodule.release(); // now owned by parent 849*7330f729Sjoerg } 850*7330f729Sjoerg PendingSubmodules.clear(); 851*7330f729Sjoerg 852*7330f729Sjoerg // Mark the main source file as being within the newly-created module so that 853*7330f729Sjoerg // declarations and macros are properly visibility-restricted to it. 854*7330f729Sjoerg auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); 855*7330f729Sjoerg assert(MainFile && "no input file for module interface"); 856*7330f729Sjoerg Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader)); 857*7330f729Sjoerg 858*7330f729Sjoerg return Result; 859*7330f729Sjoerg } 860*7330f729Sjoerg 861*7330f729Sjoerg Module *ModuleMap::createHeaderModule(StringRef Name, 862*7330f729Sjoerg ArrayRef<Module::Header> Headers) { 863*7330f729Sjoerg assert(LangOpts.CurrentModule == Name && "module name mismatch"); 864*7330f729Sjoerg assert(!Modules[Name] && "redefining existing module"); 865*7330f729Sjoerg 866*7330f729Sjoerg auto *Result = 867*7330f729Sjoerg new Module(Name, SourceLocation(), nullptr, /*IsFramework*/ false, 868*7330f729Sjoerg /*IsExplicit*/ false, NumCreatedModules++); 869*7330f729Sjoerg Result->Kind = Module::ModuleInterfaceUnit; 870*7330f729Sjoerg Modules[Name] = SourceModule = Result; 871*7330f729Sjoerg 872*7330f729Sjoerg for (const Module::Header &H : Headers) { 873*7330f729Sjoerg auto *M = new Module(H.NameAsWritten, SourceLocation(), Result, 874*7330f729Sjoerg /*IsFramework*/ false, 875*7330f729Sjoerg /*IsExplicit*/ true, NumCreatedModules++); 876*7330f729Sjoerg // Header modules are implicitly 'export *'. 877*7330f729Sjoerg M->Exports.push_back(Module::ExportDecl(nullptr, true)); 878*7330f729Sjoerg addHeader(M, H, NormalHeader); 879*7330f729Sjoerg } 880*7330f729Sjoerg 881*7330f729Sjoerg return Result; 882*7330f729Sjoerg } 883*7330f729Sjoerg 884*7330f729Sjoerg /// For a framework module, infer the framework against which we 885*7330f729Sjoerg /// should link. 886*7330f729Sjoerg static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 887*7330f729Sjoerg FileManager &FileMgr) { 888*7330f729Sjoerg assert(Mod->IsFramework && "Can only infer linking for framework modules"); 889*7330f729Sjoerg assert(!Mod->isSubFramework() && 890*7330f729Sjoerg "Can only infer linking for top-level frameworks"); 891*7330f729Sjoerg 892*7330f729Sjoerg SmallString<128> LibName; 893*7330f729Sjoerg LibName += FrameworkDir->getName(); 894*7330f729Sjoerg llvm::sys::path::append(LibName, Mod->Name); 895*7330f729Sjoerg 896*7330f729Sjoerg // The library name of a framework has more than one possible extension since 897*7330f729Sjoerg // the introduction of the text-based dynamic library format. We need to check 898*7330f729Sjoerg // for both before we give up. 899*7330f729Sjoerg for (const char *extension : {"", ".tbd"}) { 900*7330f729Sjoerg llvm::sys::path::replace_extension(LibName, extension); 901*7330f729Sjoerg if (FileMgr.getFile(LibName)) { 902*7330f729Sjoerg Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 903*7330f729Sjoerg /*IsFramework=*/true)); 904*7330f729Sjoerg return; 905*7330f729Sjoerg } 906*7330f729Sjoerg } 907*7330f729Sjoerg } 908*7330f729Sjoerg 909*7330f729Sjoerg Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, 910*7330f729Sjoerg bool IsSystem, Module *Parent) { 911*7330f729Sjoerg Attributes Attrs; 912*7330f729Sjoerg Attrs.IsSystem = IsSystem; 913*7330f729Sjoerg return inferFrameworkModule(FrameworkDir, Attrs, Parent); 914*7330f729Sjoerg } 915*7330f729Sjoerg 916*7330f729Sjoerg Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, 917*7330f729Sjoerg Attributes Attrs, Module *Parent) { 918*7330f729Sjoerg // Note: as an egregious but useful hack we use the real path here, because 919*7330f729Sjoerg // we might be looking at an embedded framework that symlinks out to a 920*7330f729Sjoerg // top-level framework, and we need to infer as if we were naming the 921*7330f729Sjoerg // top-level framework. 922*7330f729Sjoerg StringRef FrameworkDirName = 923*7330f729Sjoerg SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 924*7330f729Sjoerg 925*7330f729Sjoerg // In case this is a case-insensitive filesystem, use the canonical 926*7330f729Sjoerg // directory name as the ModuleName, since modules are case-sensitive. 927*7330f729Sjoerg // FIXME: we should be able to give a fix-it hint for the correct spelling. 928*7330f729Sjoerg SmallString<32> ModuleNameStorage; 929*7330f729Sjoerg StringRef ModuleName = sanitizeFilenameAsIdentifier( 930*7330f729Sjoerg llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage); 931*7330f729Sjoerg 932*7330f729Sjoerg // Check whether we've already found this module. 933*7330f729Sjoerg if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 934*7330f729Sjoerg return Mod; 935*7330f729Sjoerg 936*7330f729Sjoerg FileManager &FileMgr = SourceMgr.getFileManager(); 937*7330f729Sjoerg 938*7330f729Sjoerg // If the framework has a parent path from which we're allowed to infer 939*7330f729Sjoerg // a framework module, do so. 940*7330f729Sjoerg const FileEntry *ModuleMapFile = nullptr; 941*7330f729Sjoerg if (!Parent) { 942*7330f729Sjoerg // Determine whether we're allowed to infer a module map. 943*7330f729Sjoerg bool canInfer = false; 944*7330f729Sjoerg if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 945*7330f729Sjoerg // Figure out the parent path. 946*7330f729Sjoerg StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 947*7330f729Sjoerg if (auto ParentDir = FileMgr.getDirectory(Parent)) { 948*7330f729Sjoerg // Check whether we have already looked into the parent directory 949*7330f729Sjoerg // for a module map. 950*7330f729Sjoerg llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 951*7330f729Sjoerg inferred = InferredDirectories.find(*ParentDir); 952*7330f729Sjoerg if (inferred == InferredDirectories.end()) { 953*7330f729Sjoerg // We haven't looked here before. Load a module map, if there is 954*7330f729Sjoerg // one. 955*7330f729Sjoerg bool IsFrameworkDir = Parent.endswith(".framework"); 956*7330f729Sjoerg if (const FileEntry *ModMapFile = 957*7330f729Sjoerg HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) { 958*7330f729Sjoerg parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir); 959*7330f729Sjoerg inferred = InferredDirectories.find(*ParentDir); 960*7330f729Sjoerg } 961*7330f729Sjoerg 962*7330f729Sjoerg if (inferred == InferredDirectories.end()) 963*7330f729Sjoerg inferred = InferredDirectories.insert( 964*7330f729Sjoerg std::make_pair(*ParentDir, InferredDirectory())).first; 965*7330f729Sjoerg } 966*7330f729Sjoerg 967*7330f729Sjoerg if (inferred->second.InferModules) { 968*7330f729Sjoerg // We're allowed to infer for this directory, but make sure it's okay 969*7330f729Sjoerg // to infer this particular module. 970*7330f729Sjoerg StringRef Name = llvm::sys::path::stem(FrameworkDirName); 971*7330f729Sjoerg canInfer = std::find(inferred->second.ExcludedModules.begin(), 972*7330f729Sjoerg inferred->second.ExcludedModules.end(), 973*7330f729Sjoerg Name) == inferred->second.ExcludedModules.end(); 974*7330f729Sjoerg 975*7330f729Sjoerg Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 976*7330f729Sjoerg Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 977*7330f729Sjoerg Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 978*7330f729Sjoerg Attrs.NoUndeclaredIncludes |= 979*7330f729Sjoerg inferred->second.Attrs.NoUndeclaredIncludes; 980*7330f729Sjoerg ModuleMapFile = inferred->second.ModuleMapFile; 981*7330f729Sjoerg } 982*7330f729Sjoerg } 983*7330f729Sjoerg } 984*7330f729Sjoerg 985*7330f729Sjoerg // If we're not allowed to infer a framework module, don't. 986*7330f729Sjoerg if (!canInfer) 987*7330f729Sjoerg return nullptr; 988*7330f729Sjoerg } else 989*7330f729Sjoerg ModuleMapFile = getModuleMapFileForUniquing(Parent); 990*7330f729Sjoerg 991*7330f729Sjoerg 992*7330f729Sjoerg // Look for an umbrella header. 993*7330f729Sjoerg SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 994*7330f729Sjoerg llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 995*7330f729Sjoerg auto UmbrellaHeader = FileMgr.getFile(UmbrellaName); 996*7330f729Sjoerg 997*7330f729Sjoerg // FIXME: If there's no umbrella header, we could probably scan the 998*7330f729Sjoerg // framework to load *everything*. But, it's not clear that this is a good 999*7330f729Sjoerg // idea. 1000*7330f729Sjoerg if (!UmbrellaHeader) 1001*7330f729Sjoerg return nullptr; 1002*7330f729Sjoerg 1003*7330f729Sjoerg Module *Result = new Module(ModuleName, SourceLocation(), Parent, 1004*7330f729Sjoerg /*IsFramework=*/true, /*IsExplicit=*/false, 1005*7330f729Sjoerg NumCreatedModules++); 1006*7330f729Sjoerg InferredModuleAllowedBy[Result] = ModuleMapFile; 1007*7330f729Sjoerg Result->IsInferred = true; 1008*7330f729Sjoerg if (!Parent) { 1009*7330f729Sjoerg if (LangOpts.CurrentModule == ModuleName) 1010*7330f729Sjoerg SourceModule = Result; 1011*7330f729Sjoerg Modules[ModuleName] = Result; 1012*7330f729Sjoerg ModuleScopeIDs[Result] = CurrentModuleScopeID; 1013*7330f729Sjoerg } 1014*7330f729Sjoerg 1015*7330f729Sjoerg Result->IsSystem |= Attrs.IsSystem; 1016*7330f729Sjoerg Result->IsExternC |= Attrs.IsExternC; 1017*7330f729Sjoerg Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; 1018*7330f729Sjoerg Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes; 1019*7330f729Sjoerg Result->Directory = FrameworkDir; 1020*7330f729Sjoerg 1021*7330f729Sjoerg // umbrella header "umbrella-header-name" 1022*7330f729Sjoerg // 1023*7330f729Sjoerg // The "Headers/" component of the name is implied because this is 1024*7330f729Sjoerg // a framework module. 1025*7330f729Sjoerg setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h"); 1026*7330f729Sjoerg 1027*7330f729Sjoerg // export * 1028*7330f729Sjoerg Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 1029*7330f729Sjoerg 1030*7330f729Sjoerg // module * { export * } 1031*7330f729Sjoerg Result->InferSubmodules = true; 1032*7330f729Sjoerg Result->InferExportWildcard = true; 1033*7330f729Sjoerg 1034*7330f729Sjoerg // Look for subframeworks. 1035*7330f729Sjoerg std::error_code EC; 1036*7330f729Sjoerg SmallString<128> SubframeworksDirName 1037*7330f729Sjoerg = StringRef(FrameworkDir->getName()); 1038*7330f729Sjoerg llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 1039*7330f729Sjoerg llvm::sys::path::native(SubframeworksDirName); 1040*7330f729Sjoerg llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); 1041*7330f729Sjoerg for (llvm::vfs::directory_iterator 1042*7330f729Sjoerg Dir = FS.dir_begin(SubframeworksDirName, EC), 1043*7330f729Sjoerg DirEnd; 1044*7330f729Sjoerg Dir != DirEnd && !EC; Dir.increment(EC)) { 1045*7330f729Sjoerg if (!StringRef(Dir->path()).endswith(".framework")) 1046*7330f729Sjoerg continue; 1047*7330f729Sjoerg 1048*7330f729Sjoerg if (auto SubframeworkDir = 1049*7330f729Sjoerg FileMgr.getDirectory(Dir->path())) { 1050*7330f729Sjoerg // Note: as an egregious but useful hack, we use the real path here and 1051*7330f729Sjoerg // check whether it is actually a subdirectory of the parent directory. 1052*7330f729Sjoerg // This will not be the case if the 'subframework' is actually a symlink 1053*7330f729Sjoerg // out to a top-level framework. 1054*7330f729Sjoerg StringRef SubframeworkDirName = 1055*7330f729Sjoerg FileMgr.getCanonicalName(*SubframeworkDir); 1056*7330f729Sjoerg bool FoundParent = false; 1057*7330f729Sjoerg do { 1058*7330f729Sjoerg // Get the parent directory name. 1059*7330f729Sjoerg SubframeworkDirName 1060*7330f729Sjoerg = llvm::sys::path::parent_path(SubframeworkDirName); 1061*7330f729Sjoerg if (SubframeworkDirName.empty()) 1062*7330f729Sjoerg break; 1063*7330f729Sjoerg 1064*7330f729Sjoerg if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) { 1065*7330f729Sjoerg if (*SubDir == FrameworkDir) { 1066*7330f729Sjoerg FoundParent = true; 1067*7330f729Sjoerg break; 1068*7330f729Sjoerg } 1069*7330f729Sjoerg } 1070*7330f729Sjoerg } while (true); 1071*7330f729Sjoerg 1072*7330f729Sjoerg if (!FoundParent) 1073*7330f729Sjoerg continue; 1074*7330f729Sjoerg 1075*7330f729Sjoerg // FIXME: Do we want to warn about subframeworks without umbrella headers? 1076*7330f729Sjoerg inferFrameworkModule(*SubframeworkDir, Attrs, Result); 1077*7330f729Sjoerg } 1078*7330f729Sjoerg } 1079*7330f729Sjoerg 1080*7330f729Sjoerg // If the module is a top-level framework, automatically link against the 1081*7330f729Sjoerg // framework. 1082*7330f729Sjoerg if (!Result->isSubFramework()) { 1083*7330f729Sjoerg inferFrameworkLink(Result, FrameworkDir, FileMgr); 1084*7330f729Sjoerg } 1085*7330f729Sjoerg 1086*7330f729Sjoerg return Result; 1087*7330f729Sjoerg } 1088*7330f729Sjoerg 1089*7330f729Sjoerg Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework, 1090*7330f729Sjoerg Module *ShadowingModule) { 1091*7330f729Sjoerg 1092*7330f729Sjoerg // Create a new module with this name. 1093*7330f729Sjoerg Module *Result = 1094*7330f729Sjoerg new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework, 1095*7330f729Sjoerg /*IsExplicit=*/false, NumCreatedModules++); 1096*7330f729Sjoerg Result->ShadowingModule = ShadowingModule; 1097*7330f729Sjoerg Result->IsAvailable = false; 1098*7330f729Sjoerg ModuleScopeIDs[Result] = CurrentModuleScopeID; 1099*7330f729Sjoerg ShadowModules.push_back(Result); 1100*7330f729Sjoerg 1101*7330f729Sjoerg return Result; 1102*7330f729Sjoerg } 1103*7330f729Sjoerg 1104*7330f729Sjoerg void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, 1105*7330f729Sjoerg Twine NameAsWritten) { 1106*7330f729Sjoerg Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 1107*7330f729Sjoerg Mod->Umbrella = UmbrellaHeader; 1108*7330f729Sjoerg Mod->UmbrellaAsWritten = NameAsWritten.str(); 1109*7330f729Sjoerg UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 1110*7330f729Sjoerg 1111*7330f729Sjoerg // Notify callbacks that we just added a new header. 1112*7330f729Sjoerg for (const auto &Cb : Callbacks) 1113*7330f729Sjoerg Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader); 1114*7330f729Sjoerg } 1115*7330f729Sjoerg 1116*7330f729Sjoerg void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, 1117*7330f729Sjoerg Twine NameAsWritten) { 1118*7330f729Sjoerg Mod->Umbrella = UmbrellaDir; 1119*7330f729Sjoerg Mod->UmbrellaAsWritten = NameAsWritten.str(); 1120*7330f729Sjoerg UmbrellaDirs[UmbrellaDir] = Mod; 1121*7330f729Sjoerg } 1122*7330f729Sjoerg 1123*7330f729Sjoerg void ModuleMap::addUnresolvedHeader(Module *Mod, 1124*7330f729Sjoerg Module::UnresolvedHeaderDirective Header, 1125*7330f729Sjoerg bool &NeedsFramework) { 1126*7330f729Sjoerg // If there is a builtin counterpart to this file, add it now so it can 1127*7330f729Sjoerg // wrap the system header. 1128*7330f729Sjoerg if (resolveAsBuiltinHeader(Mod, Header)) { 1129*7330f729Sjoerg // If we have both a builtin and system version of the file, the 1130*7330f729Sjoerg // builtin version may want to inject macros into the system header, so 1131*7330f729Sjoerg // force the system header to be treated as a textual header in this 1132*7330f729Sjoerg // case. 1133*7330f729Sjoerg Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole( 1134*7330f729Sjoerg headerKindToRole(Header.Kind) | ModuleMap::TextualHeader)); 1135*7330f729Sjoerg Header.HasBuiltinHeader = true; 1136*7330f729Sjoerg } 1137*7330f729Sjoerg 1138*7330f729Sjoerg // If possible, don't stat the header until we need to. This requires the 1139*7330f729Sjoerg // user to have provided us with some stat information about the file. 1140*7330f729Sjoerg // FIXME: Add support for lazily stat'ing umbrella headers and excluded 1141*7330f729Sjoerg // headers. 1142*7330f729Sjoerg if ((Header.Size || Header.ModTime) && !Header.IsUmbrella && 1143*7330f729Sjoerg Header.Kind != Module::HK_Excluded) { 1144*7330f729Sjoerg // We expect more variation in mtime than size, so if we're given both, 1145*7330f729Sjoerg // use the mtime as the key. 1146*7330f729Sjoerg if (Header.ModTime) 1147*7330f729Sjoerg LazyHeadersByModTime[*Header.ModTime].push_back(Mod); 1148*7330f729Sjoerg else 1149*7330f729Sjoerg LazyHeadersBySize[*Header.Size].push_back(Mod); 1150*7330f729Sjoerg Mod->UnresolvedHeaders.push_back(Header); 1151*7330f729Sjoerg return; 1152*7330f729Sjoerg } 1153*7330f729Sjoerg 1154*7330f729Sjoerg // We don't have stat information or can't defer looking this file up. 1155*7330f729Sjoerg // Perform the lookup now. 1156*7330f729Sjoerg resolveHeader(Mod, Header, NeedsFramework); 1157*7330f729Sjoerg } 1158*7330f729Sjoerg 1159*7330f729Sjoerg void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const { 1160*7330f729Sjoerg auto BySize = LazyHeadersBySize.find(File->getSize()); 1161*7330f729Sjoerg if (BySize != LazyHeadersBySize.end()) { 1162*7330f729Sjoerg for (auto *M : BySize->second) 1163*7330f729Sjoerg resolveHeaderDirectives(M); 1164*7330f729Sjoerg LazyHeadersBySize.erase(BySize); 1165*7330f729Sjoerg } 1166*7330f729Sjoerg 1167*7330f729Sjoerg auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime()); 1168*7330f729Sjoerg if (ByModTime != LazyHeadersByModTime.end()) { 1169*7330f729Sjoerg for (auto *M : ByModTime->second) 1170*7330f729Sjoerg resolveHeaderDirectives(M); 1171*7330f729Sjoerg LazyHeadersByModTime.erase(ByModTime); 1172*7330f729Sjoerg } 1173*7330f729Sjoerg } 1174*7330f729Sjoerg 1175*7330f729Sjoerg void ModuleMap::resolveHeaderDirectives(Module *Mod) const { 1176*7330f729Sjoerg bool NeedsFramework = false; 1177*7330f729Sjoerg for (auto &Header : Mod->UnresolvedHeaders) 1178*7330f729Sjoerg // This operation is logically const; we're just changing how we represent 1179*7330f729Sjoerg // the header information for this file. 1180*7330f729Sjoerg const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header, NeedsFramework); 1181*7330f729Sjoerg Mod->UnresolvedHeaders.clear(); 1182*7330f729Sjoerg } 1183*7330f729Sjoerg 1184*7330f729Sjoerg void ModuleMap::addHeader(Module *Mod, Module::Header Header, 1185*7330f729Sjoerg ModuleHeaderRole Role, bool Imported) { 1186*7330f729Sjoerg KnownHeader KH(Mod, Role); 1187*7330f729Sjoerg 1188*7330f729Sjoerg // Only add each header to the headers list once. 1189*7330f729Sjoerg // FIXME: Should we diagnose if a header is listed twice in the 1190*7330f729Sjoerg // same module definition? 1191*7330f729Sjoerg auto &HeaderList = Headers[Header.Entry]; 1192*7330f729Sjoerg for (auto H : HeaderList) 1193*7330f729Sjoerg if (H == KH) 1194*7330f729Sjoerg return; 1195*7330f729Sjoerg 1196*7330f729Sjoerg HeaderList.push_back(KH); 1197*7330f729Sjoerg Mod->Headers[headerRoleToKind(Role)].push_back(Header); 1198*7330f729Sjoerg 1199*7330f729Sjoerg bool isCompilingModuleHeader = 1200*7330f729Sjoerg LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule; 1201*7330f729Sjoerg if (!Imported || isCompilingModuleHeader) { 1202*7330f729Sjoerg // When we import HeaderFileInfo, the external source is expected to 1203*7330f729Sjoerg // set the isModuleHeader flag itself. 1204*7330f729Sjoerg HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 1205*7330f729Sjoerg isCompilingModuleHeader); 1206*7330f729Sjoerg } 1207*7330f729Sjoerg 1208*7330f729Sjoerg // Notify callbacks that we just added a new header. 1209*7330f729Sjoerg for (const auto &Cb : Callbacks) 1210*7330f729Sjoerg Cb->moduleMapAddHeader(Header.Entry->getName()); 1211*7330f729Sjoerg } 1212*7330f729Sjoerg 1213*7330f729Sjoerg void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { 1214*7330f729Sjoerg // Add this as a known header so we won't implicitly add it to any 1215*7330f729Sjoerg // umbrella directory module. 1216*7330f729Sjoerg // FIXME: Should we only exclude it from umbrella modules within the 1217*7330f729Sjoerg // specified module? 1218*7330f729Sjoerg (void) Headers[Header.Entry]; 1219*7330f729Sjoerg 1220*7330f729Sjoerg Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); 1221*7330f729Sjoerg } 1222*7330f729Sjoerg 1223*7330f729Sjoerg const FileEntry * 1224*7330f729Sjoerg ModuleMap::getContainingModuleMapFile(const Module *Module) const { 1225*7330f729Sjoerg if (Module->DefinitionLoc.isInvalid()) 1226*7330f729Sjoerg return nullptr; 1227*7330f729Sjoerg 1228*7330f729Sjoerg return SourceMgr.getFileEntryForID( 1229*7330f729Sjoerg SourceMgr.getFileID(Module->DefinitionLoc)); 1230*7330f729Sjoerg } 1231*7330f729Sjoerg 1232*7330f729Sjoerg const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 1233*7330f729Sjoerg if (M->IsInferred) { 1234*7330f729Sjoerg assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 1235*7330f729Sjoerg return InferredModuleAllowedBy.find(M)->second; 1236*7330f729Sjoerg } 1237*7330f729Sjoerg return getContainingModuleMapFile(M); 1238*7330f729Sjoerg } 1239*7330f729Sjoerg 1240*7330f729Sjoerg void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 1241*7330f729Sjoerg assert(M->IsInferred && "module not inferred"); 1242*7330f729Sjoerg InferredModuleAllowedBy[M] = ModMap; 1243*7330f729Sjoerg } 1244*7330f729Sjoerg 1245*7330f729Sjoerg LLVM_DUMP_METHOD void ModuleMap::dump() { 1246*7330f729Sjoerg llvm::errs() << "Modules:"; 1247*7330f729Sjoerg for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 1248*7330f729Sjoerg MEnd = Modules.end(); 1249*7330f729Sjoerg M != MEnd; ++M) 1250*7330f729Sjoerg M->getValue()->print(llvm::errs(), 2); 1251*7330f729Sjoerg 1252*7330f729Sjoerg llvm::errs() << "Headers:"; 1253*7330f729Sjoerg for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 1254*7330f729Sjoerg H != HEnd; ++H) { 1255*7330f729Sjoerg llvm::errs() << " \"" << H->first->getName() << "\" -> "; 1256*7330f729Sjoerg for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 1257*7330f729Sjoerg E = H->second.end(); 1258*7330f729Sjoerg I != E; ++I) { 1259*7330f729Sjoerg if (I != H->second.begin()) 1260*7330f729Sjoerg llvm::errs() << ","; 1261*7330f729Sjoerg llvm::errs() << I->getModule()->getFullModuleName(); 1262*7330f729Sjoerg } 1263*7330f729Sjoerg llvm::errs() << "\n"; 1264*7330f729Sjoerg } 1265*7330f729Sjoerg } 1266*7330f729Sjoerg 1267*7330f729Sjoerg bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 1268*7330f729Sjoerg auto Unresolved = std::move(Mod->UnresolvedExports); 1269*7330f729Sjoerg Mod->UnresolvedExports.clear(); 1270*7330f729Sjoerg for (auto &UE : Unresolved) { 1271*7330f729Sjoerg Module::ExportDecl Export = resolveExport(Mod, UE, Complain); 1272*7330f729Sjoerg if (Export.getPointer() || Export.getInt()) 1273*7330f729Sjoerg Mod->Exports.push_back(Export); 1274*7330f729Sjoerg else 1275*7330f729Sjoerg Mod->UnresolvedExports.push_back(UE); 1276*7330f729Sjoerg } 1277*7330f729Sjoerg return !Mod->UnresolvedExports.empty(); 1278*7330f729Sjoerg } 1279*7330f729Sjoerg 1280*7330f729Sjoerg bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 1281*7330f729Sjoerg auto Unresolved = std::move(Mod->UnresolvedDirectUses); 1282*7330f729Sjoerg Mod->UnresolvedDirectUses.clear(); 1283*7330f729Sjoerg for (auto &UDU : Unresolved) { 1284*7330f729Sjoerg Module *DirectUse = resolveModuleId(UDU, Mod, Complain); 1285*7330f729Sjoerg if (DirectUse) 1286*7330f729Sjoerg Mod->DirectUses.push_back(DirectUse); 1287*7330f729Sjoerg else 1288*7330f729Sjoerg Mod->UnresolvedDirectUses.push_back(UDU); 1289*7330f729Sjoerg } 1290*7330f729Sjoerg return !Mod->UnresolvedDirectUses.empty(); 1291*7330f729Sjoerg } 1292*7330f729Sjoerg 1293*7330f729Sjoerg bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 1294*7330f729Sjoerg auto Unresolved = std::move(Mod->UnresolvedConflicts); 1295*7330f729Sjoerg Mod->UnresolvedConflicts.clear(); 1296*7330f729Sjoerg for (auto &UC : Unresolved) { 1297*7330f729Sjoerg if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) { 1298*7330f729Sjoerg Module::Conflict Conflict; 1299*7330f729Sjoerg Conflict.Other = OtherMod; 1300*7330f729Sjoerg Conflict.Message = UC.Message; 1301*7330f729Sjoerg Mod->Conflicts.push_back(Conflict); 1302*7330f729Sjoerg } else 1303*7330f729Sjoerg Mod->UnresolvedConflicts.push_back(UC); 1304*7330f729Sjoerg } 1305*7330f729Sjoerg return !Mod->UnresolvedConflicts.empty(); 1306*7330f729Sjoerg } 1307*7330f729Sjoerg 1308*7330f729Sjoerg //----------------------------------------------------------------------------// 1309*7330f729Sjoerg // Module map file parser 1310*7330f729Sjoerg //----------------------------------------------------------------------------// 1311*7330f729Sjoerg 1312*7330f729Sjoerg namespace clang { 1313*7330f729Sjoerg 1314*7330f729Sjoerg /// A token in a module map file. 1315*7330f729Sjoerg struct MMToken { 1316*7330f729Sjoerg enum TokenKind { 1317*7330f729Sjoerg Comma, 1318*7330f729Sjoerg ConfigMacros, 1319*7330f729Sjoerg Conflict, 1320*7330f729Sjoerg EndOfFile, 1321*7330f729Sjoerg HeaderKeyword, 1322*7330f729Sjoerg Identifier, 1323*7330f729Sjoerg Exclaim, 1324*7330f729Sjoerg ExcludeKeyword, 1325*7330f729Sjoerg ExplicitKeyword, 1326*7330f729Sjoerg ExportKeyword, 1327*7330f729Sjoerg ExportAsKeyword, 1328*7330f729Sjoerg ExternKeyword, 1329*7330f729Sjoerg FrameworkKeyword, 1330*7330f729Sjoerg LinkKeyword, 1331*7330f729Sjoerg ModuleKeyword, 1332*7330f729Sjoerg Period, 1333*7330f729Sjoerg PrivateKeyword, 1334*7330f729Sjoerg UmbrellaKeyword, 1335*7330f729Sjoerg UseKeyword, 1336*7330f729Sjoerg RequiresKeyword, 1337*7330f729Sjoerg Star, 1338*7330f729Sjoerg StringLiteral, 1339*7330f729Sjoerg IntegerLiteral, 1340*7330f729Sjoerg TextualKeyword, 1341*7330f729Sjoerg LBrace, 1342*7330f729Sjoerg RBrace, 1343*7330f729Sjoerg LSquare, 1344*7330f729Sjoerg RSquare 1345*7330f729Sjoerg } Kind; 1346*7330f729Sjoerg 1347*7330f729Sjoerg unsigned Location; 1348*7330f729Sjoerg unsigned StringLength; 1349*7330f729Sjoerg union { 1350*7330f729Sjoerg // If Kind != IntegerLiteral. 1351*7330f729Sjoerg const char *StringData; 1352*7330f729Sjoerg 1353*7330f729Sjoerg // If Kind == IntegerLiteral. 1354*7330f729Sjoerg uint64_t IntegerValue; 1355*7330f729Sjoerg }; 1356*7330f729Sjoerg 1357*7330f729Sjoerg void clear() { 1358*7330f729Sjoerg Kind = EndOfFile; 1359*7330f729Sjoerg Location = 0; 1360*7330f729Sjoerg StringLength = 0; 1361*7330f729Sjoerg StringData = nullptr; 1362*7330f729Sjoerg } 1363*7330f729Sjoerg 1364*7330f729Sjoerg bool is(TokenKind K) const { return Kind == K; } 1365*7330f729Sjoerg 1366*7330f729Sjoerg SourceLocation getLocation() const { 1367*7330f729Sjoerg return SourceLocation::getFromRawEncoding(Location); 1368*7330f729Sjoerg } 1369*7330f729Sjoerg 1370*7330f729Sjoerg uint64_t getInteger() const { 1371*7330f729Sjoerg return Kind == IntegerLiteral ? IntegerValue : 0; 1372*7330f729Sjoerg } 1373*7330f729Sjoerg 1374*7330f729Sjoerg StringRef getString() const { 1375*7330f729Sjoerg return Kind == IntegerLiteral ? StringRef() 1376*7330f729Sjoerg : StringRef(StringData, StringLength); 1377*7330f729Sjoerg } 1378*7330f729Sjoerg }; 1379*7330f729Sjoerg 1380*7330f729Sjoerg class ModuleMapParser { 1381*7330f729Sjoerg Lexer &L; 1382*7330f729Sjoerg SourceManager &SourceMgr; 1383*7330f729Sjoerg 1384*7330f729Sjoerg /// Default target information, used only for string literal 1385*7330f729Sjoerg /// parsing. 1386*7330f729Sjoerg const TargetInfo *Target; 1387*7330f729Sjoerg 1388*7330f729Sjoerg DiagnosticsEngine &Diags; 1389*7330f729Sjoerg ModuleMap ⤅ 1390*7330f729Sjoerg 1391*7330f729Sjoerg /// The current module map file. 1392*7330f729Sjoerg const FileEntry *ModuleMapFile; 1393*7330f729Sjoerg 1394*7330f729Sjoerg /// Source location of most recent parsed module declaration 1395*7330f729Sjoerg SourceLocation CurrModuleDeclLoc; 1396*7330f729Sjoerg 1397*7330f729Sjoerg /// The directory that file names in this module map file should 1398*7330f729Sjoerg /// be resolved relative to. 1399*7330f729Sjoerg const DirectoryEntry *Directory; 1400*7330f729Sjoerg 1401*7330f729Sjoerg /// Whether this module map is in a system header directory. 1402*7330f729Sjoerg bool IsSystem; 1403*7330f729Sjoerg 1404*7330f729Sjoerg /// Whether an error occurred. 1405*7330f729Sjoerg bool HadError = false; 1406*7330f729Sjoerg 1407*7330f729Sjoerg /// Stores string data for the various string literals referenced 1408*7330f729Sjoerg /// during parsing. 1409*7330f729Sjoerg llvm::BumpPtrAllocator StringData; 1410*7330f729Sjoerg 1411*7330f729Sjoerg /// The current token. 1412*7330f729Sjoerg MMToken Tok; 1413*7330f729Sjoerg 1414*7330f729Sjoerg /// The active module. 1415*7330f729Sjoerg Module *ActiveModule = nullptr; 1416*7330f729Sjoerg 1417*7330f729Sjoerg /// Whether a module uses the 'requires excluded' hack to mark its 1418*7330f729Sjoerg /// contents as 'textual'. 1419*7330f729Sjoerg /// 1420*7330f729Sjoerg /// On older Darwin SDK versions, 'requires excluded' is used to mark the 1421*7330f729Sjoerg /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as 1422*7330f729Sjoerg /// non-modular headers. For backwards compatibility, we continue to 1423*7330f729Sjoerg /// support this idiom for just these modules, and map the headers to 1424*7330f729Sjoerg /// 'textual' to match the original intent. 1425*7330f729Sjoerg llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack; 1426*7330f729Sjoerg 1427*7330f729Sjoerg /// Consume the current token and return its location. 1428*7330f729Sjoerg SourceLocation consumeToken(); 1429*7330f729Sjoerg 1430*7330f729Sjoerg /// Skip tokens until we reach the a token with the given kind 1431*7330f729Sjoerg /// (or the end of the file). 1432*7330f729Sjoerg void skipUntil(MMToken::TokenKind K); 1433*7330f729Sjoerg 1434*7330f729Sjoerg using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; 1435*7330f729Sjoerg 1436*7330f729Sjoerg bool parseModuleId(ModuleId &Id); 1437*7330f729Sjoerg void parseModuleDecl(); 1438*7330f729Sjoerg void parseExternModuleDecl(); 1439*7330f729Sjoerg void parseRequiresDecl(); 1440*7330f729Sjoerg void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc); 1441*7330f729Sjoerg void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1442*7330f729Sjoerg void parseExportDecl(); 1443*7330f729Sjoerg void parseExportAsDecl(); 1444*7330f729Sjoerg void parseUseDecl(); 1445*7330f729Sjoerg void parseLinkDecl(); 1446*7330f729Sjoerg void parseConfigMacros(); 1447*7330f729Sjoerg void parseConflict(); 1448*7330f729Sjoerg void parseInferredModuleDecl(bool Framework, bool Explicit); 1449*7330f729Sjoerg 1450*7330f729Sjoerg /// Private modules are canonicalized as Foo_Private. Clang provides extra 1451*7330f729Sjoerg /// module map search logic to find the appropriate private module when PCH 1452*7330f729Sjoerg /// is used with implicit module maps. Warn when private modules are written 1453*7330f729Sjoerg /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1454*7330f729Sjoerg void diagnosePrivateModules(SourceLocation ExplicitLoc, 1455*7330f729Sjoerg SourceLocation FrameworkLoc); 1456*7330f729Sjoerg 1457*7330f729Sjoerg using Attributes = ModuleMap::Attributes; 1458*7330f729Sjoerg 1459*7330f729Sjoerg bool parseOptionalAttributes(Attributes &Attrs); 1460*7330f729Sjoerg 1461*7330f729Sjoerg public: 1462*7330f729Sjoerg explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1463*7330f729Sjoerg const TargetInfo *Target, DiagnosticsEngine &Diags, 1464*7330f729Sjoerg ModuleMap &Map, const FileEntry *ModuleMapFile, 1465*7330f729Sjoerg const DirectoryEntry *Directory, bool IsSystem) 1466*7330f729Sjoerg : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1467*7330f729Sjoerg ModuleMapFile(ModuleMapFile), Directory(Directory), 1468*7330f729Sjoerg IsSystem(IsSystem) { 1469*7330f729Sjoerg Tok.clear(); 1470*7330f729Sjoerg consumeToken(); 1471*7330f729Sjoerg } 1472*7330f729Sjoerg 1473*7330f729Sjoerg bool parseModuleMapFile(); 1474*7330f729Sjoerg 1475*7330f729Sjoerg bool terminatedByDirective() { return false; } 1476*7330f729Sjoerg SourceLocation getLocation() { return Tok.getLocation(); } 1477*7330f729Sjoerg }; 1478*7330f729Sjoerg 1479*7330f729Sjoerg } // namespace clang 1480*7330f729Sjoerg 1481*7330f729Sjoerg SourceLocation ModuleMapParser::consumeToken() { 1482*7330f729Sjoerg SourceLocation Result = Tok.getLocation(); 1483*7330f729Sjoerg 1484*7330f729Sjoerg retry: 1485*7330f729Sjoerg Tok.clear(); 1486*7330f729Sjoerg Token LToken; 1487*7330f729Sjoerg L.LexFromRawLexer(LToken); 1488*7330f729Sjoerg Tok.Location = LToken.getLocation().getRawEncoding(); 1489*7330f729Sjoerg switch (LToken.getKind()) { 1490*7330f729Sjoerg case tok::raw_identifier: { 1491*7330f729Sjoerg StringRef RI = LToken.getRawIdentifier(); 1492*7330f729Sjoerg Tok.StringData = RI.data(); 1493*7330f729Sjoerg Tok.StringLength = RI.size(); 1494*7330f729Sjoerg Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1495*7330f729Sjoerg .Case("config_macros", MMToken::ConfigMacros) 1496*7330f729Sjoerg .Case("conflict", MMToken::Conflict) 1497*7330f729Sjoerg .Case("exclude", MMToken::ExcludeKeyword) 1498*7330f729Sjoerg .Case("explicit", MMToken::ExplicitKeyword) 1499*7330f729Sjoerg .Case("export", MMToken::ExportKeyword) 1500*7330f729Sjoerg .Case("export_as", MMToken::ExportAsKeyword) 1501*7330f729Sjoerg .Case("extern", MMToken::ExternKeyword) 1502*7330f729Sjoerg .Case("framework", MMToken::FrameworkKeyword) 1503*7330f729Sjoerg .Case("header", MMToken::HeaderKeyword) 1504*7330f729Sjoerg .Case("link", MMToken::LinkKeyword) 1505*7330f729Sjoerg .Case("module", MMToken::ModuleKeyword) 1506*7330f729Sjoerg .Case("private", MMToken::PrivateKeyword) 1507*7330f729Sjoerg .Case("requires", MMToken::RequiresKeyword) 1508*7330f729Sjoerg .Case("textual", MMToken::TextualKeyword) 1509*7330f729Sjoerg .Case("umbrella", MMToken::UmbrellaKeyword) 1510*7330f729Sjoerg .Case("use", MMToken::UseKeyword) 1511*7330f729Sjoerg .Default(MMToken::Identifier); 1512*7330f729Sjoerg break; 1513*7330f729Sjoerg } 1514*7330f729Sjoerg 1515*7330f729Sjoerg case tok::comma: 1516*7330f729Sjoerg Tok.Kind = MMToken::Comma; 1517*7330f729Sjoerg break; 1518*7330f729Sjoerg 1519*7330f729Sjoerg case tok::eof: 1520*7330f729Sjoerg Tok.Kind = MMToken::EndOfFile; 1521*7330f729Sjoerg break; 1522*7330f729Sjoerg 1523*7330f729Sjoerg case tok::l_brace: 1524*7330f729Sjoerg Tok.Kind = MMToken::LBrace; 1525*7330f729Sjoerg break; 1526*7330f729Sjoerg 1527*7330f729Sjoerg case tok::l_square: 1528*7330f729Sjoerg Tok.Kind = MMToken::LSquare; 1529*7330f729Sjoerg break; 1530*7330f729Sjoerg 1531*7330f729Sjoerg case tok::period: 1532*7330f729Sjoerg Tok.Kind = MMToken::Period; 1533*7330f729Sjoerg break; 1534*7330f729Sjoerg 1535*7330f729Sjoerg case tok::r_brace: 1536*7330f729Sjoerg Tok.Kind = MMToken::RBrace; 1537*7330f729Sjoerg break; 1538*7330f729Sjoerg 1539*7330f729Sjoerg case tok::r_square: 1540*7330f729Sjoerg Tok.Kind = MMToken::RSquare; 1541*7330f729Sjoerg break; 1542*7330f729Sjoerg 1543*7330f729Sjoerg case tok::star: 1544*7330f729Sjoerg Tok.Kind = MMToken::Star; 1545*7330f729Sjoerg break; 1546*7330f729Sjoerg 1547*7330f729Sjoerg case tok::exclaim: 1548*7330f729Sjoerg Tok.Kind = MMToken::Exclaim; 1549*7330f729Sjoerg break; 1550*7330f729Sjoerg 1551*7330f729Sjoerg case tok::string_literal: { 1552*7330f729Sjoerg if (LToken.hasUDSuffix()) { 1553*7330f729Sjoerg Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1554*7330f729Sjoerg HadError = true; 1555*7330f729Sjoerg goto retry; 1556*7330f729Sjoerg } 1557*7330f729Sjoerg 1558*7330f729Sjoerg // Parse the string literal. 1559*7330f729Sjoerg LangOptions LangOpts; 1560*7330f729Sjoerg StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1561*7330f729Sjoerg if (StringLiteral.hadError) 1562*7330f729Sjoerg goto retry; 1563*7330f729Sjoerg 1564*7330f729Sjoerg // Copy the string literal into our string data allocator. 1565*7330f729Sjoerg unsigned Length = StringLiteral.GetStringLength(); 1566*7330f729Sjoerg char *Saved = StringData.Allocate<char>(Length + 1); 1567*7330f729Sjoerg memcpy(Saved, StringLiteral.GetString().data(), Length); 1568*7330f729Sjoerg Saved[Length] = 0; 1569*7330f729Sjoerg 1570*7330f729Sjoerg // Form the token. 1571*7330f729Sjoerg Tok.Kind = MMToken::StringLiteral; 1572*7330f729Sjoerg Tok.StringData = Saved; 1573*7330f729Sjoerg Tok.StringLength = Length; 1574*7330f729Sjoerg break; 1575*7330f729Sjoerg } 1576*7330f729Sjoerg 1577*7330f729Sjoerg case tok::numeric_constant: { 1578*7330f729Sjoerg // We don't support any suffixes or other complications. 1579*7330f729Sjoerg SmallString<32> SpellingBuffer; 1580*7330f729Sjoerg SpellingBuffer.resize(LToken.getLength() + 1); 1581*7330f729Sjoerg const char *Start = SpellingBuffer.data(); 1582*7330f729Sjoerg unsigned Length = 1583*7330f729Sjoerg Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts()); 1584*7330f729Sjoerg uint64_t Value; 1585*7330f729Sjoerg if (StringRef(Start, Length).getAsInteger(0, Value)) { 1586*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1587*7330f729Sjoerg HadError = true; 1588*7330f729Sjoerg goto retry; 1589*7330f729Sjoerg } 1590*7330f729Sjoerg 1591*7330f729Sjoerg Tok.Kind = MMToken::IntegerLiteral; 1592*7330f729Sjoerg Tok.IntegerValue = Value; 1593*7330f729Sjoerg break; 1594*7330f729Sjoerg } 1595*7330f729Sjoerg 1596*7330f729Sjoerg case tok::comment: 1597*7330f729Sjoerg goto retry; 1598*7330f729Sjoerg 1599*7330f729Sjoerg case tok::hash: 1600*7330f729Sjoerg // A module map can be terminated prematurely by 1601*7330f729Sjoerg // #pragma clang module contents 1602*7330f729Sjoerg // When building the module, we'll treat the rest of the file as the 1603*7330f729Sjoerg // contents of the module. 1604*7330f729Sjoerg { 1605*7330f729Sjoerg auto NextIsIdent = [&](StringRef Str) -> bool { 1606*7330f729Sjoerg L.LexFromRawLexer(LToken); 1607*7330f729Sjoerg return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && 1608*7330f729Sjoerg LToken.getRawIdentifier() == Str; 1609*7330f729Sjoerg }; 1610*7330f729Sjoerg if (NextIsIdent("pragma") && NextIsIdent("clang") && 1611*7330f729Sjoerg NextIsIdent("module") && NextIsIdent("contents")) { 1612*7330f729Sjoerg Tok.Kind = MMToken::EndOfFile; 1613*7330f729Sjoerg break; 1614*7330f729Sjoerg } 1615*7330f729Sjoerg } 1616*7330f729Sjoerg LLVM_FALLTHROUGH; 1617*7330f729Sjoerg 1618*7330f729Sjoerg default: 1619*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1620*7330f729Sjoerg HadError = true; 1621*7330f729Sjoerg goto retry; 1622*7330f729Sjoerg } 1623*7330f729Sjoerg 1624*7330f729Sjoerg return Result; 1625*7330f729Sjoerg } 1626*7330f729Sjoerg 1627*7330f729Sjoerg void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1628*7330f729Sjoerg unsigned braceDepth = 0; 1629*7330f729Sjoerg unsigned squareDepth = 0; 1630*7330f729Sjoerg do { 1631*7330f729Sjoerg switch (Tok.Kind) { 1632*7330f729Sjoerg case MMToken::EndOfFile: 1633*7330f729Sjoerg return; 1634*7330f729Sjoerg 1635*7330f729Sjoerg case MMToken::LBrace: 1636*7330f729Sjoerg if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1637*7330f729Sjoerg return; 1638*7330f729Sjoerg 1639*7330f729Sjoerg ++braceDepth; 1640*7330f729Sjoerg break; 1641*7330f729Sjoerg 1642*7330f729Sjoerg case MMToken::LSquare: 1643*7330f729Sjoerg if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1644*7330f729Sjoerg return; 1645*7330f729Sjoerg 1646*7330f729Sjoerg ++squareDepth; 1647*7330f729Sjoerg break; 1648*7330f729Sjoerg 1649*7330f729Sjoerg case MMToken::RBrace: 1650*7330f729Sjoerg if (braceDepth > 0) 1651*7330f729Sjoerg --braceDepth; 1652*7330f729Sjoerg else if (Tok.is(K)) 1653*7330f729Sjoerg return; 1654*7330f729Sjoerg break; 1655*7330f729Sjoerg 1656*7330f729Sjoerg case MMToken::RSquare: 1657*7330f729Sjoerg if (squareDepth > 0) 1658*7330f729Sjoerg --squareDepth; 1659*7330f729Sjoerg else if (Tok.is(K)) 1660*7330f729Sjoerg return; 1661*7330f729Sjoerg break; 1662*7330f729Sjoerg 1663*7330f729Sjoerg default: 1664*7330f729Sjoerg if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1665*7330f729Sjoerg return; 1666*7330f729Sjoerg break; 1667*7330f729Sjoerg } 1668*7330f729Sjoerg 1669*7330f729Sjoerg consumeToken(); 1670*7330f729Sjoerg } while (true); 1671*7330f729Sjoerg } 1672*7330f729Sjoerg 1673*7330f729Sjoerg /// Parse a module-id. 1674*7330f729Sjoerg /// 1675*7330f729Sjoerg /// module-id: 1676*7330f729Sjoerg /// identifier 1677*7330f729Sjoerg /// identifier '.' module-id 1678*7330f729Sjoerg /// 1679*7330f729Sjoerg /// \returns true if an error occurred, false otherwise. 1680*7330f729Sjoerg bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1681*7330f729Sjoerg Id.clear(); 1682*7330f729Sjoerg do { 1683*7330f729Sjoerg if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1684*7330f729Sjoerg Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1685*7330f729Sjoerg consumeToken(); 1686*7330f729Sjoerg } else { 1687*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1688*7330f729Sjoerg return true; 1689*7330f729Sjoerg } 1690*7330f729Sjoerg 1691*7330f729Sjoerg if (!Tok.is(MMToken::Period)) 1692*7330f729Sjoerg break; 1693*7330f729Sjoerg 1694*7330f729Sjoerg consumeToken(); 1695*7330f729Sjoerg } while (true); 1696*7330f729Sjoerg 1697*7330f729Sjoerg return false; 1698*7330f729Sjoerg } 1699*7330f729Sjoerg 1700*7330f729Sjoerg namespace { 1701*7330f729Sjoerg 1702*7330f729Sjoerg /// Enumerates the known attributes. 1703*7330f729Sjoerg enum AttributeKind { 1704*7330f729Sjoerg /// An unknown attribute. 1705*7330f729Sjoerg AT_unknown, 1706*7330f729Sjoerg 1707*7330f729Sjoerg /// The 'system' attribute. 1708*7330f729Sjoerg AT_system, 1709*7330f729Sjoerg 1710*7330f729Sjoerg /// The 'extern_c' attribute. 1711*7330f729Sjoerg AT_extern_c, 1712*7330f729Sjoerg 1713*7330f729Sjoerg /// The 'exhaustive' attribute. 1714*7330f729Sjoerg AT_exhaustive, 1715*7330f729Sjoerg 1716*7330f729Sjoerg /// The 'no_undeclared_includes' attribute. 1717*7330f729Sjoerg AT_no_undeclared_includes 1718*7330f729Sjoerg }; 1719*7330f729Sjoerg 1720*7330f729Sjoerg } // namespace 1721*7330f729Sjoerg 1722*7330f729Sjoerg /// Private modules are canonicalized as Foo_Private. Clang provides extra 1723*7330f729Sjoerg /// module map search logic to find the appropriate private module when PCH 1724*7330f729Sjoerg /// is used with implicit module maps. Warn when private modules are written 1725*7330f729Sjoerg /// in other ways (FooPrivate and Foo.Private), providing notes and fixits. 1726*7330f729Sjoerg void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc, 1727*7330f729Sjoerg SourceLocation FrameworkLoc) { 1728*7330f729Sjoerg auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical, 1729*7330f729Sjoerg const Module *M, SourceRange ReplLoc) { 1730*7330f729Sjoerg auto D = Diags.Report(ActiveModule->DefinitionLoc, 1731*7330f729Sjoerg diag::note_mmap_rename_top_level_private_module); 1732*7330f729Sjoerg D << BadName << M->Name; 1733*7330f729Sjoerg D << FixItHint::CreateReplacement(ReplLoc, Canonical); 1734*7330f729Sjoerg }; 1735*7330f729Sjoerg 1736*7330f729Sjoerg for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1737*7330f729Sjoerg auto const *M = E->getValue(); 1738*7330f729Sjoerg if (M->Directory != ActiveModule->Directory) 1739*7330f729Sjoerg continue; 1740*7330f729Sjoerg 1741*7330f729Sjoerg SmallString<128> FullName(ActiveModule->getFullModuleName()); 1742*7330f729Sjoerg if (!FullName.startswith(M->Name) && !FullName.endswith("Private")) 1743*7330f729Sjoerg continue; 1744*7330f729Sjoerg SmallString<128> FixedPrivModDecl; 1745*7330f729Sjoerg SmallString<128> Canonical(M->Name); 1746*7330f729Sjoerg Canonical.append("_Private"); 1747*7330f729Sjoerg 1748*7330f729Sjoerg // Foo.Private -> Foo_Private 1749*7330f729Sjoerg if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent && 1750*7330f729Sjoerg M->Name == ActiveModule->Parent->Name) { 1751*7330f729Sjoerg Diags.Report(ActiveModule->DefinitionLoc, 1752*7330f729Sjoerg diag::warn_mmap_mismatched_private_submodule) 1753*7330f729Sjoerg << FullName; 1754*7330f729Sjoerg 1755*7330f729Sjoerg SourceLocation FixItInitBegin = CurrModuleDeclLoc; 1756*7330f729Sjoerg if (FrameworkLoc.isValid()) 1757*7330f729Sjoerg FixItInitBegin = FrameworkLoc; 1758*7330f729Sjoerg if (ExplicitLoc.isValid()) 1759*7330f729Sjoerg FixItInitBegin = ExplicitLoc; 1760*7330f729Sjoerg 1761*7330f729Sjoerg if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework) 1762*7330f729Sjoerg FixedPrivModDecl.append("framework "); 1763*7330f729Sjoerg FixedPrivModDecl.append("module "); 1764*7330f729Sjoerg FixedPrivModDecl.append(Canonical); 1765*7330f729Sjoerg 1766*7330f729Sjoerg GenNoteAndFixIt(FullName, FixedPrivModDecl, M, 1767*7330f729Sjoerg SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc)); 1768*7330f729Sjoerg continue; 1769*7330f729Sjoerg } 1770*7330f729Sjoerg 1771*7330f729Sjoerg // FooPrivate and whatnots -> Foo_Private 1772*7330f729Sjoerg if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name && 1773*7330f729Sjoerg ActiveModule->Name != Canonical) { 1774*7330f729Sjoerg Diags.Report(ActiveModule->DefinitionLoc, 1775*7330f729Sjoerg diag::warn_mmap_mismatched_private_module_name) 1776*7330f729Sjoerg << ActiveModule->Name; 1777*7330f729Sjoerg GenNoteAndFixIt(ActiveModule->Name, Canonical, M, 1778*7330f729Sjoerg SourceRange(ActiveModule->DefinitionLoc)); 1779*7330f729Sjoerg } 1780*7330f729Sjoerg } 1781*7330f729Sjoerg } 1782*7330f729Sjoerg 1783*7330f729Sjoerg /// Parse a module declaration. 1784*7330f729Sjoerg /// 1785*7330f729Sjoerg /// module-declaration: 1786*7330f729Sjoerg /// 'extern' 'module' module-id string-literal 1787*7330f729Sjoerg /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1788*7330f729Sjoerg /// { module-member* } 1789*7330f729Sjoerg /// 1790*7330f729Sjoerg /// module-member: 1791*7330f729Sjoerg /// requires-declaration 1792*7330f729Sjoerg /// header-declaration 1793*7330f729Sjoerg /// submodule-declaration 1794*7330f729Sjoerg /// export-declaration 1795*7330f729Sjoerg /// export-as-declaration 1796*7330f729Sjoerg /// link-declaration 1797*7330f729Sjoerg /// 1798*7330f729Sjoerg /// submodule-declaration: 1799*7330f729Sjoerg /// module-declaration 1800*7330f729Sjoerg /// inferred-submodule-declaration 1801*7330f729Sjoerg void ModuleMapParser::parseModuleDecl() { 1802*7330f729Sjoerg assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1803*7330f729Sjoerg Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1804*7330f729Sjoerg if (Tok.is(MMToken::ExternKeyword)) { 1805*7330f729Sjoerg parseExternModuleDecl(); 1806*7330f729Sjoerg return; 1807*7330f729Sjoerg } 1808*7330f729Sjoerg 1809*7330f729Sjoerg // Parse 'explicit' or 'framework' keyword, if present. 1810*7330f729Sjoerg SourceLocation ExplicitLoc; 1811*7330f729Sjoerg SourceLocation FrameworkLoc; 1812*7330f729Sjoerg bool Explicit = false; 1813*7330f729Sjoerg bool Framework = false; 1814*7330f729Sjoerg 1815*7330f729Sjoerg // Parse 'explicit' keyword, if present. 1816*7330f729Sjoerg if (Tok.is(MMToken::ExplicitKeyword)) { 1817*7330f729Sjoerg ExplicitLoc = consumeToken(); 1818*7330f729Sjoerg Explicit = true; 1819*7330f729Sjoerg } 1820*7330f729Sjoerg 1821*7330f729Sjoerg // Parse 'framework' keyword, if present. 1822*7330f729Sjoerg if (Tok.is(MMToken::FrameworkKeyword)) { 1823*7330f729Sjoerg FrameworkLoc = consumeToken(); 1824*7330f729Sjoerg Framework = true; 1825*7330f729Sjoerg } 1826*7330f729Sjoerg 1827*7330f729Sjoerg // Parse 'module' keyword. 1828*7330f729Sjoerg if (!Tok.is(MMToken::ModuleKeyword)) { 1829*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1830*7330f729Sjoerg consumeToken(); 1831*7330f729Sjoerg HadError = true; 1832*7330f729Sjoerg return; 1833*7330f729Sjoerg } 1834*7330f729Sjoerg CurrModuleDeclLoc = consumeToken(); // 'module' keyword 1835*7330f729Sjoerg 1836*7330f729Sjoerg // If we have a wildcard for the module name, this is an inferred submodule. 1837*7330f729Sjoerg // Parse it. 1838*7330f729Sjoerg if (Tok.is(MMToken::Star)) 1839*7330f729Sjoerg return parseInferredModuleDecl(Framework, Explicit); 1840*7330f729Sjoerg 1841*7330f729Sjoerg // Parse the module name. 1842*7330f729Sjoerg ModuleId Id; 1843*7330f729Sjoerg if (parseModuleId(Id)) { 1844*7330f729Sjoerg HadError = true; 1845*7330f729Sjoerg return; 1846*7330f729Sjoerg } 1847*7330f729Sjoerg 1848*7330f729Sjoerg if (ActiveModule) { 1849*7330f729Sjoerg if (Id.size() > 1) { 1850*7330f729Sjoerg Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1851*7330f729Sjoerg << SourceRange(Id.front().second, Id.back().second); 1852*7330f729Sjoerg 1853*7330f729Sjoerg HadError = true; 1854*7330f729Sjoerg return; 1855*7330f729Sjoerg } 1856*7330f729Sjoerg } else if (Id.size() == 1 && Explicit) { 1857*7330f729Sjoerg // Top-level modules can't be explicit. 1858*7330f729Sjoerg Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1859*7330f729Sjoerg Explicit = false; 1860*7330f729Sjoerg ExplicitLoc = SourceLocation(); 1861*7330f729Sjoerg HadError = true; 1862*7330f729Sjoerg } 1863*7330f729Sjoerg 1864*7330f729Sjoerg Module *PreviousActiveModule = ActiveModule; 1865*7330f729Sjoerg if (Id.size() > 1) { 1866*7330f729Sjoerg // This module map defines a submodule. Go find the module of which it 1867*7330f729Sjoerg // is a submodule. 1868*7330f729Sjoerg ActiveModule = nullptr; 1869*7330f729Sjoerg const Module *TopLevelModule = nullptr; 1870*7330f729Sjoerg for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1871*7330f729Sjoerg if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1872*7330f729Sjoerg if (I == 0) 1873*7330f729Sjoerg TopLevelModule = Next; 1874*7330f729Sjoerg ActiveModule = Next; 1875*7330f729Sjoerg continue; 1876*7330f729Sjoerg } 1877*7330f729Sjoerg 1878*7330f729Sjoerg if (ActiveModule) { 1879*7330f729Sjoerg Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1880*7330f729Sjoerg << Id[I].first 1881*7330f729Sjoerg << ActiveModule->getTopLevelModule()->getFullModuleName(); 1882*7330f729Sjoerg } else { 1883*7330f729Sjoerg Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1884*7330f729Sjoerg } 1885*7330f729Sjoerg HadError = true; 1886*7330f729Sjoerg return; 1887*7330f729Sjoerg } 1888*7330f729Sjoerg 1889*7330f729Sjoerg if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1890*7330f729Sjoerg assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1891*7330f729Sjoerg "submodule defined in same file as 'module *' that allowed its " 1892*7330f729Sjoerg "top-level module"); 1893*7330f729Sjoerg Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1894*7330f729Sjoerg } 1895*7330f729Sjoerg } 1896*7330f729Sjoerg 1897*7330f729Sjoerg StringRef ModuleName = Id.back().first; 1898*7330f729Sjoerg SourceLocation ModuleNameLoc = Id.back().second; 1899*7330f729Sjoerg 1900*7330f729Sjoerg // Parse the optional attribute list. 1901*7330f729Sjoerg Attributes Attrs; 1902*7330f729Sjoerg if (parseOptionalAttributes(Attrs)) 1903*7330f729Sjoerg return; 1904*7330f729Sjoerg 1905*7330f729Sjoerg // Parse the opening brace. 1906*7330f729Sjoerg if (!Tok.is(MMToken::LBrace)) { 1907*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1908*7330f729Sjoerg << ModuleName; 1909*7330f729Sjoerg HadError = true; 1910*7330f729Sjoerg return; 1911*7330f729Sjoerg } 1912*7330f729Sjoerg SourceLocation LBraceLoc = consumeToken(); 1913*7330f729Sjoerg 1914*7330f729Sjoerg // Determine whether this (sub)module has already been defined. 1915*7330f729Sjoerg Module *ShadowingModule = nullptr; 1916*7330f729Sjoerg if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1917*7330f729Sjoerg // We might see a (re)definition of a module that we already have a 1918*7330f729Sjoerg // definition for in two cases: 1919*7330f729Sjoerg // - If we loaded one definition from an AST file and we've just found a 1920*7330f729Sjoerg // corresponding definition in a module map file, or 1921*7330f729Sjoerg bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid(); 1922*7330f729Sjoerg // - If we're building a (preprocessed) module and we've just loaded the 1923*7330f729Sjoerg // module map file from which it was created. 1924*7330f729Sjoerg bool ParsedAsMainInput = 1925*7330f729Sjoerg Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 1926*7330f729Sjoerg Map.LangOpts.CurrentModule == ModuleName && 1927*7330f729Sjoerg SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 1928*7330f729Sjoerg SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 1929*7330f729Sjoerg if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) { 1930*7330f729Sjoerg // Skip the module definition. 1931*7330f729Sjoerg skipUntil(MMToken::RBrace); 1932*7330f729Sjoerg if (Tok.is(MMToken::RBrace)) 1933*7330f729Sjoerg consumeToken(); 1934*7330f729Sjoerg else { 1935*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1936*7330f729Sjoerg Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1937*7330f729Sjoerg HadError = true; 1938*7330f729Sjoerg } 1939*7330f729Sjoerg return; 1940*7330f729Sjoerg } 1941*7330f729Sjoerg 1942*7330f729Sjoerg if (!Existing->Parent && Map.mayShadowNewModule(Existing)) { 1943*7330f729Sjoerg ShadowingModule = Existing; 1944*7330f729Sjoerg } else { 1945*7330f729Sjoerg // This is not a shawdowed module decl, it is an illegal redefinition. 1946*7330f729Sjoerg Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1947*7330f729Sjoerg << ModuleName; 1948*7330f729Sjoerg Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1949*7330f729Sjoerg 1950*7330f729Sjoerg // Skip the module definition. 1951*7330f729Sjoerg skipUntil(MMToken::RBrace); 1952*7330f729Sjoerg if (Tok.is(MMToken::RBrace)) 1953*7330f729Sjoerg consumeToken(); 1954*7330f729Sjoerg 1955*7330f729Sjoerg HadError = true; 1956*7330f729Sjoerg return; 1957*7330f729Sjoerg } 1958*7330f729Sjoerg } 1959*7330f729Sjoerg 1960*7330f729Sjoerg // Start defining this module. 1961*7330f729Sjoerg if (ShadowingModule) { 1962*7330f729Sjoerg ActiveModule = 1963*7330f729Sjoerg Map.createShadowedModule(ModuleName, Framework, ShadowingModule); 1964*7330f729Sjoerg } else { 1965*7330f729Sjoerg ActiveModule = 1966*7330f729Sjoerg Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit) 1967*7330f729Sjoerg .first; 1968*7330f729Sjoerg } 1969*7330f729Sjoerg 1970*7330f729Sjoerg ActiveModule->DefinitionLoc = ModuleNameLoc; 1971*7330f729Sjoerg if (Attrs.IsSystem || IsSystem) 1972*7330f729Sjoerg ActiveModule->IsSystem = true; 1973*7330f729Sjoerg if (Attrs.IsExternC) 1974*7330f729Sjoerg ActiveModule->IsExternC = true; 1975*7330f729Sjoerg if (Attrs.NoUndeclaredIncludes || 1976*7330f729Sjoerg (!ActiveModule->Parent && ModuleName == "Darwin")) 1977*7330f729Sjoerg ActiveModule->NoUndeclaredIncludes = true; 1978*7330f729Sjoerg ActiveModule->Directory = Directory; 1979*7330f729Sjoerg 1980*7330f729Sjoerg StringRef MapFileName(ModuleMapFile->getName()); 1981*7330f729Sjoerg if (MapFileName.endswith("module.private.modulemap") || 1982*7330f729Sjoerg MapFileName.endswith("module_private.map")) { 1983*7330f729Sjoerg ActiveModule->ModuleMapIsPrivate = true; 1984*7330f729Sjoerg } 1985*7330f729Sjoerg 1986*7330f729Sjoerg // Private modules named as FooPrivate, Foo.Private or similar are likely a 1987*7330f729Sjoerg // user error; provide warnings, notes and fixits to direct users to use 1988*7330f729Sjoerg // Foo_Private instead. 1989*7330f729Sjoerg SourceLocation StartLoc = 1990*7330f729Sjoerg SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); 1991*7330f729Sjoerg if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && 1992*7330f729Sjoerg !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule, 1993*7330f729Sjoerg StartLoc) && 1994*7330f729Sjoerg !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name, 1995*7330f729Sjoerg StartLoc) && 1996*7330f729Sjoerg ActiveModule->ModuleMapIsPrivate) 1997*7330f729Sjoerg diagnosePrivateModules(ExplicitLoc, FrameworkLoc); 1998*7330f729Sjoerg 1999*7330f729Sjoerg bool Done = false; 2000*7330f729Sjoerg do { 2001*7330f729Sjoerg switch (Tok.Kind) { 2002*7330f729Sjoerg case MMToken::EndOfFile: 2003*7330f729Sjoerg case MMToken::RBrace: 2004*7330f729Sjoerg Done = true; 2005*7330f729Sjoerg break; 2006*7330f729Sjoerg 2007*7330f729Sjoerg case MMToken::ConfigMacros: 2008*7330f729Sjoerg parseConfigMacros(); 2009*7330f729Sjoerg break; 2010*7330f729Sjoerg 2011*7330f729Sjoerg case MMToken::Conflict: 2012*7330f729Sjoerg parseConflict(); 2013*7330f729Sjoerg break; 2014*7330f729Sjoerg 2015*7330f729Sjoerg case MMToken::ExplicitKeyword: 2016*7330f729Sjoerg case MMToken::ExternKeyword: 2017*7330f729Sjoerg case MMToken::FrameworkKeyword: 2018*7330f729Sjoerg case MMToken::ModuleKeyword: 2019*7330f729Sjoerg parseModuleDecl(); 2020*7330f729Sjoerg break; 2021*7330f729Sjoerg 2022*7330f729Sjoerg case MMToken::ExportKeyword: 2023*7330f729Sjoerg parseExportDecl(); 2024*7330f729Sjoerg break; 2025*7330f729Sjoerg 2026*7330f729Sjoerg case MMToken::ExportAsKeyword: 2027*7330f729Sjoerg parseExportAsDecl(); 2028*7330f729Sjoerg break; 2029*7330f729Sjoerg 2030*7330f729Sjoerg case MMToken::UseKeyword: 2031*7330f729Sjoerg parseUseDecl(); 2032*7330f729Sjoerg break; 2033*7330f729Sjoerg 2034*7330f729Sjoerg case MMToken::RequiresKeyword: 2035*7330f729Sjoerg parseRequiresDecl(); 2036*7330f729Sjoerg break; 2037*7330f729Sjoerg 2038*7330f729Sjoerg case MMToken::TextualKeyword: 2039*7330f729Sjoerg parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 2040*7330f729Sjoerg break; 2041*7330f729Sjoerg 2042*7330f729Sjoerg case MMToken::UmbrellaKeyword: { 2043*7330f729Sjoerg SourceLocation UmbrellaLoc = consumeToken(); 2044*7330f729Sjoerg if (Tok.is(MMToken::HeaderKeyword)) 2045*7330f729Sjoerg parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 2046*7330f729Sjoerg else 2047*7330f729Sjoerg parseUmbrellaDirDecl(UmbrellaLoc); 2048*7330f729Sjoerg break; 2049*7330f729Sjoerg } 2050*7330f729Sjoerg 2051*7330f729Sjoerg case MMToken::ExcludeKeyword: 2052*7330f729Sjoerg parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 2053*7330f729Sjoerg break; 2054*7330f729Sjoerg 2055*7330f729Sjoerg case MMToken::PrivateKeyword: 2056*7330f729Sjoerg parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 2057*7330f729Sjoerg break; 2058*7330f729Sjoerg 2059*7330f729Sjoerg case MMToken::HeaderKeyword: 2060*7330f729Sjoerg parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 2061*7330f729Sjoerg break; 2062*7330f729Sjoerg 2063*7330f729Sjoerg case MMToken::LinkKeyword: 2064*7330f729Sjoerg parseLinkDecl(); 2065*7330f729Sjoerg break; 2066*7330f729Sjoerg 2067*7330f729Sjoerg default: 2068*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 2069*7330f729Sjoerg consumeToken(); 2070*7330f729Sjoerg break; 2071*7330f729Sjoerg } 2072*7330f729Sjoerg } while (!Done); 2073*7330f729Sjoerg 2074*7330f729Sjoerg if (Tok.is(MMToken::RBrace)) 2075*7330f729Sjoerg consumeToken(); 2076*7330f729Sjoerg else { 2077*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2078*7330f729Sjoerg Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2079*7330f729Sjoerg HadError = true; 2080*7330f729Sjoerg } 2081*7330f729Sjoerg 2082*7330f729Sjoerg // If the active module is a top-level framework, and there are no link 2083*7330f729Sjoerg // libraries, automatically link against the framework. 2084*7330f729Sjoerg if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 2085*7330f729Sjoerg ActiveModule->LinkLibraries.empty()) { 2086*7330f729Sjoerg inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 2087*7330f729Sjoerg } 2088*7330f729Sjoerg 2089*7330f729Sjoerg // If the module meets all requirements but is still unavailable, mark the 2090*7330f729Sjoerg // whole tree as unavailable to prevent it from building. 2091*7330f729Sjoerg if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 2092*7330f729Sjoerg ActiveModule->Parent) { 2093*7330f729Sjoerg ActiveModule->getTopLevelModule()->markUnavailable(); 2094*7330f729Sjoerg ActiveModule->getTopLevelModule()->MissingHeaders.append( 2095*7330f729Sjoerg ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 2096*7330f729Sjoerg } 2097*7330f729Sjoerg 2098*7330f729Sjoerg // We're done parsing this module. Pop back to the previous module. 2099*7330f729Sjoerg ActiveModule = PreviousActiveModule; 2100*7330f729Sjoerg } 2101*7330f729Sjoerg 2102*7330f729Sjoerg /// Parse an extern module declaration. 2103*7330f729Sjoerg /// 2104*7330f729Sjoerg /// extern module-declaration: 2105*7330f729Sjoerg /// 'extern' 'module' module-id string-literal 2106*7330f729Sjoerg void ModuleMapParser::parseExternModuleDecl() { 2107*7330f729Sjoerg assert(Tok.is(MMToken::ExternKeyword)); 2108*7330f729Sjoerg SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 2109*7330f729Sjoerg 2110*7330f729Sjoerg // Parse 'module' keyword. 2111*7330f729Sjoerg if (!Tok.is(MMToken::ModuleKeyword)) { 2112*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2113*7330f729Sjoerg consumeToken(); 2114*7330f729Sjoerg HadError = true; 2115*7330f729Sjoerg return; 2116*7330f729Sjoerg } 2117*7330f729Sjoerg consumeToken(); // 'module' keyword 2118*7330f729Sjoerg 2119*7330f729Sjoerg // Parse the module name. 2120*7330f729Sjoerg ModuleId Id; 2121*7330f729Sjoerg if (parseModuleId(Id)) { 2122*7330f729Sjoerg HadError = true; 2123*7330f729Sjoerg return; 2124*7330f729Sjoerg } 2125*7330f729Sjoerg 2126*7330f729Sjoerg // Parse the referenced module map file name. 2127*7330f729Sjoerg if (!Tok.is(MMToken::StringLiteral)) { 2128*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 2129*7330f729Sjoerg HadError = true; 2130*7330f729Sjoerg return; 2131*7330f729Sjoerg } 2132*7330f729Sjoerg std::string FileName = Tok.getString(); 2133*7330f729Sjoerg consumeToken(); // filename 2134*7330f729Sjoerg 2135*7330f729Sjoerg StringRef FileNameRef = FileName; 2136*7330f729Sjoerg SmallString<128> ModuleMapFileName; 2137*7330f729Sjoerg if (llvm::sys::path::is_relative(FileNameRef)) { 2138*7330f729Sjoerg ModuleMapFileName += Directory->getName(); 2139*7330f729Sjoerg llvm::sys::path::append(ModuleMapFileName, FileName); 2140*7330f729Sjoerg FileNameRef = ModuleMapFileName; 2141*7330f729Sjoerg } 2142*7330f729Sjoerg if (auto File = SourceMgr.getFileManager().getFile(FileNameRef)) 2143*7330f729Sjoerg Map.parseModuleMapFile( 2144*7330f729Sjoerg *File, /*IsSystem=*/false, 2145*7330f729Sjoerg Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 2146*7330f729Sjoerg ? Directory 2147*7330f729Sjoerg : (*File)->getDir(), 2148*7330f729Sjoerg FileID(), nullptr, ExternLoc); 2149*7330f729Sjoerg } 2150*7330f729Sjoerg 2151*7330f729Sjoerg /// Whether to add the requirement \p Feature to the module \p M. 2152*7330f729Sjoerg /// 2153*7330f729Sjoerg /// This preserves backwards compatibility for two hacks in the Darwin system 2154*7330f729Sjoerg /// module map files: 2155*7330f729Sjoerg /// 2156*7330f729Sjoerg /// 1. The use of 'requires excluded' to make headers non-modular, which 2157*7330f729Sjoerg /// should really be mapped to 'textual' now that we have this feature. We 2158*7330f729Sjoerg /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 2159*7330f729Sjoerg /// true. Later, this bit will be used to map all the headers inside this 2160*7330f729Sjoerg /// module to 'textual'. 2161*7330f729Sjoerg /// 2162*7330f729Sjoerg /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 2163*7330f729Sjoerg /// 2164*7330f729Sjoerg /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 2165*7330f729Sjoerg /// was never correct and causes issues now that we check it, so drop it. 2166*7330f729Sjoerg static bool shouldAddRequirement(Module *M, StringRef Feature, 2167*7330f729Sjoerg bool &IsRequiresExcludedHack) { 2168*7330f729Sjoerg if (Feature == "excluded" && 2169*7330f729Sjoerg (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 2170*7330f729Sjoerg M->fullModuleNameIs({"Tcl", "Private"}))) { 2171*7330f729Sjoerg IsRequiresExcludedHack = true; 2172*7330f729Sjoerg return false; 2173*7330f729Sjoerg } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 2174*7330f729Sjoerg return false; 2175*7330f729Sjoerg } 2176*7330f729Sjoerg 2177*7330f729Sjoerg return true; 2178*7330f729Sjoerg } 2179*7330f729Sjoerg 2180*7330f729Sjoerg /// Parse a requires declaration. 2181*7330f729Sjoerg /// 2182*7330f729Sjoerg /// requires-declaration: 2183*7330f729Sjoerg /// 'requires' feature-list 2184*7330f729Sjoerg /// 2185*7330f729Sjoerg /// feature-list: 2186*7330f729Sjoerg /// feature ',' feature-list 2187*7330f729Sjoerg /// feature 2188*7330f729Sjoerg /// 2189*7330f729Sjoerg /// feature: 2190*7330f729Sjoerg /// '!'[opt] identifier 2191*7330f729Sjoerg void ModuleMapParser::parseRequiresDecl() { 2192*7330f729Sjoerg assert(Tok.is(MMToken::RequiresKeyword)); 2193*7330f729Sjoerg 2194*7330f729Sjoerg // Parse 'requires' keyword. 2195*7330f729Sjoerg consumeToken(); 2196*7330f729Sjoerg 2197*7330f729Sjoerg // Parse the feature-list. 2198*7330f729Sjoerg do { 2199*7330f729Sjoerg bool RequiredState = true; 2200*7330f729Sjoerg if (Tok.is(MMToken::Exclaim)) { 2201*7330f729Sjoerg RequiredState = false; 2202*7330f729Sjoerg consumeToken(); 2203*7330f729Sjoerg } 2204*7330f729Sjoerg 2205*7330f729Sjoerg if (!Tok.is(MMToken::Identifier)) { 2206*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 2207*7330f729Sjoerg HadError = true; 2208*7330f729Sjoerg return; 2209*7330f729Sjoerg } 2210*7330f729Sjoerg 2211*7330f729Sjoerg // Consume the feature name. 2212*7330f729Sjoerg std::string Feature = Tok.getString(); 2213*7330f729Sjoerg consumeToken(); 2214*7330f729Sjoerg 2215*7330f729Sjoerg bool IsRequiresExcludedHack = false; 2216*7330f729Sjoerg bool ShouldAddRequirement = 2217*7330f729Sjoerg shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2218*7330f729Sjoerg 2219*7330f729Sjoerg if (IsRequiresExcludedHack) 2220*7330f729Sjoerg UsesRequiresExcludedHack.insert(ActiveModule); 2221*7330f729Sjoerg 2222*7330f729Sjoerg if (ShouldAddRequirement) { 2223*7330f729Sjoerg // Add this feature. 2224*7330f729Sjoerg ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2225*7330f729Sjoerg *Map.Target); 2226*7330f729Sjoerg } 2227*7330f729Sjoerg 2228*7330f729Sjoerg if (!Tok.is(MMToken::Comma)) 2229*7330f729Sjoerg break; 2230*7330f729Sjoerg 2231*7330f729Sjoerg // Consume the comma. 2232*7330f729Sjoerg consumeToken(); 2233*7330f729Sjoerg } while (true); 2234*7330f729Sjoerg } 2235*7330f729Sjoerg 2236*7330f729Sjoerg /// Parse a header declaration. 2237*7330f729Sjoerg /// 2238*7330f729Sjoerg /// header-declaration: 2239*7330f729Sjoerg /// 'textual'[opt] 'header' string-literal 2240*7330f729Sjoerg /// 'private' 'textual'[opt] 'header' string-literal 2241*7330f729Sjoerg /// 'exclude' 'header' string-literal 2242*7330f729Sjoerg /// 'umbrella' 'header' string-literal 2243*7330f729Sjoerg /// 2244*7330f729Sjoerg /// FIXME: Support 'private textual header'. 2245*7330f729Sjoerg void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2246*7330f729Sjoerg SourceLocation LeadingLoc) { 2247*7330f729Sjoerg // We've already consumed the first token. 2248*7330f729Sjoerg ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2249*7330f729Sjoerg if (LeadingToken == MMToken::PrivateKeyword) { 2250*7330f729Sjoerg Role = ModuleMap::PrivateHeader; 2251*7330f729Sjoerg // 'private' may optionally be followed by 'textual'. 2252*7330f729Sjoerg if (Tok.is(MMToken::TextualKeyword)) { 2253*7330f729Sjoerg LeadingToken = Tok.Kind; 2254*7330f729Sjoerg consumeToken(); 2255*7330f729Sjoerg } 2256*7330f729Sjoerg } 2257*7330f729Sjoerg 2258*7330f729Sjoerg if (LeadingToken == MMToken::TextualKeyword) 2259*7330f729Sjoerg Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2260*7330f729Sjoerg 2261*7330f729Sjoerg if (UsesRequiresExcludedHack.count(ActiveModule)) { 2262*7330f729Sjoerg // Mark this header 'textual' (see doc comment for 2263*7330f729Sjoerg // Module::UsesRequiresExcludedHack). 2264*7330f729Sjoerg Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2265*7330f729Sjoerg } 2266*7330f729Sjoerg 2267*7330f729Sjoerg if (LeadingToken != MMToken::HeaderKeyword) { 2268*7330f729Sjoerg if (!Tok.is(MMToken::HeaderKeyword)) { 2269*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2270*7330f729Sjoerg << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2271*7330f729Sjoerg LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2272*7330f729Sjoerg LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2273*7330f729Sjoerg return; 2274*7330f729Sjoerg } 2275*7330f729Sjoerg consumeToken(); 2276*7330f729Sjoerg } 2277*7330f729Sjoerg 2278*7330f729Sjoerg // Parse the header name. 2279*7330f729Sjoerg if (!Tok.is(MMToken::StringLiteral)) { 2280*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2281*7330f729Sjoerg << "header"; 2282*7330f729Sjoerg HadError = true; 2283*7330f729Sjoerg return; 2284*7330f729Sjoerg } 2285*7330f729Sjoerg Module::UnresolvedHeaderDirective Header; 2286*7330f729Sjoerg Header.FileName = Tok.getString(); 2287*7330f729Sjoerg Header.FileNameLoc = consumeToken(); 2288*7330f729Sjoerg Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2289*7330f729Sjoerg Header.Kind = 2290*7330f729Sjoerg (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded 2291*7330f729Sjoerg : Map.headerRoleToKind(Role)); 2292*7330f729Sjoerg 2293*7330f729Sjoerg // Check whether we already have an umbrella. 2294*7330f729Sjoerg if (Header.IsUmbrella && ActiveModule->Umbrella) { 2295*7330f729Sjoerg Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2296*7330f729Sjoerg << ActiveModule->getFullModuleName(); 2297*7330f729Sjoerg HadError = true; 2298*7330f729Sjoerg return; 2299*7330f729Sjoerg } 2300*7330f729Sjoerg 2301*7330f729Sjoerg // If we were given stat information, parse it so we can skip looking for 2302*7330f729Sjoerg // the file. 2303*7330f729Sjoerg if (Tok.is(MMToken::LBrace)) { 2304*7330f729Sjoerg SourceLocation LBraceLoc = consumeToken(); 2305*7330f729Sjoerg 2306*7330f729Sjoerg while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2307*7330f729Sjoerg enum Attribute { Size, ModTime, Unknown }; 2308*7330f729Sjoerg StringRef Str = Tok.getString(); 2309*7330f729Sjoerg SourceLocation Loc = consumeToken(); 2310*7330f729Sjoerg switch (llvm::StringSwitch<Attribute>(Str) 2311*7330f729Sjoerg .Case("size", Size) 2312*7330f729Sjoerg .Case("mtime", ModTime) 2313*7330f729Sjoerg .Default(Unknown)) { 2314*7330f729Sjoerg case Size: 2315*7330f729Sjoerg if (Header.Size) 2316*7330f729Sjoerg Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2317*7330f729Sjoerg if (!Tok.is(MMToken::IntegerLiteral)) { 2318*7330f729Sjoerg Diags.Report(Tok.getLocation(), 2319*7330f729Sjoerg diag::err_mmap_invalid_header_attribute_value) << Str; 2320*7330f729Sjoerg skipUntil(MMToken::RBrace); 2321*7330f729Sjoerg break; 2322*7330f729Sjoerg } 2323*7330f729Sjoerg Header.Size = Tok.getInteger(); 2324*7330f729Sjoerg consumeToken(); 2325*7330f729Sjoerg break; 2326*7330f729Sjoerg 2327*7330f729Sjoerg case ModTime: 2328*7330f729Sjoerg if (Header.ModTime) 2329*7330f729Sjoerg Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2330*7330f729Sjoerg if (!Tok.is(MMToken::IntegerLiteral)) { 2331*7330f729Sjoerg Diags.Report(Tok.getLocation(), 2332*7330f729Sjoerg diag::err_mmap_invalid_header_attribute_value) << Str; 2333*7330f729Sjoerg skipUntil(MMToken::RBrace); 2334*7330f729Sjoerg break; 2335*7330f729Sjoerg } 2336*7330f729Sjoerg Header.ModTime = Tok.getInteger(); 2337*7330f729Sjoerg consumeToken(); 2338*7330f729Sjoerg break; 2339*7330f729Sjoerg 2340*7330f729Sjoerg case Unknown: 2341*7330f729Sjoerg Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2342*7330f729Sjoerg skipUntil(MMToken::RBrace); 2343*7330f729Sjoerg break; 2344*7330f729Sjoerg } 2345*7330f729Sjoerg } 2346*7330f729Sjoerg 2347*7330f729Sjoerg if (Tok.is(MMToken::RBrace)) 2348*7330f729Sjoerg consumeToken(); 2349*7330f729Sjoerg else { 2350*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2351*7330f729Sjoerg Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2352*7330f729Sjoerg HadError = true; 2353*7330f729Sjoerg } 2354*7330f729Sjoerg } 2355*7330f729Sjoerg 2356*7330f729Sjoerg bool NeedsFramework = false; 2357*7330f729Sjoerg Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework); 2358*7330f729Sjoerg 2359*7330f729Sjoerg if (NeedsFramework && ActiveModule) 2360*7330f729Sjoerg Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword) 2361*7330f729Sjoerg << ActiveModule->getFullModuleName() 2362*7330f729Sjoerg << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module"); 2363*7330f729Sjoerg } 2364*7330f729Sjoerg 2365*7330f729Sjoerg static int compareModuleHeaders(const Module::Header *A, 2366*7330f729Sjoerg const Module::Header *B) { 2367*7330f729Sjoerg return A->NameAsWritten.compare(B->NameAsWritten); 2368*7330f729Sjoerg } 2369*7330f729Sjoerg 2370*7330f729Sjoerg /// Parse an umbrella directory declaration. 2371*7330f729Sjoerg /// 2372*7330f729Sjoerg /// umbrella-dir-declaration: 2373*7330f729Sjoerg /// umbrella string-literal 2374*7330f729Sjoerg void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2375*7330f729Sjoerg // Parse the directory name. 2376*7330f729Sjoerg if (!Tok.is(MMToken::StringLiteral)) { 2377*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2378*7330f729Sjoerg << "umbrella"; 2379*7330f729Sjoerg HadError = true; 2380*7330f729Sjoerg return; 2381*7330f729Sjoerg } 2382*7330f729Sjoerg 2383*7330f729Sjoerg std::string DirName = Tok.getString(); 2384*7330f729Sjoerg SourceLocation DirNameLoc = consumeToken(); 2385*7330f729Sjoerg 2386*7330f729Sjoerg // Check whether we already have an umbrella. 2387*7330f729Sjoerg if (ActiveModule->Umbrella) { 2388*7330f729Sjoerg Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2389*7330f729Sjoerg << ActiveModule->getFullModuleName(); 2390*7330f729Sjoerg HadError = true; 2391*7330f729Sjoerg return; 2392*7330f729Sjoerg } 2393*7330f729Sjoerg 2394*7330f729Sjoerg // Look for this file. 2395*7330f729Sjoerg const DirectoryEntry *Dir = nullptr; 2396*7330f729Sjoerg if (llvm::sys::path::is_absolute(DirName)) { 2397*7330f729Sjoerg if (auto D = SourceMgr.getFileManager().getDirectory(DirName)) 2398*7330f729Sjoerg Dir = *D; 2399*7330f729Sjoerg } else { 2400*7330f729Sjoerg SmallString<128> PathName; 2401*7330f729Sjoerg PathName = Directory->getName(); 2402*7330f729Sjoerg llvm::sys::path::append(PathName, DirName); 2403*7330f729Sjoerg if (auto D = SourceMgr.getFileManager().getDirectory(PathName)) 2404*7330f729Sjoerg Dir = *D; 2405*7330f729Sjoerg } 2406*7330f729Sjoerg 2407*7330f729Sjoerg if (!Dir) { 2408*7330f729Sjoerg Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2409*7330f729Sjoerg << DirName; 2410*7330f729Sjoerg return; 2411*7330f729Sjoerg } 2412*7330f729Sjoerg 2413*7330f729Sjoerg if (UsesRequiresExcludedHack.count(ActiveModule)) { 2414*7330f729Sjoerg // Mark this header 'textual' (see doc comment for 2415*7330f729Sjoerg // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2416*7330f729Sjoerg // directory is relatively expensive, in practice this only applies to the 2417*7330f729Sjoerg // uncommonly used Tcl module on Darwin platforms. 2418*7330f729Sjoerg std::error_code EC; 2419*7330f729Sjoerg SmallVector<Module::Header, 6> Headers; 2420*7330f729Sjoerg llvm::vfs::FileSystem &FS = 2421*7330f729Sjoerg SourceMgr.getFileManager().getVirtualFileSystem(); 2422*7330f729Sjoerg for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2423*7330f729Sjoerg I != E && !EC; I.increment(EC)) { 2424*7330f729Sjoerg if (auto FE = SourceMgr.getFileManager().getFile(I->path())) { 2425*7330f729Sjoerg 2426*7330f729Sjoerg Module::Header Header = {I->path(), *FE}; 2427*7330f729Sjoerg Headers.push_back(std::move(Header)); 2428*7330f729Sjoerg } 2429*7330f729Sjoerg } 2430*7330f729Sjoerg 2431*7330f729Sjoerg // Sort header paths so that the pcm doesn't depend on iteration order. 2432*7330f729Sjoerg llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2433*7330f729Sjoerg 2434*7330f729Sjoerg for (auto &Header : Headers) 2435*7330f729Sjoerg Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2436*7330f729Sjoerg return; 2437*7330f729Sjoerg } 2438*7330f729Sjoerg 2439*7330f729Sjoerg if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 2440*7330f729Sjoerg Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2441*7330f729Sjoerg << OwningModule->getFullModuleName(); 2442*7330f729Sjoerg HadError = true; 2443*7330f729Sjoerg return; 2444*7330f729Sjoerg } 2445*7330f729Sjoerg 2446*7330f729Sjoerg // Record this umbrella directory. 2447*7330f729Sjoerg Map.setUmbrellaDir(ActiveModule, Dir, DirName); 2448*7330f729Sjoerg } 2449*7330f729Sjoerg 2450*7330f729Sjoerg /// Parse a module export declaration. 2451*7330f729Sjoerg /// 2452*7330f729Sjoerg /// export-declaration: 2453*7330f729Sjoerg /// 'export' wildcard-module-id 2454*7330f729Sjoerg /// 2455*7330f729Sjoerg /// wildcard-module-id: 2456*7330f729Sjoerg /// identifier 2457*7330f729Sjoerg /// '*' 2458*7330f729Sjoerg /// identifier '.' wildcard-module-id 2459*7330f729Sjoerg void ModuleMapParser::parseExportDecl() { 2460*7330f729Sjoerg assert(Tok.is(MMToken::ExportKeyword)); 2461*7330f729Sjoerg SourceLocation ExportLoc = consumeToken(); 2462*7330f729Sjoerg 2463*7330f729Sjoerg // Parse the module-id with an optional wildcard at the end. 2464*7330f729Sjoerg ModuleId ParsedModuleId; 2465*7330f729Sjoerg bool Wildcard = false; 2466*7330f729Sjoerg do { 2467*7330f729Sjoerg // FIXME: Support string-literal module names here. 2468*7330f729Sjoerg if (Tok.is(MMToken::Identifier)) { 2469*7330f729Sjoerg ParsedModuleId.push_back(std::make_pair(Tok.getString(), 2470*7330f729Sjoerg Tok.getLocation())); 2471*7330f729Sjoerg consumeToken(); 2472*7330f729Sjoerg 2473*7330f729Sjoerg if (Tok.is(MMToken::Period)) { 2474*7330f729Sjoerg consumeToken(); 2475*7330f729Sjoerg continue; 2476*7330f729Sjoerg } 2477*7330f729Sjoerg 2478*7330f729Sjoerg break; 2479*7330f729Sjoerg } 2480*7330f729Sjoerg 2481*7330f729Sjoerg if(Tok.is(MMToken::Star)) { 2482*7330f729Sjoerg Wildcard = true; 2483*7330f729Sjoerg consumeToken(); 2484*7330f729Sjoerg break; 2485*7330f729Sjoerg } 2486*7330f729Sjoerg 2487*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2488*7330f729Sjoerg HadError = true; 2489*7330f729Sjoerg return; 2490*7330f729Sjoerg } while (true); 2491*7330f729Sjoerg 2492*7330f729Sjoerg Module::UnresolvedExportDecl Unresolved = { 2493*7330f729Sjoerg ExportLoc, ParsedModuleId, Wildcard 2494*7330f729Sjoerg }; 2495*7330f729Sjoerg ActiveModule->UnresolvedExports.push_back(Unresolved); 2496*7330f729Sjoerg } 2497*7330f729Sjoerg 2498*7330f729Sjoerg /// Parse a module export_as declaration. 2499*7330f729Sjoerg /// 2500*7330f729Sjoerg /// export-as-declaration: 2501*7330f729Sjoerg /// 'export_as' identifier 2502*7330f729Sjoerg void ModuleMapParser::parseExportAsDecl() { 2503*7330f729Sjoerg assert(Tok.is(MMToken::ExportAsKeyword)); 2504*7330f729Sjoerg consumeToken(); 2505*7330f729Sjoerg 2506*7330f729Sjoerg if (!Tok.is(MMToken::Identifier)) { 2507*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2508*7330f729Sjoerg HadError = true; 2509*7330f729Sjoerg return; 2510*7330f729Sjoerg } 2511*7330f729Sjoerg 2512*7330f729Sjoerg if (ActiveModule->Parent) { 2513*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); 2514*7330f729Sjoerg consumeToken(); 2515*7330f729Sjoerg return; 2516*7330f729Sjoerg } 2517*7330f729Sjoerg 2518*7330f729Sjoerg if (!ActiveModule->ExportAsModule.empty()) { 2519*7330f729Sjoerg if (ActiveModule->ExportAsModule == Tok.getString()) { 2520*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) 2521*7330f729Sjoerg << ActiveModule->Name << Tok.getString(); 2522*7330f729Sjoerg } else { 2523*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) 2524*7330f729Sjoerg << ActiveModule->Name << ActiveModule->ExportAsModule 2525*7330f729Sjoerg << Tok.getString(); 2526*7330f729Sjoerg } 2527*7330f729Sjoerg } 2528*7330f729Sjoerg 2529*7330f729Sjoerg ActiveModule->ExportAsModule = Tok.getString(); 2530*7330f729Sjoerg Map.addLinkAsDependency(ActiveModule); 2531*7330f729Sjoerg 2532*7330f729Sjoerg consumeToken(); 2533*7330f729Sjoerg } 2534*7330f729Sjoerg 2535*7330f729Sjoerg /// Parse a module use declaration. 2536*7330f729Sjoerg /// 2537*7330f729Sjoerg /// use-declaration: 2538*7330f729Sjoerg /// 'use' wildcard-module-id 2539*7330f729Sjoerg void ModuleMapParser::parseUseDecl() { 2540*7330f729Sjoerg assert(Tok.is(MMToken::UseKeyword)); 2541*7330f729Sjoerg auto KWLoc = consumeToken(); 2542*7330f729Sjoerg // Parse the module-id. 2543*7330f729Sjoerg ModuleId ParsedModuleId; 2544*7330f729Sjoerg parseModuleId(ParsedModuleId); 2545*7330f729Sjoerg 2546*7330f729Sjoerg if (ActiveModule->Parent) 2547*7330f729Sjoerg Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2548*7330f729Sjoerg else 2549*7330f729Sjoerg ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2550*7330f729Sjoerg } 2551*7330f729Sjoerg 2552*7330f729Sjoerg /// Parse a link declaration. 2553*7330f729Sjoerg /// 2554*7330f729Sjoerg /// module-declaration: 2555*7330f729Sjoerg /// 'link' 'framework'[opt] string-literal 2556*7330f729Sjoerg void ModuleMapParser::parseLinkDecl() { 2557*7330f729Sjoerg assert(Tok.is(MMToken::LinkKeyword)); 2558*7330f729Sjoerg SourceLocation LinkLoc = consumeToken(); 2559*7330f729Sjoerg 2560*7330f729Sjoerg // Parse the optional 'framework' keyword. 2561*7330f729Sjoerg bool IsFramework = false; 2562*7330f729Sjoerg if (Tok.is(MMToken::FrameworkKeyword)) { 2563*7330f729Sjoerg consumeToken(); 2564*7330f729Sjoerg IsFramework = true; 2565*7330f729Sjoerg } 2566*7330f729Sjoerg 2567*7330f729Sjoerg // Parse the library name 2568*7330f729Sjoerg if (!Tok.is(MMToken::StringLiteral)) { 2569*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2570*7330f729Sjoerg << IsFramework << SourceRange(LinkLoc); 2571*7330f729Sjoerg HadError = true; 2572*7330f729Sjoerg return; 2573*7330f729Sjoerg } 2574*7330f729Sjoerg 2575*7330f729Sjoerg std::string LibraryName = Tok.getString(); 2576*7330f729Sjoerg consumeToken(); 2577*7330f729Sjoerg ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2578*7330f729Sjoerg IsFramework)); 2579*7330f729Sjoerg } 2580*7330f729Sjoerg 2581*7330f729Sjoerg /// Parse a configuration macro declaration. 2582*7330f729Sjoerg /// 2583*7330f729Sjoerg /// module-declaration: 2584*7330f729Sjoerg /// 'config_macros' attributes[opt] config-macro-list? 2585*7330f729Sjoerg /// 2586*7330f729Sjoerg /// config-macro-list: 2587*7330f729Sjoerg /// identifier (',' identifier)? 2588*7330f729Sjoerg void ModuleMapParser::parseConfigMacros() { 2589*7330f729Sjoerg assert(Tok.is(MMToken::ConfigMacros)); 2590*7330f729Sjoerg SourceLocation ConfigMacrosLoc = consumeToken(); 2591*7330f729Sjoerg 2592*7330f729Sjoerg // Only top-level modules can have configuration macros. 2593*7330f729Sjoerg if (ActiveModule->Parent) { 2594*7330f729Sjoerg Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2595*7330f729Sjoerg } 2596*7330f729Sjoerg 2597*7330f729Sjoerg // Parse the optional attributes. 2598*7330f729Sjoerg Attributes Attrs; 2599*7330f729Sjoerg if (parseOptionalAttributes(Attrs)) 2600*7330f729Sjoerg return; 2601*7330f729Sjoerg 2602*7330f729Sjoerg if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2603*7330f729Sjoerg ActiveModule->ConfigMacrosExhaustive = true; 2604*7330f729Sjoerg } 2605*7330f729Sjoerg 2606*7330f729Sjoerg // If we don't have an identifier, we're done. 2607*7330f729Sjoerg // FIXME: Support macros with the same name as a keyword here. 2608*7330f729Sjoerg if (!Tok.is(MMToken::Identifier)) 2609*7330f729Sjoerg return; 2610*7330f729Sjoerg 2611*7330f729Sjoerg // Consume the first identifier. 2612*7330f729Sjoerg if (!ActiveModule->Parent) { 2613*7330f729Sjoerg ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2614*7330f729Sjoerg } 2615*7330f729Sjoerg consumeToken(); 2616*7330f729Sjoerg 2617*7330f729Sjoerg do { 2618*7330f729Sjoerg // If there's a comma, consume it. 2619*7330f729Sjoerg if (!Tok.is(MMToken::Comma)) 2620*7330f729Sjoerg break; 2621*7330f729Sjoerg consumeToken(); 2622*7330f729Sjoerg 2623*7330f729Sjoerg // We expect to see a macro name here. 2624*7330f729Sjoerg // FIXME: Support macros with the same name as a keyword here. 2625*7330f729Sjoerg if (!Tok.is(MMToken::Identifier)) { 2626*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2627*7330f729Sjoerg break; 2628*7330f729Sjoerg } 2629*7330f729Sjoerg 2630*7330f729Sjoerg // Consume the macro name. 2631*7330f729Sjoerg if (!ActiveModule->Parent) { 2632*7330f729Sjoerg ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2633*7330f729Sjoerg } 2634*7330f729Sjoerg consumeToken(); 2635*7330f729Sjoerg } while (true); 2636*7330f729Sjoerg } 2637*7330f729Sjoerg 2638*7330f729Sjoerg /// Format a module-id into a string. 2639*7330f729Sjoerg static std::string formatModuleId(const ModuleId &Id) { 2640*7330f729Sjoerg std::string result; 2641*7330f729Sjoerg { 2642*7330f729Sjoerg llvm::raw_string_ostream OS(result); 2643*7330f729Sjoerg 2644*7330f729Sjoerg for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2645*7330f729Sjoerg if (I) 2646*7330f729Sjoerg OS << "."; 2647*7330f729Sjoerg OS << Id[I].first; 2648*7330f729Sjoerg } 2649*7330f729Sjoerg } 2650*7330f729Sjoerg 2651*7330f729Sjoerg return result; 2652*7330f729Sjoerg } 2653*7330f729Sjoerg 2654*7330f729Sjoerg /// Parse a conflict declaration. 2655*7330f729Sjoerg /// 2656*7330f729Sjoerg /// module-declaration: 2657*7330f729Sjoerg /// 'conflict' module-id ',' string-literal 2658*7330f729Sjoerg void ModuleMapParser::parseConflict() { 2659*7330f729Sjoerg assert(Tok.is(MMToken::Conflict)); 2660*7330f729Sjoerg SourceLocation ConflictLoc = consumeToken(); 2661*7330f729Sjoerg Module::UnresolvedConflict Conflict; 2662*7330f729Sjoerg 2663*7330f729Sjoerg // Parse the module-id. 2664*7330f729Sjoerg if (parseModuleId(Conflict.Id)) 2665*7330f729Sjoerg return; 2666*7330f729Sjoerg 2667*7330f729Sjoerg // Parse the ','. 2668*7330f729Sjoerg if (!Tok.is(MMToken::Comma)) { 2669*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2670*7330f729Sjoerg << SourceRange(ConflictLoc); 2671*7330f729Sjoerg return; 2672*7330f729Sjoerg } 2673*7330f729Sjoerg consumeToken(); 2674*7330f729Sjoerg 2675*7330f729Sjoerg // Parse the message. 2676*7330f729Sjoerg if (!Tok.is(MMToken::StringLiteral)) { 2677*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2678*7330f729Sjoerg << formatModuleId(Conflict.Id); 2679*7330f729Sjoerg return; 2680*7330f729Sjoerg } 2681*7330f729Sjoerg Conflict.Message = Tok.getString().str(); 2682*7330f729Sjoerg consumeToken(); 2683*7330f729Sjoerg 2684*7330f729Sjoerg // Add this unresolved conflict. 2685*7330f729Sjoerg ActiveModule->UnresolvedConflicts.push_back(Conflict); 2686*7330f729Sjoerg } 2687*7330f729Sjoerg 2688*7330f729Sjoerg /// Parse an inferred module declaration (wildcard modules). 2689*7330f729Sjoerg /// 2690*7330f729Sjoerg /// module-declaration: 2691*7330f729Sjoerg /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2692*7330f729Sjoerg /// { inferred-module-member* } 2693*7330f729Sjoerg /// 2694*7330f729Sjoerg /// inferred-module-member: 2695*7330f729Sjoerg /// 'export' '*' 2696*7330f729Sjoerg /// 'exclude' identifier 2697*7330f729Sjoerg void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2698*7330f729Sjoerg assert(Tok.is(MMToken::Star)); 2699*7330f729Sjoerg SourceLocation StarLoc = consumeToken(); 2700*7330f729Sjoerg bool Failed = false; 2701*7330f729Sjoerg 2702*7330f729Sjoerg // Inferred modules must be submodules. 2703*7330f729Sjoerg if (!ActiveModule && !Framework) { 2704*7330f729Sjoerg Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2705*7330f729Sjoerg Failed = true; 2706*7330f729Sjoerg } 2707*7330f729Sjoerg 2708*7330f729Sjoerg if (ActiveModule) { 2709*7330f729Sjoerg // Inferred modules must have umbrella directories. 2710*7330f729Sjoerg if (!Failed && ActiveModule->IsAvailable && 2711*7330f729Sjoerg !ActiveModule->getUmbrellaDir()) { 2712*7330f729Sjoerg Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2713*7330f729Sjoerg Failed = true; 2714*7330f729Sjoerg } 2715*7330f729Sjoerg 2716*7330f729Sjoerg // Check for redefinition of an inferred module. 2717*7330f729Sjoerg if (!Failed && ActiveModule->InferSubmodules) { 2718*7330f729Sjoerg Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2719*7330f729Sjoerg if (ActiveModule->InferredSubmoduleLoc.isValid()) 2720*7330f729Sjoerg Diags.Report(ActiveModule->InferredSubmoduleLoc, 2721*7330f729Sjoerg diag::note_mmap_prev_definition); 2722*7330f729Sjoerg Failed = true; 2723*7330f729Sjoerg } 2724*7330f729Sjoerg 2725*7330f729Sjoerg // Check for the 'framework' keyword, which is not permitted here. 2726*7330f729Sjoerg if (Framework) { 2727*7330f729Sjoerg Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2728*7330f729Sjoerg Framework = false; 2729*7330f729Sjoerg } 2730*7330f729Sjoerg } else if (Explicit) { 2731*7330f729Sjoerg Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2732*7330f729Sjoerg Explicit = false; 2733*7330f729Sjoerg } 2734*7330f729Sjoerg 2735*7330f729Sjoerg // If there were any problems with this inferred submodule, skip its body. 2736*7330f729Sjoerg if (Failed) { 2737*7330f729Sjoerg if (Tok.is(MMToken::LBrace)) { 2738*7330f729Sjoerg consumeToken(); 2739*7330f729Sjoerg skipUntil(MMToken::RBrace); 2740*7330f729Sjoerg if (Tok.is(MMToken::RBrace)) 2741*7330f729Sjoerg consumeToken(); 2742*7330f729Sjoerg } 2743*7330f729Sjoerg HadError = true; 2744*7330f729Sjoerg return; 2745*7330f729Sjoerg } 2746*7330f729Sjoerg 2747*7330f729Sjoerg // Parse optional attributes. 2748*7330f729Sjoerg Attributes Attrs; 2749*7330f729Sjoerg if (parseOptionalAttributes(Attrs)) 2750*7330f729Sjoerg return; 2751*7330f729Sjoerg 2752*7330f729Sjoerg if (ActiveModule) { 2753*7330f729Sjoerg // Note that we have an inferred submodule. 2754*7330f729Sjoerg ActiveModule->InferSubmodules = true; 2755*7330f729Sjoerg ActiveModule->InferredSubmoduleLoc = StarLoc; 2756*7330f729Sjoerg ActiveModule->InferExplicitSubmodules = Explicit; 2757*7330f729Sjoerg } else { 2758*7330f729Sjoerg // We'll be inferring framework modules for this directory. 2759*7330f729Sjoerg Map.InferredDirectories[Directory].InferModules = true; 2760*7330f729Sjoerg Map.InferredDirectories[Directory].Attrs = Attrs; 2761*7330f729Sjoerg Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2762*7330f729Sjoerg // FIXME: Handle the 'framework' keyword. 2763*7330f729Sjoerg } 2764*7330f729Sjoerg 2765*7330f729Sjoerg // Parse the opening brace. 2766*7330f729Sjoerg if (!Tok.is(MMToken::LBrace)) { 2767*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2768*7330f729Sjoerg HadError = true; 2769*7330f729Sjoerg return; 2770*7330f729Sjoerg } 2771*7330f729Sjoerg SourceLocation LBraceLoc = consumeToken(); 2772*7330f729Sjoerg 2773*7330f729Sjoerg // Parse the body of the inferred submodule. 2774*7330f729Sjoerg bool Done = false; 2775*7330f729Sjoerg do { 2776*7330f729Sjoerg switch (Tok.Kind) { 2777*7330f729Sjoerg case MMToken::EndOfFile: 2778*7330f729Sjoerg case MMToken::RBrace: 2779*7330f729Sjoerg Done = true; 2780*7330f729Sjoerg break; 2781*7330f729Sjoerg 2782*7330f729Sjoerg case MMToken::ExcludeKeyword: 2783*7330f729Sjoerg if (ActiveModule) { 2784*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2785*7330f729Sjoerg << (ActiveModule != nullptr); 2786*7330f729Sjoerg consumeToken(); 2787*7330f729Sjoerg break; 2788*7330f729Sjoerg } 2789*7330f729Sjoerg 2790*7330f729Sjoerg consumeToken(); 2791*7330f729Sjoerg // FIXME: Support string-literal module names here. 2792*7330f729Sjoerg if (!Tok.is(MMToken::Identifier)) { 2793*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2794*7330f729Sjoerg break; 2795*7330f729Sjoerg } 2796*7330f729Sjoerg 2797*7330f729Sjoerg Map.InferredDirectories[Directory].ExcludedModules 2798*7330f729Sjoerg .push_back(Tok.getString()); 2799*7330f729Sjoerg consumeToken(); 2800*7330f729Sjoerg break; 2801*7330f729Sjoerg 2802*7330f729Sjoerg case MMToken::ExportKeyword: 2803*7330f729Sjoerg if (!ActiveModule) { 2804*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2805*7330f729Sjoerg << (ActiveModule != nullptr); 2806*7330f729Sjoerg consumeToken(); 2807*7330f729Sjoerg break; 2808*7330f729Sjoerg } 2809*7330f729Sjoerg 2810*7330f729Sjoerg consumeToken(); 2811*7330f729Sjoerg if (Tok.is(MMToken::Star)) 2812*7330f729Sjoerg ActiveModule->InferExportWildcard = true; 2813*7330f729Sjoerg else 2814*7330f729Sjoerg Diags.Report(Tok.getLocation(), 2815*7330f729Sjoerg diag::err_mmap_expected_export_wildcard); 2816*7330f729Sjoerg consumeToken(); 2817*7330f729Sjoerg break; 2818*7330f729Sjoerg 2819*7330f729Sjoerg case MMToken::ExplicitKeyword: 2820*7330f729Sjoerg case MMToken::ModuleKeyword: 2821*7330f729Sjoerg case MMToken::HeaderKeyword: 2822*7330f729Sjoerg case MMToken::PrivateKeyword: 2823*7330f729Sjoerg case MMToken::UmbrellaKeyword: 2824*7330f729Sjoerg default: 2825*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2826*7330f729Sjoerg << (ActiveModule != nullptr); 2827*7330f729Sjoerg consumeToken(); 2828*7330f729Sjoerg break; 2829*7330f729Sjoerg } 2830*7330f729Sjoerg } while (!Done); 2831*7330f729Sjoerg 2832*7330f729Sjoerg if (Tok.is(MMToken::RBrace)) 2833*7330f729Sjoerg consumeToken(); 2834*7330f729Sjoerg else { 2835*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2836*7330f729Sjoerg Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2837*7330f729Sjoerg HadError = true; 2838*7330f729Sjoerg } 2839*7330f729Sjoerg } 2840*7330f729Sjoerg 2841*7330f729Sjoerg /// Parse optional attributes. 2842*7330f729Sjoerg /// 2843*7330f729Sjoerg /// attributes: 2844*7330f729Sjoerg /// attribute attributes 2845*7330f729Sjoerg /// attribute 2846*7330f729Sjoerg /// 2847*7330f729Sjoerg /// attribute: 2848*7330f729Sjoerg /// [ identifier ] 2849*7330f729Sjoerg /// 2850*7330f729Sjoerg /// \param Attrs Will be filled in with the parsed attributes. 2851*7330f729Sjoerg /// 2852*7330f729Sjoerg /// \returns true if an error occurred, false otherwise. 2853*7330f729Sjoerg bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2854*7330f729Sjoerg bool HadError = false; 2855*7330f729Sjoerg 2856*7330f729Sjoerg while (Tok.is(MMToken::LSquare)) { 2857*7330f729Sjoerg // Consume the '['. 2858*7330f729Sjoerg SourceLocation LSquareLoc = consumeToken(); 2859*7330f729Sjoerg 2860*7330f729Sjoerg // Check whether we have an attribute name here. 2861*7330f729Sjoerg if (!Tok.is(MMToken::Identifier)) { 2862*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2863*7330f729Sjoerg skipUntil(MMToken::RSquare); 2864*7330f729Sjoerg if (Tok.is(MMToken::RSquare)) 2865*7330f729Sjoerg consumeToken(); 2866*7330f729Sjoerg HadError = true; 2867*7330f729Sjoerg } 2868*7330f729Sjoerg 2869*7330f729Sjoerg // Decode the attribute name. 2870*7330f729Sjoerg AttributeKind Attribute 2871*7330f729Sjoerg = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2872*7330f729Sjoerg .Case("exhaustive", AT_exhaustive) 2873*7330f729Sjoerg .Case("extern_c", AT_extern_c) 2874*7330f729Sjoerg .Case("no_undeclared_includes", AT_no_undeclared_includes) 2875*7330f729Sjoerg .Case("system", AT_system) 2876*7330f729Sjoerg .Default(AT_unknown); 2877*7330f729Sjoerg switch (Attribute) { 2878*7330f729Sjoerg case AT_unknown: 2879*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2880*7330f729Sjoerg << Tok.getString(); 2881*7330f729Sjoerg break; 2882*7330f729Sjoerg 2883*7330f729Sjoerg case AT_system: 2884*7330f729Sjoerg Attrs.IsSystem = true; 2885*7330f729Sjoerg break; 2886*7330f729Sjoerg 2887*7330f729Sjoerg case AT_extern_c: 2888*7330f729Sjoerg Attrs.IsExternC = true; 2889*7330f729Sjoerg break; 2890*7330f729Sjoerg 2891*7330f729Sjoerg case AT_exhaustive: 2892*7330f729Sjoerg Attrs.IsExhaustive = true; 2893*7330f729Sjoerg break; 2894*7330f729Sjoerg 2895*7330f729Sjoerg case AT_no_undeclared_includes: 2896*7330f729Sjoerg Attrs.NoUndeclaredIncludes = true; 2897*7330f729Sjoerg break; 2898*7330f729Sjoerg } 2899*7330f729Sjoerg consumeToken(); 2900*7330f729Sjoerg 2901*7330f729Sjoerg // Consume the ']'. 2902*7330f729Sjoerg if (!Tok.is(MMToken::RSquare)) { 2903*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2904*7330f729Sjoerg Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2905*7330f729Sjoerg skipUntil(MMToken::RSquare); 2906*7330f729Sjoerg HadError = true; 2907*7330f729Sjoerg } 2908*7330f729Sjoerg 2909*7330f729Sjoerg if (Tok.is(MMToken::RSquare)) 2910*7330f729Sjoerg consumeToken(); 2911*7330f729Sjoerg } 2912*7330f729Sjoerg 2913*7330f729Sjoerg return HadError; 2914*7330f729Sjoerg } 2915*7330f729Sjoerg 2916*7330f729Sjoerg /// Parse a module map file. 2917*7330f729Sjoerg /// 2918*7330f729Sjoerg /// module-map-file: 2919*7330f729Sjoerg /// module-declaration* 2920*7330f729Sjoerg bool ModuleMapParser::parseModuleMapFile() { 2921*7330f729Sjoerg do { 2922*7330f729Sjoerg switch (Tok.Kind) { 2923*7330f729Sjoerg case MMToken::EndOfFile: 2924*7330f729Sjoerg return HadError; 2925*7330f729Sjoerg 2926*7330f729Sjoerg case MMToken::ExplicitKeyword: 2927*7330f729Sjoerg case MMToken::ExternKeyword: 2928*7330f729Sjoerg case MMToken::ModuleKeyword: 2929*7330f729Sjoerg case MMToken::FrameworkKeyword: 2930*7330f729Sjoerg parseModuleDecl(); 2931*7330f729Sjoerg break; 2932*7330f729Sjoerg 2933*7330f729Sjoerg case MMToken::Comma: 2934*7330f729Sjoerg case MMToken::ConfigMacros: 2935*7330f729Sjoerg case MMToken::Conflict: 2936*7330f729Sjoerg case MMToken::Exclaim: 2937*7330f729Sjoerg case MMToken::ExcludeKeyword: 2938*7330f729Sjoerg case MMToken::ExportKeyword: 2939*7330f729Sjoerg case MMToken::ExportAsKeyword: 2940*7330f729Sjoerg case MMToken::HeaderKeyword: 2941*7330f729Sjoerg case MMToken::Identifier: 2942*7330f729Sjoerg case MMToken::LBrace: 2943*7330f729Sjoerg case MMToken::LinkKeyword: 2944*7330f729Sjoerg case MMToken::LSquare: 2945*7330f729Sjoerg case MMToken::Period: 2946*7330f729Sjoerg case MMToken::PrivateKeyword: 2947*7330f729Sjoerg case MMToken::RBrace: 2948*7330f729Sjoerg case MMToken::RSquare: 2949*7330f729Sjoerg case MMToken::RequiresKeyword: 2950*7330f729Sjoerg case MMToken::Star: 2951*7330f729Sjoerg case MMToken::StringLiteral: 2952*7330f729Sjoerg case MMToken::IntegerLiteral: 2953*7330f729Sjoerg case MMToken::TextualKeyword: 2954*7330f729Sjoerg case MMToken::UmbrellaKeyword: 2955*7330f729Sjoerg case MMToken::UseKeyword: 2956*7330f729Sjoerg Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2957*7330f729Sjoerg HadError = true; 2958*7330f729Sjoerg consumeToken(); 2959*7330f729Sjoerg break; 2960*7330f729Sjoerg } 2961*7330f729Sjoerg } while (true); 2962*7330f729Sjoerg } 2963*7330f729Sjoerg 2964*7330f729Sjoerg bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2965*7330f729Sjoerg const DirectoryEntry *Dir, FileID ID, 2966*7330f729Sjoerg unsigned *Offset, 2967*7330f729Sjoerg SourceLocation ExternModuleLoc) { 2968*7330f729Sjoerg assert(Target && "Missing target information"); 2969*7330f729Sjoerg llvm::DenseMap<const FileEntry *, bool>::iterator Known 2970*7330f729Sjoerg = ParsedModuleMap.find(File); 2971*7330f729Sjoerg if (Known != ParsedModuleMap.end()) 2972*7330f729Sjoerg return Known->second; 2973*7330f729Sjoerg 2974*7330f729Sjoerg // If the module map file wasn't already entered, do so now. 2975*7330f729Sjoerg if (ID.isInvalid()) { 2976*7330f729Sjoerg auto FileCharacter = 2977*7330f729Sjoerg IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 2978*7330f729Sjoerg ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 2979*7330f729Sjoerg } 2980*7330f729Sjoerg 2981*7330f729Sjoerg assert(Target && "Missing target information"); 2982*7330f729Sjoerg const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2983*7330f729Sjoerg if (!Buffer) 2984*7330f729Sjoerg return ParsedModuleMap[File] = true; 2985*7330f729Sjoerg assert((!Offset || *Offset <= Buffer->getBufferSize()) && 2986*7330f729Sjoerg "invalid buffer offset"); 2987*7330f729Sjoerg 2988*7330f729Sjoerg // Parse this module map file. 2989*7330f729Sjoerg Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 2990*7330f729Sjoerg Buffer->getBufferStart(), 2991*7330f729Sjoerg Buffer->getBufferStart() + (Offset ? *Offset : 0), 2992*7330f729Sjoerg Buffer->getBufferEnd()); 2993*7330f729Sjoerg SourceLocation Start = L.getSourceLocation(); 2994*7330f729Sjoerg ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2995*7330f729Sjoerg IsSystem); 2996*7330f729Sjoerg bool Result = Parser.parseModuleMapFile(); 2997*7330f729Sjoerg ParsedModuleMap[File] = Result; 2998*7330f729Sjoerg 2999*7330f729Sjoerg if (Offset) { 3000*7330f729Sjoerg auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 3001*7330f729Sjoerg assert(Loc.first == ID && "stopped in a different file?"); 3002*7330f729Sjoerg *Offset = Loc.second; 3003*7330f729Sjoerg } 3004*7330f729Sjoerg 3005*7330f729Sjoerg // Notify callbacks that we parsed it. 3006*7330f729Sjoerg for (const auto &Cb : Callbacks) 3007*7330f729Sjoerg Cb->moduleMapFileRead(Start, *File, IsSystem); 3008*7330f729Sjoerg 3009*7330f729Sjoerg return Result; 3010*7330f729Sjoerg } 3011