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