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