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 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1489 // Skip the module definition. 1490 skipUntil(MMToken::RBrace); 1491 if (Tok.is(MMToken::RBrace)) 1492 consumeToken(); 1493 else { 1494 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1495 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1496 HadError = true; 1497 } 1498 return; 1499 } 1500 1501 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1502 << ModuleName; 1503 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1504 1505 // Skip the module definition. 1506 skipUntil(MMToken::RBrace); 1507 if (Tok.is(MMToken::RBrace)) 1508 consumeToken(); 1509 1510 HadError = true; 1511 return; 1512 } 1513 1514 // Start defining this module. 1515 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1516 Explicit).first; 1517 ActiveModule->DefinitionLoc = ModuleNameLoc; 1518 if (Attrs.IsSystem || IsSystem) 1519 ActiveModule->IsSystem = true; 1520 if (Attrs.IsExternC) 1521 ActiveModule->IsExternC = true; 1522 if (Attrs.NoUndeclaredIncludes || 1523 (!ActiveModule->Parent && ModuleName == "Darwin")) 1524 ActiveModule->NoUndeclaredIncludes = true; 1525 ActiveModule->Directory = Directory; 1526 1527 if (!ActiveModule->Parent) { 1528 StringRef MapFileName(ModuleMapFile->getName()); 1529 if (MapFileName.endswith("module.private.modulemap") || 1530 MapFileName.endswith("module_private.map")) { 1531 // Adding a top-level module from a private modulemap is likely a 1532 // user error; we check to see if there's another top-level module 1533 // defined in the non-private map in the same dir, and if so emit a 1534 // warning. 1535 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1536 auto const *M = E->getValue(); 1537 if (!M->Parent && 1538 M->Directory == ActiveModule->Directory && 1539 M->Name != ActiveModule->Name) { 1540 Diags.Report(ActiveModule->DefinitionLoc, 1541 diag::warn_mmap_mismatched_top_level_private) 1542 << ActiveModule->Name << M->Name; 1543 // The pattern we're defending against here is typically due to 1544 // a module named FooPrivate which is supposed to be a submodule 1545 // called Foo.Private. Emit a fixit in that case. 1546 auto D = 1547 Diags.Report(ActiveModule->DefinitionLoc, 1548 diag::note_mmap_rename_top_level_private_as_submodule); 1549 D << ActiveModule->Name << M->Name; 1550 StringRef Bad(ActiveModule->Name); 1551 if (Bad.consume_back("Private")) { 1552 SmallString<128> Fixed = Bad; 1553 Fixed.append(".Private"); 1554 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, 1555 Fixed); 1556 } 1557 break; 1558 } 1559 } 1560 } 1561 } 1562 1563 bool Done = false; 1564 do { 1565 switch (Tok.Kind) { 1566 case MMToken::EndOfFile: 1567 case MMToken::RBrace: 1568 Done = true; 1569 break; 1570 1571 case MMToken::ConfigMacros: 1572 parseConfigMacros(); 1573 break; 1574 1575 case MMToken::Conflict: 1576 parseConflict(); 1577 break; 1578 1579 case MMToken::ExplicitKeyword: 1580 case MMToken::ExternKeyword: 1581 case MMToken::FrameworkKeyword: 1582 case MMToken::ModuleKeyword: 1583 parseModuleDecl(); 1584 break; 1585 1586 case MMToken::ExportKeyword: 1587 parseExportDecl(); 1588 break; 1589 1590 case MMToken::UseKeyword: 1591 parseUseDecl(); 1592 break; 1593 1594 case MMToken::RequiresKeyword: 1595 parseRequiresDecl(); 1596 break; 1597 1598 case MMToken::TextualKeyword: 1599 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1600 break; 1601 1602 case MMToken::UmbrellaKeyword: { 1603 SourceLocation UmbrellaLoc = consumeToken(); 1604 if (Tok.is(MMToken::HeaderKeyword)) 1605 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1606 else 1607 parseUmbrellaDirDecl(UmbrellaLoc); 1608 break; 1609 } 1610 1611 case MMToken::ExcludeKeyword: 1612 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1613 break; 1614 1615 case MMToken::PrivateKeyword: 1616 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1617 break; 1618 1619 case MMToken::HeaderKeyword: 1620 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1621 break; 1622 1623 case MMToken::LinkKeyword: 1624 parseLinkDecl(); 1625 break; 1626 1627 default: 1628 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1629 consumeToken(); 1630 break; 1631 } 1632 } while (!Done); 1633 1634 if (Tok.is(MMToken::RBrace)) 1635 consumeToken(); 1636 else { 1637 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1638 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1639 HadError = true; 1640 } 1641 1642 // If the active module is a top-level framework, and there are no link 1643 // libraries, automatically link against the framework. 1644 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1645 ActiveModule->LinkLibraries.empty()) { 1646 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1647 } 1648 1649 // If the module meets all requirements but is still unavailable, mark the 1650 // whole tree as unavailable to prevent it from building. 1651 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1652 ActiveModule->Parent) { 1653 ActiveModule->getTopLevelModule()->markUnavailable(); 1654 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1655 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1656 } 1657 1658 // We're done parsing this module. Pop back to the previous module. 1659 ActiveModule = PreviousActiveModule; 1660 } 1661 1662 /// \brief Parse an extern module declaration. 1663 /// 1664 /// extern module-declaration: 1665 /// 'extern' 'module' module-id string-literal 1666 void ModuleMapParser::parseExternModuleDecl() { 1667 assert(Tok.is(MMToken::ExternKeyword)); 1668 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 1669 1670 // Parse 'module' keyword. 1671 if (!Tok.is(MMToken::ModuleKeyword)) { 1672 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1673 consumeToken(); 1674 HadError = true; 1675 return; 1676 } 1677 consumeToken(); // 'module' keyword 1678 1679 // Parse the module name. 1680 ModuleId Id; 1681 if (parseModuleId(Id)) { 1682 HadError = true; 1683 return; 1684 } 1685 1686 // Parse the referenced module map file name. 1687 if (!Tok.is(MMToken::StringLiteral)) { 1688 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1689 HadError = true; 1690 return; 1691 } 1692 std::string FileName = Tok.getString(); 1693 consumeToken(); // filename 1694 1695 StringRef FileNameRef = FileName; 1696 SmallString<128> ModuleMapFileName; 1697 if (llvm::sys::path::is_relative(FileNameRef)) { 1698 ModuleMapFileName += Directory->getName(); 1699 llvm::sys::path::append(ModuleMapFileName, FileName); 1700 FileNameRef = ModuleMapFileName; 1701 } 1702 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1703 Map.parseModuleMapFile( 1704 File, /*IsSystem=*/false, 1705 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 1706 ? Directory 1707 : File->getDir(), 1708 FileID(), nullptr, ExternLoc); 1709 } 1710 1711 /// Whether to add the requirement \p Feature to the module \p M. 1712 /// 1713 /// This preserves backwards compatibility for two hacks in the Darwin system 1714 /// module map files: 1715 /// 1716 /// 1. The use of 'requires excluded' to make headers non-modular, which 1717 /// should really be mapped to 'textual' now that we have this feature. We 1718 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 1719 /// true. Later, this bit will be used to map all the headers inside this 1720 /// module to 'textual'. 1721 /// 1722 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 1723 /// 1724 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 1725 /// was never correct and causes issues now that we check it, so drop it. 1726 static bool shouldAddRequirement(Module *M, StringRef Feature, 1727 bool &IsRequiresExcludedHack) { 1728 if (Feature == "excluded" && 1729 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 1730 M->fullModuleNameIs({"Tcl", "Private"}))) { 1731 IsRequiresExcludedHack = true; 1732 return false; 1733 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 1734 return false; 1735 } 1736 1737 return true; 1738 } 1739 1740 /// \brief Parse a requires declaration. 1741 /// 1742 /// requires-declaration: 1743 /// 'requires' feature-list 1744 /// 1745 /// feature-list: 1746 /// feature ',' feature-list 1747 /// feature 1748 /// 1749 /// feature: 1750 /// '!'[opt] identifier 1751 void ModuleMapParser::parseRequiresDecl() { 1752 assert(Tok.is(MMToken::RequiresKeyword)); 1753 1754 // Parse 'requires' keyword. 1755 consumeToken(); 1756 1757 // Parse the feature-list. 1758 do { 1759 bool RequiredState = true; 1760 if (Tok.is(MMToken::Exclaim)) { 1761 RequiredState = false; 1762 consumeToken(); 1763 } 1764 1765 if (!Tok.is(MMToken::Identifier)) { 1766 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1767 HadError = true; 1768 return; 1769 } 1770 1771 // Consume the feature name. 1772 std::string Feature = Tok.getString(); 1773 consumeToken(); 1774 1775 bool IsRequiresExcludedHack = false; 1776 bool ShouldAddRequirement = 1777 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 1778 1779 if (IsRequiresExcludedHack) 1780 UsesRequiresExcludedHack.insert(ActiveModule); 1781 1782 if (ShouldAddRequirement) { 1783 // Add this feature. 1784 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 1785 *Map.Target); 1786 } 1787 1788 if (!Tok.is(MMToken::Comma)) 1789 break; 1790 1791 // Consume the comma. 1792 consumeToken(); 1793 } while (true); 1794 } 1795 1796 /// \brief Append to \p Paths the set of paths needed to get to the 1797 /// subframework in which the given module lives. 1798 static void appendSubframeworkPaths(Module *Mod, 1799 SmallVectorImpl<char> &Path) { 1800 // Collect the framework names from the given module to the top-level module. 1801 SmallVector<StringRef, 2> Paths; 1802 for (; Mod; Mod = Mod->Parent) { 1803 if (Mod->IsFramework) 1804 Paths.push_back(Mod->Name); 1805 } 1806 1807 if (Paths.empty()) 1808 return; 1809 1810 // Add Frameworks/Name.framework for each subframework. 1811 for (unsigned I = Paths.size() - 1; I != 0; --I) 1812 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1813 } 1814 1815 /// \brief Parse a header declaration. 1816 /// 1817 /// header-declaration: 1818 /// 'textual'[opt] 'header' string-literal 1819 /// 'private' 'textual'[opt] 'header' string-literal 1820 /// 'exclude' 'header' string-literal 1821 /// 'umbrella' 'header' string-literal 1822 /// 1823 /// FIXME: Support 'private textual header'. 1824 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1825 SourceLocation LeadingLoc) { 1826 // We've already consumed the first token. 1827 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1828 if (LeadingToken == MMToken::PrivateKeyword) { 1829 Role = ModuleMap::PrivateHeader; 1830 // 'private' may optionally be followed by 'textual'. 1831 if (Tok.is(MMToken::TextualKeyword)) { 1832 LeadingToken = Tok.Kind; 1833 consumeToken(); 1834 } 1835 } 1836 1837 if (LeadingToken == MMToken::TextualKeyword) 1838 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1839 1840 if (UsesRequiresExcludedHack.count(ActiveModule)) { 1841 // Mark this header 'textual' (see doc comment for 1842 // Module::UsesRequiresExcludedHack). 1843 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1844 } 1845 1846 if (LeadingToken != MMToken::HeaderKeyword) { 1847 if (!Tok.is(MMToken::HeaderKeyword)) { 1848 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1849 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 1850 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 1851 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 1852 return; 1853 } 1854 consumeToken(); 1855 } 1856 1857 // Parse the header name. 1858 if (!Tok.is(MMToken::StringLiteral)) { 1859 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1860 << "header"; 1861 HadError = true; 1862 return; 1863 } 1864 Module::UnresolvedHeaderDirective Header; 1865 Header.FileName = Tok.getString(); 1866 Header.FileNameLoc = consumeToken(); 1867 1868 // Check whether we already have an umbrella. 1869 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1870 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 1871 << ActiveModule->getFullModuleName(); 1872 HadError = true; 1873 return; 1874 } 1875 1876 // Look for this file. 1877 const FileEntry *File = nullptr; 1878 const FileEntry *BuiltinFile = nullptr; 1879 SmallString<128> RelativePathName; 1880 if (llvm::sys::path::is_absolute(Header.FileName)) { 1881 RelativePathName = Header.FileName; 1882 File = SourceMgr.getFileManager().getFile(RelativePathName); 1883 } else { 1884 // Search for the header file within the search directory. 1885 SmallString<128> FullPathName(Directory->getName()); 1886 unsigned FullPathLength = FullPathName.size(); 1887 1888 if (ActiveModule->isPartOfFramework()) { 1889 appendSubframeworkPaths(ActiveModule, RelativePathName); 1890 unsigned RelativePathLength = RelativePathName.size(); 1891 1892 // Check whether this file is in the public headers. 1893 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); 1894 llvm::sys::path::append(FullPathName, RelativePathName); 1895 File = SourceMgr.getFileManager().getFile(FullPathName); 1896 1897 // Check whether this file is in the private headers. 1898 if (!File) { 1899 // Ideally, private modules in the form 'FrameworkName.Private' should 1900 // be defined as 'module FrameworkName.Private', and not as 1901 // 'framework module FrameworkName.Private', since a 'Private.Framework' 1902 // does not usually exist. However, since both are currently widely used 1903 // for private modules, make sure we find the right path in both cases. 1904 RelativePathName.resize(ActiveModule->IsFramework ? 0 1905 : RelativePathLength); 1906 FullPathName.resize(FullPathLength); 1907 llvm::sys::path::append(RelativePathName, "PrivateHeaders", 1908 Header.FileName); 1909 llvm::sys::path::append(FullPathName, RelativePathName); 1910 File = SourceMgr.getFileManager().getFile(FullPathName); 1911 } 1912 } else { 1913 // Lookup for normal headers. 1914 llvm::sys::path::append(RelativePathName, Header.FileName); 1915 llvm::sys::path::append(FullPathName, RelativePathName); 1916 File = SourceMgr.getFileManager().getFile(FullPathName); 1917 1918 // If this is a system module with a top-level header, this header 1919 // may have a counterpart (or replacement) in the set of headers 1920 // supplied by Clang. Find that builtin header. 1921 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1922 BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1923 ModuleMap::isBuiltinHeader(Header.FileName)) { 1924 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1925 llvm::sys::path::append(BuiltinPathName, Header.FileName); 1926 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1927 1928 // If Clang supplies this header but the underlying system does not, 1929 // just silently swap in our builtin version. Otherwise, we'll end 1930 // up adding both (later). 1931 if (BuiltinFile && !File) { 1932 File = BuiltinFile; 1933 RelativePathName = BuiltinPathName; 1934 BuiltinFile = nullptr; 1935 } 1936 } 1937 } 1938 } 1939 1940 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1941 // Come up with a lazy way to do this. 1942 if (File) { 1943 if (LeadingToken == MMToken::UmbrellaKeyword) { 1944 const DirectoryEntry *UmbrellaDir = File->getDir(); 1945 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1946 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 1947 << UmbrellaModule->getFullModuleName(); 1948 HadError = true; 1949 } else { 1950 // Record this umbrella header. 1951 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str()); 1952 } 1953 } else if (LeadingToken == MMToken::ExcludeKeyword) { 1954 Module::Header H = {RelativePathName.str(), File}; 1955 Map.excludeHeader(ActiveModule, H); 1956 } else { 1957 // If there is a builtin counterpart to this file, add it now so it can 1958 // wrap the system header. 1959 if (BuiltinFile) { 1960 // FIXME: Taking the name from the FileEntry is unstable and can give 1961 // different results depending on how we've previously named that file 1962 // in this build. 1963 Module::Header H = { BuiltinFile->getName(), BuiltinFile }; 1964 Map.addHeader(ActiveModule, H, Role); 1965 1966 // If we have both a builtin and system version of the file, the 1967 // builtin version may want to inject macros into the system header, so 1968 // force the system header to be treated as a textual header in this 1969 // case. 1970 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1971 } 1972 1973 // Record this header. 1974 Module::Header H = { RelativePathName.str(), File }; 1975 Map.addHeader(ActiveModule, H, Role); 1976 } 1977 } else if (LeadingToken != MMToken::ExcludeKeyword) { 1978 // Ignore excluded header files. They're optional anyway. 1979 1980 // If we find a module that has a missing header, we mark this module as 1981 // unavailable and store the header directive for displaying diagnostics. 1982 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 1983 ActiveModule->markUnavailable(); 1984 ActiveModule->MissingHeaders.push_back(Header); 1985 } 1986 } 1987 1988 static int compareModuleHeaders(const Module::Header *A, 1989 const Module::Header *B) { 1990 return A->NameAsWritten.compare(B->NameAsWritten); 1991 } 1992 1993 /// \brief Parse an umbrella directory declaration. 1994 /// 1995 /// umbrella-dir-declaration: 1996 /// umbrella string-literal 1997 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1998 // Parse the directory name. 1999 if (!Tok.is(MMToken::StringLiteral)) { 2000 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2001 << "umbrella"; 2002 HadError = true; 2003 return; 2004 } 2005 2006 std::string DirName = Tok.getString(); 2007 SourceLocation DirNameLoc = consumeToken(); 2008 2009 // Check whether we already have an umbrella. 2010 if (ActiveModule->Umbrella) { 2011 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2012 << ActiveModule->getFullModuleName(); 2013 HadError = true; 2014 return; 2015 } 2016 2017 // Look for this file. 2018 const DirectoryEntry *Dir = nullptr; 2019 if (llvm::sys::path::is_absolute(DirName)) 2020 Dir = SourceMgr.getFileManager().getDirectory(DirName); 2021 else { 2022 SmallString<128> PathName; 2023 PathName = Directory->getName(); 2024 llvm::sys::path::append(PathName, DirName); 2025 Dir = SourceMgr.getFileManager().getDirectory(PathName); 2026 } 2027 2028 if (!Dir) { 2029 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2030 << DirName; 2031 return; 2032 } 2033 2034 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2035 // Mark this header 'textual' (see doc comment for 2036 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2037 // directory is relatively expensive, in practice this only applies to the 2038 // uncommonly used Tcl module on Darwin platforms. 2039 std::error_code EC; 2040 SmallVector<Module::Header, 6> Headers; 2041 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem(); 2042 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2043 I != E && !EC; I.increment(EC)) { 2044 if (const FileEntry *FE = 2045 SourceMgr.getFileManager().getFile(I->getName())) { 2046 2047 Module::Header Header = {I->getName(), FE}; 2048 Headers.push_back(std::move(Header)); 2049 } 2050 } 2051 2052 // Sort header paths so that the pcm doesn't depend on iteration order. 2053 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2054 2055 for (auto &Header : Headers) 2056 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2057 return; 2058 } 2059 2060 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 2061 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2062 << OwningModule->getFullModuleName(); 2063 HadError = true; 2064 return; 2065 } 2066 2067 // Record this umbrella directory. 2068 Map.setUmbrellaDir(ActiveModule, Dir, DirName); 2069 } 2070 2071 /// \brief Parse a module export declaration. 2072 /// 2073 /// export-declaration: 2074 /// 'export' wildcard-module-id 2075 /// 2076 /// wildcard-module-id: 2077 /// identifier 2078 /// '*' 2079 /// identifier '.' wildcard-module-id 2080 void ModuleMapParser::parseExportDecl() { 2081 assert(Tok.is(MMToken::ExportKeyword)); 2082 SourceLocation ExportLoc = consumeToken(); 2083 2084 // Parse the module-id with an optional wildcard at the end. 2085 ModuleId ParsedModuleId; 2086 bool Wildcard = false; 2087 do { 2088 // FIXME: Support string-literal module names here. 2089 if (Tok.is(MMToken::Identifier)) { 2090 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 2091 Tok.getLocation())); 2092 consumeToken(); 2093 2094 if (Tok.is(MMToken::Period)) { 2095 consumeToken(); 2096 continue; 2097 } 2098 2099 break; 2100 } 2101 2102 if(Tok.is(MMToken::Star)) { 2103 Wildcard = true; 2104 consumeToken(); 2105 break; 2106 } 2107 2108 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2109 HadError = true; 2110 return; 2111 } while (true); 2112 2113 Module::UnresolvedExportDecl Unresolved = { 2114 ExportLoc, ParsedModuleId, Wildcard 2115 }; 2116 ActiveModule->UnresolvedExports.push_back(Unresolved); 2117 } 2118 2119 /// \brief Parse a module use declaration. 2120 /// 2121 /// use-declaration: 2122 /// 'use' wildcard-module-id 2123 void ModuleMapParser::parseUseDecl() { 2124 assert(Tok.is(MMToken::UseKeyword)); 2125 auto KWLoc = consumeToken(); 2126 // Parse the module-id. 2127 ModuleId ParsedModuleId; 2128 parseModuleId(ParsedModuleId); 2129 2130 if (ActiveModule->Parent) 2131 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2132 else 2133 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2134 } 2135 2136 /// \brief Parse a link declaration. 2137 /// 2138 /// module-declaration: 2139 /// 'link' 'framework'[opt] string-literal 2140 void ModuleMapParser::parseLinkDecl() { 2141 assert(Tok.is(MMToken::LinkKeyword)); 2142 SourceLocation LinkLoc = consumeToken(); 2143 2144 // Parse the optional 'framework' keyword. 2145 bool IsFramework = false; 2146 if (Tok.is(MMToken::FrameworkKeyword)) { 2147 consumeToken(); 2148 IsFramework = true; 2149 } 2150 2151 // Parse the library name 2152 if (!Tok.is(MMToken::StringLiteral)) { 2153 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2154 << IsFramework << SourceRange(LinkLoc); 2155 HadError = true; 2156 return; 2157 } 2158 2159 std::string LibraryName = Tok.getString(); 2160 consumeToken(); 2161 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2162 IsFramework)); 2163 } 2164 2165 /// \brief Parse a configuration macro declaration. 2166 /// 2167 /// module-declaration: 2168 /// 'config_macros' attributes[opt] config-macro-list? 2169 /// 2170 /// config-macro-list: 2171 /// identifier (',' identifier)? 2172 void ModuleMapParser::parseConfigMacros() { 2173 assert(Tok.is(MMToken::ConfigMacros)); 2174 SourceLocation ConfigMacrosLoc = consumeToken(); 2175 2176 // Only top-level modules can have configuration macros. 2177 if (ActiveModule->Parent) { 2178 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2179 } 2180 2181 // Parse the optional attributes. 2182 Attributes Attrs; 2183 if (parseOptionalAttributes(Attrs)) 2184 return; 2185 2186 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2187 ActiveModule->ConfigMacrosExhaustive = true; 2188 } 2189 2190 // If we don't have an identifier, we're done. 2191 // FIXME: Support macros with the same name as a keyword here. 2192 if (!Tok.is(MMToken::Identifier)) 2193 return; 2194 2195 // Consume the first identifier. 2196 if (!ActiveModule->Parent) { 2197 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2198 } 2199 consumeToken(); 2200 2201 do { 2202 // If there's a comma, consume it. 2203 if (!Tok.is(MMToken::Comma)) 2204 break; 2205 consumeToken(); 2206 2207 // We expect to see a macro name here. 2208 // FIXME: Support macros with the same name as a keyword here. 2209 if (!Tok.is(MMToken::Identifier)) { 2210 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2211 break; 2212 } 2213 2214 // Consume the macro name. 2215 if (!ActiveModule->Parent) { 2216 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2217 } 2218 consumeToken(); 2219 } while (true); 2220 } 2221 2222 /// \brief Format a module-id into a string. 2223 static std::string formatModuleId(const ModuleId &Id) { 2224 std::string result; 2225 { 2226 llvm::raw_string_ostream OS(result); 2227 2228 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2229 if (I) 2230 OS << "."; 2231 OS << Id[I].first; 2232 } 2233 } 2234 2235 return result; 2236 } 2237 2238 /// \brief Parse a conflict declaration. 2239 /// 2240 /// module-declaration: 2241 /// 'conflict' module-id ',' string-literal 2242 void ModuleMapParser::parseConflict() { 2243 assert(Tok.is(MMToken::Conflict)); 2244 SourceLocation ConflictLoc = consumeToken(); 2245 Module::UnresolvedConflict Conflict; 2246 2247 // Parse the module-id. 2248 if (parseModuleId(Conflict.Id)) 2249 return; 2250 2251 // Parse the ','. 2252 if (!Tok.is(MMToken::Comma)) { 2253 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2254 << SourceRange(ConflictLoc); 2255 return; 2256 } 2257 consumeToken(); 2258 2259 // Parse the message. 2260 if (!Tok.is(MMToken::StringLiteral)) { 2261 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2262 << formatModuleId(Conflict.Id); 2263 return; 2264 } 2265 Conflict.Message = Tok.getString().str(); 2266 consumeToken(); 2267 2268 // Add this unresolved conflict. 2269 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2270 } 2271 2272 /// \brief Parse an inferred module declaration (wildcard modules). 2273 /// 2274 /// module-declaration: 2275 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2276 /// { inferred-module-member* } 2277 /// 2278 /// inferred-module-member: 2279 /// 'export' '*' 2280 /// 'exclude' identifier 2281 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2282 assert(Tok.is(MMToken::Star)); 2283 SourceLocation StarLoc = consumeToken(); 2284 bool Failed = false; 2285 2286 // Inferred modules must be submodules. 2287 if (!ActiveModule && !Framework) { 2288 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2289 Failed = true; 2290 } 2291 2292 if (ActiveModule) { 2293 // Inferred modules must have umbrella directories. 2294 if (!Failed && ActiveModule->IsAvailable && 2295 !ActiveModule->getUmbrellaDir()) { 2296 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2297 Failed = true; 2298 } 2299 2300 // Check for redefinition of an inferred module. 2301 if (!Failed && ActiveModule->InferSubmodules) { 2302 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2303 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2304 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2305 diag::note_mmap_prev_definition); 2306 Failed = true; 2307 } 2308 2309 // Check for the 'framework' keyword, which is not permitted here. 2310 if (Framework) { 2311 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2312 Framework = false; 2313 } 2314 } else if (Explicit) { 2315 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2316 Explicit = false; 2317 } 2318 2319 // If there were any problems with this inferred submodule, skip its body. 2320 if (Failed) { 2321 if (Tok.is(MMToken::LBrace)) { 2322 consumeToken(); 2323 skipUntil(MMToken::RBrace); 2324 if (Tok.is(MMToken::RBrace)) 2325 consumeToken(); 2326 } 2327 HadError = true; 2328 return; 2329 } 2330 2331 // Parse optional attributes. 2332 Attributes Attrs; 2333 if (parseOptionalAttributes(Attrs)) 2334 return; 2335 2336 if (ActiveModule) { 2337 // Note that we have an inferred submodule. 2338 ActiveModule->InferSubmodules = true; 2339 ActiveModule->InferredSubmoduleLoc = StarLoc; 2340 ActiveModule->InferExplicitSubmodules = Explicit; 2341 } else { 2342 // We'll be inferring framework modules for this directory. 2343 Map.InferredDirectories[Directory].InferModules = true; 2344 Map.InferredDirectories[Directory].Attrs = Attrs; 2345 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2346 // FIXME: Handle the 'framework' keyword. 2347 } 2348 2349 // Parse the opening brace. 2350 if (!Tok.is(MMToken::LBrace)) { 2351 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2352 HadError = true; 2353 return; 2354 } 2355 SourceLocation LBraceLoc = consumeToken(); 2356 2357 // Parse the body of the inferred submodule. 2358 bool Done = false; 2359 do { 2360 switch (Tok.Kind) { 2361 case MMToken::EndOfFile: 2362 case MMToken::RBrace: 2363 Done = true; 2364 break; 2365 2366 case MMToken::ExcludeKeyword: { 2367 if (ActiveModule) { 2368 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2369 << (ActiveModule != nullptr); 2370 consumeToken(); 2371 break; 2372 } 2373 2374 consumeToken(); 2375 // FIXME: Support string-literal module names here. 2376 if (!Tok.is(MMToken::Identifier)) { 2377 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2378 break; 2379 } 2380 2381 Map.InferredDirectories[Directory].ExcludedModules 2382 .push_back(Tok.getString()); 2383 consumeToken(); 2384 break; 2385 } 2386 2387 case MMToken::ExportKeyword: 2388 if (!ActiveModule) { 2389 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2390 << (ActiveModule != nullptr); 2391 consumeToken(); 2392 break; 2393 } 2394 2395 consumeToken(); 2396 if (Tok.is(MMToken::Star)) 2397 ActiveModule->InferExportWildcard = true; 2398 else 2399 Diags.Report(Tok.getLocation(), 2400 diag::err_mmap_expected_export_wildcard); 2401 consumeToken(); 2402 break; 2403 2404 case MMToken::ExplicitKeyword: 2405 case MMToken::ModuleKeyword: 2406 case MMToken::HeaderKeyword: 2407 case MMToken::PrivateKeyword: 2408 case MMToken::UmbrellaKeyword: 2409 default: 2410 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2411 << (ActiveModule != nullptr); 2412 consumeToken(); 2413 break; 2414 } 2415 } while (!Done); 2416 2417 if (Tok.is(MMToken::RBrace)) 2418 consumeToken(); 2419 else { 2420 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2421 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2422 HadError = true; 2423 } 2424 } 2425 2426 /// \brief Parse optional attributes. 2427 /// 2428 /// attributes: 2429 /// attribute attributes 2430 /// attribute 2431 /// 2432 /// attribute: 2433 /// [ identifier ] 2434 /// 2435 /// \param Attrs Will be filled in with the parsed attributes. 2436 /// 2437 /// \returns true if an error occurred, false otherwise. 2438 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2439 bool HadError = false; 2440 2441 while (Tok.is(MMToken::LSquare)) { 2442 // Consume the '['. 2443 SourceLocation LSquareLoc = consumeToken(); 2444 2445 // Check whether we have an attribute name here. 2446 if (!Tok.is(MMToken::Identifier)) { 2447 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2448 skipUntil(MMToken::RSquare); 2449 if (Tok.is(MMToken::RSquare)) 2450 consumeToken(); 2451 HadError = true; 2452 } 2453 2454 // Decode the attribute name. 2455 AttributeKind Attribute 2456 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2457 .Case("exhaustive", AT_exhaustive) 2458 .Case("extern_c", AT_extern_c) 2459 .Case("no_undeclared_includes", AT_no_undeclared_includes) 2460 .Case("system", AT_system) 2461 .Default(AT_unknown); 2462 switch (Attribute) { 2463 case AT_unknown: 2464 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2465 << Tok.getString(); 2466 break; 2467 2468 case AT_system: 2469 Attrs.IsSystem = true; 2470 break; 2471 2472 case AT_extern_c: 2473 Attrs.IsExternC = true; 2474 break; 2475 2476 case AT_exhaustive: 2477 Attrs.IsExhaustive = true; 2478 break; 2479 2480 case AT_no_undeclared_includes: 2481 Attrs.NoUndeclaredIncludes = true; 2482 break; 2483 } 2484 consumeToken(); 2485 2486 // Consume the ']'. 2487 if (!Tok.is(MMToken::RSquare)) { 2488 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2489 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2490 skipUntil(MMToken::RSquare); 2491 HadError = true; 2492 } 2493 2494 if (Tok.is(MMToken::RSquare)) 2495 consumeToken(); 2496 } 2497 2498 return HadError; 2499 } 2500 2501 /// \brief Parse a module map file. 2502 /// 2503 /// module-map-file: 2504 /// module-declaration* 2505 bool ModuleMapParser::parseModuleMapFile() { 2506 do { 2507 switch (Tok.Kind) { 2508 case MMToken::EndOfFile: 2509 return HadError; 2510 2511 case MMToken::ExplicitKeyword: 2512 case MMToken::ExternKeyword: 2513 case MMToken::ModuleKeyword: 2514 case MMToken::FrameworkKeyword: 2515 parseModuleDecl(); 2516 break; 2517 2518 case MMToken::Comma: 2519 case MMToken::ConfigMacros: 2520 case MMToken::Conflict: 2521 case MMToken::Exclaim: 2522 case MMToken::ExcludeKeyword: 2523 case MMToken::ExportKeyword: 2524 case MMToken::HeaderKeyword: 2525 case MMToken::Identifier: 2526 case MMToken::LBrace: 2527 case MMToken::LinkKeyword: 2528 case MMToken::LSquare: 2529 case MMToken::Period: 2530 case MMToken::PrivateKeyword: 2531 case MMToken::RBrace: 2532 case MMToken::RSquare: 2533 case MMToken::RequiresKeyword: 2534 case MMToken::Star: 2535 case MMToken::StringLiteral: 2536 case MMToken::TextualKeyword: 2537 case MMToken::UmbrellaKeyword: 2538 case MMToken::UseKeyword: 2539 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2540 HadError = true; 2541 consumeToken(); 2542 break; 2543 } 2544 } while (true); 2545 } 2546 2547 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2548 const DirectoryEntry *Dir, FileID ID, 2549 unsigned *Offset, 2550 SourceLocation ExternModuleLoc) { 2551 assert(Target && "Missing target information"); 2552 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2553 = ParsedModuleMap.find(File); 2554 if (Known != ParsedModuleMap.end()) 2555 return Known->second; 2556 2557 // If the module map file wasn't already entered, do so now. 2558 if (ID.isInvalid()) { 2559 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2560 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 2561 } 2562 2563 assert(Target && "Missing target information"); 2564 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2565 if (!Buffer) 2566 return ParsedModuleMap[File] = true; 2567 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 2568 "invalid buffer offset"); 2569 2570 // Parse this module map file. 2571 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 2572 Buffer->getBufferStart(), 2573 Buffer->getBufferStart() + (Offset ? *Offset : 0), 2574 Buffer->getBufferEnd()); 2575 SourceLocation Start = L.getSourceLocation(); 2576 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2577 BuiltinIncludeDir, IsSystem); 2578 bool Result = Parser.parseModuleMapFile(); 2579 ParsedModuleMap[File] = Result; 2580 2581 if (Offset) { 2582 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 2583 assert(Loc.first == ID && "stopped in a different file?"); 2584 *Offset = Loc.second; 2585 } 2586 2587 // Notify callbacks that we parsed it. 2588 for (const auto &Cb : Callbacks) 2589 Cb->moduleMapFileRead(Start, *File, IsSystem); 2590 return Result; 2591 } 2592