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 ExternKeyword, 1205 FrameworkKeyword, 1206 LinkKeyword, 1207 ModuleKeyword, 1208 Period, 1209 PrivateKeyword, 1210 UmbrellaKeyword, 1211 UseKeyword, 1212 RequiresKeyword, 1213 Star, 1214 StringLiteral, 1215 IntegerLiteral, 1216 TextualKeyword, 1217 LBrace, 1218 RBrace, 1219 LSquare, 1220 RSquare 1221 } Kind; 1222 1223 unsigned Location; 1224 unsigned StringLength; 1225 union { 1226 // If Kind != IntegerLiteral. 1227 const char *StringData; 1228 // If Kind == IntegerLiteral. 1229 uint64_t IntegerValue; 1230 }; 1231 1232 void clear() { 1233 Kind = EndOfFile; 1234 Location = 0; 1235 StringLength = 0; 1236 StringData = nullptr; 1237 } 1238 1239 bool is(TokenKind K) const { return Kind == K; } 1240 1241 SourceLocation getLocation() const { 1242 return SourceLocation::getFromRawEncoding(Location); 1243 } 1244 1245 uint64_t getInteger() const { 1246 return Kind == IntegerLiteral ? IntegerValue : 0; 1247 } 1248 1249 StringRef getString() const { 1250 return Kind == IntegerLiteral ? StringRef() 1251 : StringRef(StringData, StringLength); 1252 } 1253 }; 1254 1255 class ModuleMapParser { 1256 Lexer &L; 1257 SourceManager &SourceMgr; 1258 1259 /// \brief Default target information, used only for string literal 1260 /// parsing. 1261 const TargetInfo *Target; 1262 1263 DiagnosticsEngine &Diags; 1264 ModuleMap ⤅ 1265 1266 /// \brief The current module map file. 1267 const FileEntry *ModuleMapFile; 1268 1269 /// \brief The directory that file names in this module map file should 1270 /// be resolved relative to. 1271 const DirectoryEntry *Directory; 1272 1273 /// \brief Whether this module map is in a system header directory. 1274 bool IsSystem; 1275 1276 /// \brief Whether an error occurred. 1277 bool HadError; 1278 1279 /// \brief Stores string data for the various string literals referenced 1280 /// during parsing. 1281 llvm::BumpPtrAllocator StringData; 1282 1283 /// \brief The current token. 1284 MMToken Tok; 1285 1286 /// \brief The active module. 1287 Module *ActiveModule; 1288 1289 /// \brief Whether a module uses the 'requires excluded' hack to mark its 1290 /// contents as 'textual'. 1291 /// 1292 /// On older Darwin SDK versions, 'requires excluded' is used to mark the 1293 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as 1294 /// non-modular headers. For backwards compatibility, we continue to 1295 /// support this idiom for just these modules, and map the headers to 1296 /// 'textual' to match the original intent. 1297 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack; 1298 1299 /// \brief Consume the current token and return its location. 1300 SourceLocation consumeToken(); 1301 1302 /// \brief Skip tokens until we reach the a token with the given kind 1303 /// (or the end of the file). 1304 void skipUntil(MMToken::TokenKind K); 1305 1306 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1307 bool parseModuleId(ModuleId &Id); 1308 void parseModuleDecl(); 1309 void parseExternModuleDecl(); 1310 void parseRequiresDecl(); 1311 void parseHeaderDecl(clang::MMToken::TokenKind, 1312 SourceLocation LeadingLoc); 1313 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1314 void parseExportDecl(); 1315 void parseUseDecl(); 1316 void parseLinkDecl(); 1317 void parseConfigMacros(); 1318 void parseConflict(); 1319 void parseInferredModuleDecl(bool Framework, bool Explicit); 1320 1321 typedef ModuleMap::Attributes Attributes; 1322 bool parseOptionalAttributes(Attributes &Attrs); 1323 1324 public: 1325 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1326 const TargetInfo *Target, 1327 DiagnosticsEngine &Diags, 1328 ModuleMap &Map, 1329 const FileEntry *ModuleMapFile, 1330 const DirectoryEntry *Directory, 1331 bool IsSystem) 1332 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1333 ModuleMapFile(ModuleMapFile), Directory(Directory), 1334 IsSystem(IsSystem), HadError(false), ActiveModule(nullptr) 1335 { 1336 Tok.clear(); 1337 consumeToken(); 1338 } 1339 1340 bool parseModuleMapFile(); 1341 1342 bool terminatedByDirective() { return false; } 1343 SourceLocation getLocation() { return Tok.getLocation(); } 1344 }; 1345 } 1346 1347 SourceLocation ModuleMapParser::consumeToken() { 1348 SourceLocation Result = Tok.getLocation(); 1349 1350 retry: 1351 Tok.clear(); 1352 Token LToken; 1353 L.LexFromRawLexer(LToken); 1354 Tok.Location = LToken.getLocation().getRawEncoding(); 1355 switch (LToken.getKind()) { 1356 case tok::raw_identifier: { 1357 StringRef RI = LToken.getRawIdentifier(); 1358 Tok.StringData = RI.data(); 1359 Tok.StringLength = RI.size(); 1360 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1361 .Case("config_macros", MMToken::ConfigMacros) 1362 .Case("conflict", MMToken::Conflict) 1363 .Case("exclude", MMToken::ExcludeKeyword) 1364 .Case("explicit", MMToken::ExplicitKeyword) 1365 .Case("export", MMToken::ExportKeyword) 1366 .Case("extern", MMToken::ExternKeyword) 1367 .Case("framework", MMToken::FrameworkKeyword) 1368 .Case("header", MMToken::HeaderKeyword) 1369 .Case("link", MMToken::LinkKeyword) 1370 .Case("module", MMToken::ModuleKeyword) 1371 .Case("private", MMToken::PrivateKeyword) 1372 .Case("requires", MMToken::RequiresKeyword) 1373 .Case("textual", MMToken::TextualKeyword) 1374 .Case("umbrella", MMToken::UmbrellaKeyword) 1375 .Case("use", MMToken::UseKeyword) 1376 .Default(MMToken::Identifier); 1377 break; 1378 } 1379 1380 case tok::comma: 1381 Tok.Kind = MMToken::Comma; 1382 break; 1383 1384 case tok::eof: 1385 Tok.Kind = MMToken::EndOfFile; 1386 break; 1387 1388 case tok::l_brace: 1389 Tok.Kind = MMToken::LBrace; 1390 break; 1391 1392 case tok::l_square: 1393 Tok.Kind = MMToken::LSquare; 1394 break; 1395 1396 case tok::period: 1397 Tok.Kind = MMToken::Period; 1398 break; 1399 1400 case tok::r_brace: 1401 Tok.Kind = MMToken::RBrace; 1402 break; 1403 1404 case tok::r_square: 1405 Tok.Kind = MMToken::RSquare; 1406 break; 1407 1408 case tok::star: 1409 Tok.Kind = MMToken::Star; 1410 break; 1411 1412 case tok::exclaim: 1413 Tok.Kind = MMToken::Exclaim; 1414 break; 1415 1416 case tok::string_literal: { 1417 if (LToken.hasUDSuffix()) { 1418 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1419 HadError = true; 1420 goto retry; 1421 } 1422 1423 // Parse the string literal. 1424 LangOptions LangOpts; 1425 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1426 if (StringLiteral.hadError) 1427 goto retry; 1428 1429 // Copy the string literal into our string data allocator. 1430 unsigned Length = StringLiteral.GetStringLength(); 1431 char *Saved = StringData.Allocate<char>(Length + 1); 1432 memcpy(Saved, StringLiteral.GetString().data(), Length); 1433 Saved[Length] = 0; 1434 1435 // Form the token. 1436 Tok.Kind = MMToken::StringLiteral; 1437 Tok.StringData = Saved; 1438 Tok.StringLength = Length; 1439 break; 1440 } 1441 1442 case tok::numeric_constant: { 1443 // We don't support any suffixes or other complications. 1444 SmallString<32> SpellingBuffer; 1445 SpellingBuffer.resize(LToken.getLength() + 1); 1446 const char *Start = SpellingBuffer.data(); 1447 unsigned Length = 1448 Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts()); 1449 uint64_t Value; 1450 if (StringRef(Start, Length).getAsInteger(0, Value)) { 1451 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1452 HadError = true; 1453 goto retry; 1454 } 1455 1456 Tok.Kind = MMToken::IntegerLiteral; 1457 Tok.IntegerValue = Value; 1458 break; 1459 } 1460 1461 case tok::comment: 1462 goto retry; 1463 1464 case tok::hash: 1465 // A module map can be terminated prematurely by 1466 // #pragma clang module contents 1467 // When building the module, we'll treat the rest of the file as the 1468 // contents of the module. 1469 { 1470 auto NextIsIdent = [&](StringRef Str) -> bool { 1471 L.LexFromRawLexer(LToken); 1472 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && 1473 LToken.getRawIdentifier() == Str; 1474 }; 1475 if (NextIsIdent("pragma") && NextIsIdent("clang") && 1476 NextIsIdent("module") && NextIsIdent("contents")) { 1477 Tok.Kind = MMToken::EndOfFile; 1478 break; 1479 } 1480 } 1481 LLVM_FALLTHROUGH; 1482 1483 default: 1484 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1485 HadError = true; 1486 goto retry; 1487 } 1488 1489 return Result; 1490 } 1491 1492 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1493 unsigned braceDepth = 0; 1494 unsigned squareDepth = 0; 1495 do { 1496 switch (Tok.Kind) { 1497 case MMToken::EndOfFile: 1498 return; 1499 1500 case MMToken::LBrace: 1501 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1502 return; 1503 1504 ++braceDepth; 1505 break; 1506 1507 case MMToken::LSquare: 1508 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1509 return; 1510 1511 ++squareDepth; 1512 break; 1513 1514 case MMToken::RBrace: 1515 if (braceDepth > 0) 1516 --braceDepth; 1517 else if (Tok.is(K)) 1518 return; 1519 break; 1520 1521 case MMToken::RSquare: 1522 if (squareDepth > 0) 1523 --squareDepth; 1524 else if (Tok.is(K)) 1525 return; 1526 break; 1527 1528 default: 1529 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1530 return; 1531 break; 1532 } 1533 1534 consumeToken(); 1535 } while (true); 1536 } 1537 1538 /// \brief Parse a module-id. 1539 /// 1540 /// module-id: 1541 /// identifier 1542 /// identifier '.' module-id 1543 /// 1544 /// \returns true if an error occurred, false otherwise. 1545 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1546 Id.clear(); 1547 do { 1548 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1549 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1550 consumeToken(); 1551 } else { 1552 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1553 return true; 1554 } 1555 1556 if (!Tok.is(MMToken::Period)) 1557 break; 1558 1559 consumeToken(); 1560 } while (true); 1561 1562 return false; 1563 } 1564 1565 namespace { 1566 /// \brief Enumerates the known attributes. 1567 enum AttributeKind { 1568 /// \brief An unknown attribute. 1569 AT_unknown, 1570 /// \brief The 'system' attribute. 1571 AT_system, 1572 /// \brief The 'extern_c' attribute. 1573 AT_extern_c, 1574 /// \brief The 'exhaustive' attribute. 1575 AT_exhaustive, 1576 /// \brief The 'no_undeclared_includes' attribute. 1577 AT_no_undeclared_includes 1578 }; 1579 } 1580 1581 /// \brief Parse a module declaration. 1582 /// 1583 /// module-declaration: 1584 /// 'extern' 'module' module-id string-literal 1585 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1586 /// { module-member* } 1587 /// 1588 /// module-member: 1589 /// requires-declaration 1590 /// header-declaration 1591 /// submodule-declaration 1592 /// export-declaration 1593 /// link-declaration 1594 /// 1595 /// submodule-declaration: 1596 /// module-declaration 1597 /// inferred-submodule-declaration 1598 void ModuleMapParser::parseModuleDecl() { 1599 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1600 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1601 if (Tok.is(MMToken::ExternKeyword)) { 1602 parseExternModuleDecl(); 1603 return; 1604 } 1605 1606 // Parse 'explicit' or 'framework' keyword, if present. 1607 SourceLocation ExplicitLoc; 1608 bool Explicit = false; 1609 bool Framework = false; 1610 1611 // Parse 'explicit' keyword, if present. 1612 if (Tok.is(MMToken::ExplicitKeyword)) { 1613 ExplicitLoc = consumeToken(); 1614 Explicit = true; 1615 } 1616 1617 // Parse 'framework' keyword, if present. 1618 if (Tok.is(MMToken::FrameworkKeyword)) { 1619 consumeToken(); 1620 Framework = true; 1621 } 1622 1623 // Parse 'module' keyword. 1624 if (!Tok.is(MMToken::ModuleKeyword)) { 1625 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1626 consumeToken(); 1627 HadError = true; 1628 return; 1629 } 1630 consumeToken(); // 'module' keyword 1631 1632 // If we have a wildcard for the module name, this is an inferred submodule. 1633 // Parse it. 1634 if (Tok.is(MMToken::Star)) 1635 return parseInferredModuleDecl(Framework, Explicit); 1636 1637 // Parse the module name. 1638 ModuleId Id; 1639 if (parseModuleId(Id)) { 1640 HadError = true; 1641 return; 1642 } 1643 1644 if (ActiveModule) { 1645 if (Id.size() > 1) { 1646 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1647 << SourceRange(Id.front().second, Id.back().second); 1648 1649 HadError = true; 1650 return; 1651 } 1652 } else if (Id.size() == 1 && Explicit) { 1653 // Top-level modules can't be explicit. 1654 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1655 Explicit = false; 1656 ExplicitLoc = SourceLocation(); 1657 HadError = true; 1658 } 1659 1660 Module *PreviousActiveModule = ActiveModule; 1661 if (Id.size() > 1) { 1662 // This module map defines a submodule. Go find the module of which it 1663 // is a submodule. 1664 ActiveModule = nullptr; 1665 const Module *TopLevelModule = nullptr; 1666 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1667 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1668 if (I == 0) 1669 TopLevelModule = Next; 1670 ActiveModule = Next; 1671 continue; 1672 } 1673 1674 if (ActiveModule) { 1675 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1676 << Id[I].first 1677 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1678 } else { 1679 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1680 } 1681 HadError = true; 1682 return; 1683 } 1684 1685 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1686 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1687 "submodule defined in same file as 'module *' that allowed its " 1688 "top-level module"); 1689 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1690 } 1691 } 1692 1693 StringRef ModuleName = Id.back().first; 1694 SourceLocation ModuleNameLoc = Id.back().second; 1695 1696 // Parse the optional attribute list. 1697 Attributes Attrs; 1698 if (parseOptionalAttributes(Attrs)) 1699 return; 1700 1701 1702 // Parse the opening brace. 1703 if (!Tok.is(MMToken::LBrace)) { 1704 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1705 << ModuleName; 1706 HadError = true; 1707 return; 1708 } 1709 SourceLocation LBraceLoc = consumeToken(); 1710 1711 // Determine whether this (sub)module has already been defined. 1712 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1713 // We might see a (re)definition of a module that we already have a 1714 // definition for in two cases: 1715 // - If we loaded one definition from an AST file and we've just found a 1716 // corresponding definition in a module map file, or 1717 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid(); 1718 // - If we're building a (preprocessed) module and we've just loaded the 1719 // module map file from which it was created. 1720 bool ParsedAsMainInput = 1721 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 1722 Map.LangOpts.CurrentModule == ModuleName && 1723 SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 1724 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 1725 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) { 1726 // Skip the module definition. 1727 skipUntil(MMToken::RBrace); 1728 if (Tok.is(MMToken::RBrace)) 1729 consumeToken(); 1730 else { 1731 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1732 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1733 HadError = true; 1734 } 1735 return; 1736 } 1737 1738 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1739 << ModuleName; 1740 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1741 1742 // Skip the module definition. 1743 skipUntil(MMToken::RBrace); 1744 if (Tok.is(MMToken::RBrace)) 1745 consumeToken(); 1746 1747 HadError = true; 1748 return; 1749 } 1750 1751 // Start defining this module. 1752 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1753 Explicit).first; 1754 ActiveModule->DefinitionLoc = ModuleNameLoc; 1755 if (Attrs.IsSystem || IsSystem) 1756 ActiveModule->IsSystem = true; 1757 if (Attrs.IsExternC) 1758 ActiveModule->IsExternC = true; 1759 if (Attrs.NoUndeclaredIncludes || 1760 (!ActiveModule->Parent && ModuleName == "Darwin")) 1761 ActiveModule->NoUndeclaredIncludes = true; 1762 ActiveModule->Directory = Directory; 1763 1764 if (!ActiveModule->Parent) { 1765 StringRef MapFileName(ModuleMapFile->getName()); 1766 if (MapFileName.endswith("module.private.modulemap") || 1767 MapFileName.endswith("module_private.map")) { 1768 // Adding a top-level module from a private modulemap is likely a 1769 // user error; we check to see if there's another top-level module 1770 // defined in the non-private map in the same dir, and if so emit a 1771 // warning. 1772 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1773 auto const *M = E->getValue(); 1774 if (!M->Parent && 1775 M->Directory == ActiveModule->Directory && 1776 M->Name != ActiveModule->Name) { 1777 Diags.Report(ActiveModule->DefinitionLoc, 1778 diag::warn_mmap_mismatched_top_level_private) 1779 << ActiveModule->Name << M->Name; 1780 // The pattern we're defending against here is typically due to 1781 // a module named FooPrivate which is supposed to be a submodule 1782 // called Foo.Private. Emit a fixit in that case. 1783 auto D = 1784 Diags.Report(ActiveModule->DefinitionLoc, 1785 diag::note_mmap_rename_top_level_private_as_submodule); 1786 D << ActiveModule->Name << M->Name; 1787 StringRef Bad(ActiveModule->Name); 1788 if (Bad.consume_back("Private")) { 1789 SmallString<128> Fixed = Bad; 1790 Fixed.append(".Private"); 1791 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, 1792 Fixed); 1793 } 1794 break; 1795 } 1796 } 1797 } 1798 } 1799 1800 bool Done = false; 1801 do { 1802 switch (Tok.Kind) { 1803 case MMToken::EndOfFile: 1804 case MMToken::RBrace: 1805 Done = true; 1806 break; 1807 1808 case MMToken::ConfigMacros: 1809 parseConfigMacros(); 1810 break; 1811 1812 case MMToken::Conflict: 1813 parseConflict(); 1814 break; 1815 1816 case MMToken::ExplicitKeyword: 1817 case MMToken::ExternKeyword: 1818 case MMToken::FrameworkKeyword: 1819 case MMToken::ModuleKeyword: 1820 parseModuleDecl(); 1821 break; 1822 1823 case MMToken::ExportKeyword: 1824 parseExportDecl(); 1825 break; 1826 1827 case MMToken::UseKeyword: 1828 parseUseDecl(); 1829 break; 1830 1831 case MMToken::RequiresKeyword: 1832 parseRequiresDecl(); 1833 break; 1834 1835 case MMToken::TextualKeyword: 1836 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1837 break; 1838 1839 case MMToken::UmbrellaKeyword: { 1840 SourceLocation UmbrellaLoc = consumeToken(); 1841 if (Tok.is(MMToken::HeaderKeyword)) 1842 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1843 else 1844 parseUmbrellaDirDecl(UmbrellaLoc); 1845 break; 1846 } 1847 1848 case MMToken::ExcludeKeyword: 1849 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1850 break; 1851 1852 case MMToken::PrivateKeyword: 1853 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1854 break; 1855 1856 case MMToken::HeaderKeyword: 1857 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1858 break; 1859 1860 case MMToken::LinkKeyword: 1861 parseLinkDecl(); 1862 break; 1863 1864 default: 1865 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1866 consumeToken(); 1867 break; 1868 } 1869 } while (!Done); 1870 1871 if (Tok.is(MMToken::RBrace)) 1872 consumeToken(); 1873 else { 1874 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1875 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1876 HadError = true; 1877 } 1878 1879 // If the active module is a top-level framework, and there are no link 1880 // libraries, automatically link against the framework. 1881 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1882 ActiveModule->LinkLibraries.empty()) { 1883 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1884 } 1885 1886 // If the module meets all requirements but is still unavailable, mark the 1887 // whole tree as unavailable to prevent it from building. 1888 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1889 ActiveModule->Parent) { 1890 ActiveModule->getTopLevelModule()->markUnavailable(); 1891 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1892 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1893 } 1894 1895 // We're done parsing this module. Pop back to the previous module. 1896 ActiveModule = PreviousActiveModule; 1897 } 1898 1899 /// \brief Parse an extern module declaration. 1900 /// 1901 /// extern module-declaration: 1902 /// 'extern' 'module' module-id string-literal 1903 void ModuleMapParser::parseExternModuleDecl() { 1904 assert(Tok.is(MMToken::ExternKeyword)); 1905 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 1906 1907 // Parse 'module' keyword. 1908 if (!Tok.is(MMToken::ModuleKeyword)) { 1909 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1910 consumeToken(); 1911 HadError = true; 1912 return; 1913 } 1914 consumeToken(); // 'module' keyword 1915 1916 // Parse the module name. 1917 ModuleId Id; 1918 if (parseModuleId(Id)) { 1919 HadError = true; 1920 return; 1921 } 1922 1923 // Parse the referenced module map file name. 1924 if (!Tok.is(MMToken::StringLiteral)) { 1925 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1926 HadError = true; 1927 return; 1928 } 1929 std::string FileName = Tok.getString(); 1930 consumeToken(); // filename 1931 1932 StringRef FileNameRef = FileName; 1933 SmallString<128> ModuleMapFileName; 1934 if (llvm::sys::path::is_relative(FileNameRef)) { 1935 ModuleMapFileName += Directory->getName(); 1936 llvm::sys::path::append(ModuleMapFileName, FileName); 1937 FileNameRef = ModuleMapFileName; 1938 } 1939 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1940 Map.parseModuleMapFile( 1941 File, /*IsSystem=*/false, 1942 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 1943 ? Directory 1944 : File->getDir(), 1945 FileID(), nullptr, ExternLoc); 1946 } 1947 1948 /// Whether to add the requirement \p Feature to the module \p M. 1949 /// 1950 /// This preserves backwards compatibility for two hacks in the Darwin system 1951 /// module map files: 1952 /// 1953 /// 1. The use of 'requires excluded' to make headers non-modular, which 1954 /// should really be mapped to 'textual' now that we have this feature. We 1955 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 1956 /// true. Later, this bit will be used to map all the headers inside this 1957 /// module to 'textual'. 1958 /// 1959 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 1960 /// 1961 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 1962 /// was never correct and causes issues now that we check it, so drop it. 1963 static bool shouldAddRequirement(Module *M, StringRef Feature, 1964 bool &IsRequiresExcludedHack) { 1965 if (Feature == "excluded" && 1966 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 1967 M->fullModuleNameIs({"Tcl", "Private"}))) { 1968 IsRequiresExcludedHack = true; 1969 return false; 1970 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 1971 return false; 1972 } 1973 1974 return true; 1975 } 1976 1977 /// \brief Parse a requires declaration. 1978 /// 1979 /// requires-declaration: 1980 /// 'requires' feature-list 1981 /// 1982 /// feature-list: 1983 /// feature ',' feature-list 1984 /// feature 1985 /// 1986 /// feature: 1987 /// '!'[opt] identifier 1988 void ModuleMapParser::parseRequiresDecl() { 1989 assert(Tok.is(MMToken::RequiresKeyword)); 1990 1991 // Parse 'requires' keyword. 1992 consumeToken(); 1993 1994 // Parse the feature-list. 1995 do { 1996 bool RequiredState = true; 1997 if (Tok.is(MMToken::Exclaim)) { 1998 RequiredState = false; 1999 consumeToken(); 2000 } 2001 2002 if (!Tok.is(MMToken::Identifier)) { 2003 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 2004 HadError = true; 2005 return; 2006 } 2007 2008 // Consume the feature name. 2009 std::string Feature = Tok.getString(); 2010 consumeToken(); 2011 2012 bool IsRequiresExcludedHack = false; 2013 bool ShouldAddRequirement = 2014 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2015 2016 if (IsRequiresExcludedHack) 2017 UsesRequiresExcludedHack.insert(ActiveModule); 2018 2019 if (ShouldAddRequirement) { 2020 // Add this feature. 2021 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2022 *Map.Target); 2023 } 2024 2025 if (!Tok.is(MMToken::Comma)) 2026 break; 2027 2028 // Consume the comma. 2029 consumeToken(); 2030 } while (true); 2031 } 2032 2033 /// \brief Parse a header declaration. 2034 /// 2035 /// header-declaration: 2036 /// 'textual'[opt] 'header' string-literal 2037 /// 'private' 'textual'[opt] 'header' string-literal 2038 /// 'exclude' 'header' string-literal 2039 /// 'umbrella' 'header' string-literal 2040 /// 2041 /// FIXME: Support 'private textual header'. 2042 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2043 SourceLocation LeadingLoc) { 2044 // We've already consumed the first token. 2045 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2046 if (LeadingToken == MMToken::PrivateKeyword) { 2047 Role = ModuleMap::PrivateHeader; 2048 // 'private' may optionally be followed by 'textual'. 2049 if (Tok.is(MMToken::TextualKeyword)) { 2050 LeadingToken = Tok.Kind; 2051 consumeToken(); 2052 } 2053 } 2054 2055 if (LeadingToken == MMToken::TextualKeyword) 2056 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2057 2058 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2059 // Mark this header 'textual' (see doc comment for 2060 // Module::UsesRequiresExcludedHack). 2061 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2062 } 2063 2064 if (LeadingToken != MMToken::HeaderKeyword) { 2065 if (!Tok.is(MMToken::HeaderKeyword)) { 2066 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2067 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2068 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2069 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2070 return; 2071 } 2072 consumeToken(); 2073 } 2074 2075 // Parse the header name. 2076 if (!Tok.is(MMToken::StringLiteral)) { 2077 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2078 << "header"; 2079 HadError = true; 2080 return; 2081 } 2082 Module::UnresolvedHeaderDirective Header; 2083 Header.FileName = Tok.getString(); 2084 Header.FileNameLoc = consumeToken(); 2085 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2086 Header.Kind = 2087 (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded 2088 : Map.headerRoleToKind(Role)); 2089 2090 // Check whether we already have an umbrella. 2091 if (Header.IsUmbrella && ActiveModule->Umbrella) { 2092 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2093 << ActiveModule->getFullModuleName(); 2094 HadError = true; 2095 return; 2096 } 2097 2098 // If we were given stat information, parse it so we can skip looking for 2099 // the file. 2100 if (Tok.is(MMToken::LBrace)) { 2101 SourceLocation LBraceLoc = consumeToken(); 2102 2103 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2104 enum Attribute { Size, ModTime, Unknown }; 2105 StringRef Str = Tok.getString(); 2106 SourceLocation Loc = consumeToken(); 2107 switch (llvm::StringSwitch<Attribute>(Str) 2108 .Case("size", Size) 2109 .Case("mtime", ModTime) 2110 .Default(Unknown)) { 2111 case Size: 2112 if (Header.Size) 2113 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2114 if (!Tok.is(MMToken::IntegerLiteral)) { 2115 Diags.Report(Tok.getLocation(), 2116 diag::err_mmap_invalid_header_attribute_value) << Str; 2117 skipUntil(MMToken::RBrace); 2118 break; 2119 } 2120 Header.Size = Tok.getInteger(); 2121 consumeToken(); 2122 break; 2123 2124 case ModTime: 2125 if (Header.ModTime) 2126 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2127 if (!Tok.is(MMToken::IntegerLiteral)) { 2128 Diags.Report(Tok.getLocation(), 2129 diag::err_mmap_invalid_header_attribute_value) << Str; 2130 skipUntil(MMToken::RBrace); 2131 break; 2132 } 2133 Header.ModTime = Tok.getInteger(); 2134 consumeToken(); 2135 break; 2136 2137 case Unknown: 2138 Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2139 skipUntil(MMToken::RBrace); 2140 break; 2141 } 2142 } 2143 2144 if (Tok.is(MMToken::RBrace)) 2145 consumeToken(); 2146 else { 2147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2148 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2149 HadError = true; 2150 } 2151 } 2152 2153 Map.addUnresolvedHeader(ActiveModule, std::move(Header)); 2154 } 2155 2156 static int compareModuleHeaders(const Module::Header *A, 2157 const Module::Header *B) { 2158 return A->NameAsWritten.compare(B->NameAsWritten); 2159 } 2160 2161 /// \brief Parse an umbrella directory declaration. 2162 /// 2163 /// umbrella-dir-declaration: 2164 /// umbrella string-literal 2165 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2166 // Parse the directory name. 2167 if (!Tok.is(MMToken::StringLiteral)) { 2168 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2169 << "umbrella"; 2170 HadError = true; 2171 return; 2172 } 2173 2174 std::string DirName = Tok.getString(); 2175 SourceLocation DirNameLoc = consumeToken(); 2176 2177 // Check whether we already have an umbrella. 2178 if (ActiveModule->Umbrella) { 2179 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2180 << ActiveModule->getFullModuleName(); 2181 HadError = true; 2182 return; 2183 } 2184 2185 // Look for this file. 2186 const DirectoryEntry *Dir = nullptr; 2187 if (llvm::sys::path::is_absolute(DirName)) 2188 Dir = SourceMgr.getFileManager().getDirectory(DirName); 2189 else { 2190 SmallString<128> PathName; 2191 PathName = Directory->getName(); 2192 llvm::sys::path::append(PathName, DirName); 2193 Dir = SourceMgr.getFileManager().getDirectory(PathName); 2194 } 2195 2196 if (!Dir) { 2197 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2198 << DirName; 2199 return; 2200 } 2201 2202 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2203 // Mark this header 'textual' (see doc comment for 2204 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2205 // directory is relatively expensive, in practice this only applies to the 2206 // uncommonly used Tcl module on Darwin platforms. 2207 std::error_code EC; 2208 SmallVector<Module::Header, 6> Headers; 2209 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem(); 2210 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2211 I != E && !EC; I.increment(EC)) { 2212 if (const FileEntry *FE = 2213 SourceMgr.getFileManager().getFile(I->getName())) { 2214 2215 Module::Header Header = {I->getName(), FE}; 2216 Headers.push_back(std::move(Header)); 2217 } 2218 } 2219 2220 // Sort header paths so that the pcm doesn't depend on iteration order. 2221 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2222 2223 for (auto &Header : Headers) 2224 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2225 return; 2226 } 2227 2228 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 2229 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2230 << OwningModule->getFullModuleName(); 2231 HadError = true; 2232 return; 2233 } 2234 2235 // Record this umbrella directory. 2236 Map.setUmbrellaDir(ActiveModule, Dir, DirName); 2237 } 2238 2239 /// \brief Parse a module export declaration. 2240 /// 2241 /// export-declaration: 2242 /// 'export' wildcard-module-id 2243 /// 2244 /// wildcard-module-id: 2245 /// identifier 2246 /// '*' 2247 /// identifier '.' wildcard-module-id 2248 void ModuleMapParser::parseExportDecl() { 2249 assert(Tok.is(MMToken::ExportKeyword)); 2250 SourceLocation ExportLoc = consumeToken(); 2251 2252 // Parse the module-id with an optional wildcard at the end. 2253 ModuleId ParsedModuleId; 2254 bool Wildcard = false; 2255 do { 2256 // FIXME: Support string-literal module names here. 2257 if (Tok.is(MMToken::Identifier)) { 2258 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 2259 Tok.getLocation())); 2260 consumeToken(); 2261 2262 if (Tok.is(MMToken::Period)) { 2263 consumeToken(); 2264 continue; 2265 } 2266 2267 break; 2268 } 2269 2270 if(Tok.is(MMToken::Star)) { 2271 Wildcard = true; 2272 consumeToken(); 2273 break; 2274 } 2275 2276 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2277 HadError = true; 2278 return; 2279 } while (true); 2280 2281 Module::UnresolvedExportDecl Unresolved = { 2282 ExportLoc, ParsedModuleId, Wildcard 2283 }; 2284 ActiveModule->UnresolvedExports.push_back(Unresolved); 2285 } 2286 2287 /// \brief Parse a module use declaration. 2288 /// 2289 /// use-declaration: 2290 /// 'use' wildcard-module-id 2291 void ModuleMapParser::parseUseDecl() { 2292 assert(Tok.is(MMToken::UseKeyword)); 2293 auto KWLoc = consumeToken(); 2294 // Parse the module-id. 2295 ModuleId ParsedModuleId; 2296 parseModuleId(ParsedModuleId); 2297 2298 if (ActiveModule->Parent) 2299 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2300 else 2301 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2302 } 2303 2304 /// \brief Parse a link declaration. 2305 /// 2306 /// module-declaration: 2307 /// 'link' 'framework'[opt] string-literal 2308 void ModuleMapParser::parseLinkDecl() { 2309 assert(Tok.is(MMToken::LinkKeyword)); 2310 SourceLocation LinkLoc = consumeToken(); 2311 2312 // Parse the optional 'framework' keyword. 2313 bool IsFramework = false; 2314 if (Tok.is(MMToken::FrameworkKeyword)) { 2315 consumeToken(); 2316 IsFramework = true; 2317 } 2318 2319 // Parse the library name 2320 if (!Tok.is(MMToken::StringLiteral)) { 2321 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2322 << IsFramework << SourceRange(LinkLoc); 2323 HadError = true; 2324 return; 2325 } 2326 2327 std::string LibraryName = Tok.getString(); 2328 consumeToken(); 2329 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2330 IsFramework)); 2331 } 2332 2333 /// \brief Parse a configuration macro declaration. 2334 /// 2335 /// module-declaration: 2336 /// 'config_macros' attributes[opt] config-macro-list? 2337 /// 2338 /// config-macro-list: 2339 /// identifier (',' identifier)? 2340 void ModuleMapParser::parseConfigMacros() { 2341 assert(Tok.is(MMToken::ConfigMacros)); 2342 SourceLocation ConfigMacrosLoc = consumeToken(); 2343 2344 // Only top-level modules can have configuration macros. 2345 if (ActiveModule->Parent) { 2346 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2347 } 2348 2349 // Parse the optional attributes. 2350 Attributes Attrs; 2351 if (parseOptionalAttributes(Attrs)) 2352 return; 2353 2354 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2355 ActiveModule->ConfigMacrosExhaustive = true; 2356 } 2357 2358 // If we don't have an identifier, we're done. 2359 // FIXME: Support macros with the same name as a keyword here. 2360 if (!Tok.is(MMToken::Identifier)) 2361 return; 2362 2363 // Consume the first identifier. 2364 if (!ActiveModule->Parent) { 2365 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2366 } 2367 consumeToken(); 2368 2369 do { 2370 // If there's a comma, consume it. 2371 if (!Tok.is(MMToken::Comma)) 2372 break; 2373 consumeToken(); 2374 2375 // We expect to see a macro name here. 2376 // FIXME: Support macros with the same name as a keyword here. 2377 if (!Tok.is(MMToken::Identifier)) { 2378 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2379 break; 2380 } 2381 2382 // Consume the macro name. 2383 if (!ActiveModule->Parent) { 2384 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2385 } 2386 consumeToken(); 2387 } while (true); 2388 } 2389 2390 /// \brief Format a module-id into a string. 2391 static std::string formatModuleId(const ModuleId &Id) { 2392 std::string result; 2393 { 2394 llvm::raw_string_ostream OS(result); 2395 2396 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2397 if (I) 2398 OS << "."; 2399 OS << Id[I].first; 2400 } 2401 } 2402 2403 return result; 2404 } 2405 2406 /// \brief Parse a conflict declaration. 2407 /// 2408 /// module-declaration: 2409 /// 'conflict' module-id ',' string-literal 2410 void ModuleMapParser::parseConflict() { 2411 assert(Tok.is(MMToken::Conflict)); 2412 SourceLocation ConflictLoc = consumeToken(); 2413 Module::UnresolvedConflict Conflict; 2414 2415 // Parse the module-id. 2416 if (parseModuleId(Conflict.Id)) 2417 return; 2418 2419 // Parse the ','. 2420 if (!Tok.is(MMToken::Comma)) { 2421 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2422 << SourceRange(ConflictLoc); 2423 return; 2424 } 2425 consumeToken(); 2426 2427 // Parse the message. 2428 if (!Tok.is(MMToken::StringLiteral)) { 2429 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2430 << formatModuleId(Conflict.Id); 2431 return; 2432 } 2433 Conflict.Message = Tok.getString().str(); 2434 consumeToken(); 2435 2436 // Add this unresolved conflict. 2437 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2438 } 2439 2440 /// \brief Parse an inferred module declaration (wildcard modules). 2441 /// 2442 /// module-declaration: 2443 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2444 /// { inferred-module-member* } 2445 /// 2446 /// inferred-module-member: 2447 /// 'export' '*' 2448 /// 'exclude' identifier 2449 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2450 assert(Tok.is(MMToken::Star)); 2451 SourceLocation StarLoc = consumeToken(); 2452 bool Failed = false; 2453 2454 // Inferred modules must be submodules. 2455 if (!ActiveModule && !Framework) { 2456 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2457 Failed = true; 2458 } 2459 2460 if (ActiveModule) { 2461 // Inferred modules must have umbrella directories. 2462 if (!Failed && ActiveModule->IsAvailable && 2463 !ActiveModule->getUmbrellaDir()) { 2464 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2465 Failed = true; 2466 } 2467 2468 // Check for redefinition of an inferred module. 2469 if (!Failed && ActiveModule->InferSubmodules) { 2470 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2471 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2472 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2473 diag::note_mmap_prev_definition); 2474 Failed = true; 2475 } 2476 2477 // Check for the 'framework' keyword, which is not permitted here. 2478 if (Framework) { 2479 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2480 Framework = false; 2481 } 2482 } else if (Explicit) { 2483 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2484 Explicit = false; 2485 } 2486 2487 // If there were any problems with this inferred submodule, skip its body. 2488 if (Failed) { 2489 if (Tok.is(MMToken::LBrace)) { 2490 consumeToken(); 2491 skipUntil(MMToken::RBrace); 2492 if (Tok.is(MMToken::RBrace)) 2493 consumeToken(); 2494 } 2495 HadError = true; 2496 return; 2497 } 2498 2499 // Parse optional attributes. 2500 Attributes Attrs; 2501 if (parseOptionalAttributes(Attrs)) 2502 return; 2503 2504 if (ActiveModule) { 2505 // Note that we have an inferred submodule. 2506 ActiveModule->InferSubmodules = true; 2507 ActiveModule->InferredSubmoduleLoc = StarLoc; 2508 ActiveModule->InferExplicitSubmodules = Explicit; 2509 } else { 2510 // We'll be inferring framework modules for this directory. 2511 Map.InferredDirectories[Directory].InferModules = true; 2512 Map.InferredDirectories[Directory].Attrs = Attrs; 2513 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2514 // FIXME: Handle the 'framework' keyword. 2515 } 2516 2517 // Parse the opening brace. 2518 if (!Tok.is(MMToken::LBrace)) { 2519 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2520 HadError = true; 2521 return; 2522 } 2523 SourceLocation LBraceLoc = consumeToken(); 2524 2525 // Parse the body of the inferred submodule. 2526 bool Done = false; 2527 do { 2528 switch (Tok.Kind) { 2529 case MMToken::EndOfFile: 2530 case MMToken::RBrace: 2531 Done = true; 2532 break; 2533 2534 case MMToken::ExcludeKeyword: { 2535 if (ActiveModule) { 2536 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2537 << (ActiveModule != nullptr); 2538 consumeToken(); 2539 break; 2540 } 2541 2542 consumeToken(); 2543 // FIXME: Support string-literal module names here. 2544 if (!Tok.is(MMToken::Identifier)) { 2545 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2546 break; 2547 } 2548 2549 Map.InferredDirectories[Directory].ExcludedModules 2550 .push_back(Tok.getString()); 2551 consumeToken(); 2552 break; 2553 } 2554 2555 case MMToken::ExportKeyword: 2556 if (!ActiveModule) { 2557 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2558 << (ActiveModule != nullptr); 2559 consumeToken(); 2560 break; 2561 } 2562 2563 consumeToken(); 2564 if (Tok.is(MMToken::Star)) 2565 ActiveModule->InferExportWildcard = true; 2566 else 2567 Diags.Report(Tok.getLocation(), 2568 diag::err_mmap_expected_export_wildcard); 2569 consumeToken(); 2570 break; 2571 2572 case MMToken::ExplicitKeyword: 2573 case MMToken::ModuleKeyword: 2574 case MMToken::HeaderKeyword: 2575 case MMToken::PrivateKeyword: 2576 case MMToken::UmbrellaKeyword: 2577 default: 2578 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2579 << (ActiveModule != nullptr); 2580 consumeToken(); 2581 break; 2582 } 2583 } while (!Done); 2584 2585 if (Tok.is(MMToken::RBrace)) 2586 consumeToken(); 2587 else { 2588 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2589 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2590 HadError = true; 2591 } 2592 } 2593 2594 /// \brief Parse optional attributes. 2595 /// 2596 /// attributes: 2597 /// attribute attributes 2598 /// attribute 2599 /// 2600 /// attribute: 2601 /// [ identifier ] 2602 /// 2603 /// \param Attrs Will be filled in with the parsed attributes. 2604 /// 2605 /// \returns true if an error occurred, false otherwise. 2606 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2607 bool HadError = false; 2608 2609 while (Tok.is(MMToken::LSquare)) { 2610 // Consume the '['. 2611 SourceLocation LSquareLoc = consumeToken(); 2612 2613 // Check whether we have an attribute name here. 2614 if (!Tok.is(MMToken::Identifier)) { 2615 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2616 skipUntil(MMToken::RSquare); 2617 if (Tok.is(MMToken::RSquare)) 2618 consumeToken(); 2619 HadError = true; 2620 } 2621 2622 // Decode the attribute name. 2623 AttributeKind Attribute 2624 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2625 .Case("exhaustive", AT_exhaustive) 2626 .Case("extern_c", AT_extern_c) 2627 .Case("no_undeclared_includes", AT_no_undeclared_includes) 2628 .Case("system", AT_system) 2629 .Default(AT_unknown); 2630 switch (Attribute) { 2631 case AT_unknown: 2632 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2633 << Tok.getString(); 2634 break; 2635 2636 case AT_system: 2637 Attrs.IsSystem = true; 2638 break; 2639 2640 case AT_extern_c: 2641 Attrs.IsExternC = true; 2642 break; 2643 2644 case AT_exhaustive: 2645 Attrs.IsExhaustive = true; 2646 break; 2647 2648 case AT_no_undeclared_includes: 2649 Attrs.NoUndeclaredIncludes = true; 2650 break; 2651 } 2652 consumeToken(); 2653 2654 // Consume the ']'. 2655 if (!Tok.is(MMToken::RSquare)) { 2656 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2657 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2658 skipUntil(MMToken::RSquare); 2659 HadError = true; 2660 } 2661 2662 if (Tok.is(MMToken::RSquare)) 2663 consumeToken(); 2664 } 2665 2666 return HadError; 2667 } 2668 2669 /// \brief Parse a module map file. 2670 /// 2671 /// module-map-file: 2672 /// module-declaration* 2673 bool ModuleMapParser::parseModuleMapFile() { 2674 do { 2675 switch (Tok.Kind) { 2676 case MMToken::EndOfFile: 2677 return HadError; 2678 2679 case MMToken::ExplicitKeyword: 2680 case MMToken::ExternKeyword: 2681 case MMToken::ModuleKeyword: 2682 case MMToken::FrameworkKeyword: 2683 parseModuleDecl(); 2684 break; 2685 2686 case MMToken::Comma: 2687 case MMToken::ConfigMacros: 2688 case MMToken::Conflict: 2689 case MMToken::Exclaim: 2690 case MMToken::ExcludeKeyword: 2691 case MMToken::ExportKeyword: 2692 case MMToken::HeaderKeyword: 2693 case MMToken::Identifier: 2694 case MMToken::LBrace: 2695 case MMToken::LinkKeyword: 2696 case MMToken::LSquare: 2697 case MMToken::Period: 2698 case MMToken::PrivateKeyword: 2699 case MMToken::RBrace: 2700 case MMToken::RSquare: 2701 case MMToken::RequiresKeyword: 2702 case MMToken::Star: 2703 case MMToken::StringLiteral: 2704 case MMToken::IntegerLiteral: 2705 case MMToken::TextualKeyword: 2706 case MMToken::UmbrellaKeyword: 2707 case MMToken::UseKeyword: 2708 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2709 HadError = true; 2710 consumeToken(); 2711 break; 2712 } 2713 } while (true); 2714 } 2715 2716 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2717 const DirectoryEntry *Dir, FileID ID, 2718 unsigned *Offset, 2719 SourceLocation ExternModuleLoc) { 2720 assert(Target && "Missing target information"); 2721 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2722 = ParsedModuleMap.find(File); 2723 if (Known != ParsedModuleMap.end()) 2724 return Known->second; 2725 2726 // If the module map file wasn't already entered, do so now. 2727 if (ID.isInvalid()) { 2728 auto FileCharacter = 2729 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 2730 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 2731 } 2732 2733 assert(Target && "Missing target information"); 2734 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2735 if (!Buffer) 2736 return ParsedModuleMap[File] = true; 2737 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 2738 "invalid buffer offset"); 2739 2740 // Parse this module map file. 2741 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 2742 Buffer->getBufferStart(), 2743 Buffer->getBufferStart() + (Offset ? *Offset : 0), 2744 Buffer->getBufferEnd()); 2745 SourceLocation Start = L.getSourceLocation(); 2746 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2747 IsSystem); 2748 bool Result = Parser.parseModuleMapFile(); 2749 ParsedModuleMap[File] = Result; 2750 2751 if (Offset) { 2752 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 2753 assert(Loc.first == ID && "stopped in a different file?"); 2754 *Offset = Loc.second; 2755 } 2756 2757 // Notify callbacks that we parsed it. 2758 for (const auto &Cb : Callbacks) 2759 Cb->moduleMapFileRead(Start, *File, IsSystem); 2760 return Result; 2761 } 2762