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