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