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