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 /// \brief Parse a module declaration. 1612 /// 1613 /// module-declaration: 1614 /// 'extern' 'module' module-id string-literal 1615 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1616 /// { module-member* } 1617 /// 1618 /// module-member: 1619 /// requires-declaration 1620 /// header-declaration 1621 /// submodule-declaration 1622 /// export-declaration 1623 /// export-as-declaration 1624 /// link-declaration 1625 /// 1626 /// submodule-declaration: 1627 /// module-declaration 1628 /// inferred-submodule-declaration 1629 void ModuleMapParser::parseModuleDecl() { 1630 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1631 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1632 if (Tok.is(MMToken::ExternKeyword)) { 1633 parseExternModuleDecl(); 1634 return; 1635 } 1636 1637 // Parse 'explicit' or 'framework' keyword, if present. 1638 SourceLocation ExplicitLoc; 1639 bool Explicit = false; 1640 bool Framework = false; 1641 1642 // Parse 'explicit' keyword, if present. 1643 if (Tok.is(MMToken::ExplicitKeyword)) { 1644 ExplicitLoc = consumeToken(); 1645 Explicit = true; 1646 } 1647 1648 // Parse 'framework' keyword, if present. 1649 if (Tok.is(MMToken::FrameworkKeyword)) { 1650 consumeToken(); 1651 Framework = true; 1652 } 1653 1654 // Parse 'module' keyword. 1655 if (!Tok.is(MMToken::ModuleKeyword)) { 1656 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1657 consumeToken(); 1658 HadError = true; 1659 return; 1660 } 1661 consumeToken(); // 'module' keyword 1662 1663 // If we have a wildcard for the module name, this is an inferred submodule. 1664 // Parse it. 1665 if (Tok.is(MMToken::Star)) 1666 return parseInferredModuleDecl(Framework, Explicit); 1667 1668 // Parse the module name. 1669 ModuleId Id; 1670 if (parseModuleId(Id)) { 1671 HadError = true; 1672 return; 1673 } 1674 1675 if (ActiveModule) { 1676 if (Id.size() > 1) { 1677 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1678 << SourceRange(Id.front().second, Id.back().second); 1679 1680 HadError = true; 1681 return; 1682 } 1683 } else if (Id.size() == 1 && Explicit) { 1684 // Top-level modules can't be explicit. 1685 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1686 Explicit = false; 1687 ExplicitLoc = SourceLocation(); 1688 HadError = true; 1689 } 1690 1691 Module *PreviousActiveModule = ActiveModule; 1692 if (Id.size() > 1) { 1693 // This module map defines a submodule. Go find the module of which it 1694 // is a submodule. 1695 ActiveModule = nullptr; 1696 const Module *TopLevelModule = nullptr; 1697 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1698 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1699 if (I == 0) 1700 TopLevelModule = Next; 1701 ActiveModule = Next; 1702 continue; 1703 } 1704 1705 if (ActiveModule) { 1706 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1707 << Id[I].first 1708 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1709 } else { 1710 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1711 } 1712 HadError = true; 1713 return; 1714 } 1715 1716 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1717 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1718 "submodule defined in same file as 'module *' that allowed its " 1719 "top-level module"); 1720 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1721 } 1722 } 1723 1724 StringRef ModuleName = Id.back().first; 1725 SourceLocation ModuleNameLoc = Id.back().second; 1726 1727 // Parse the optional attribute list. 1728 Attributes Attrs; 1729 if (parseOptionalAttributes(Attrs)) 1730 return; 1731 1732 // Parse the opening brace. 1733 if (!Tok.is(MMToken::LBrace)) { 1734 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1735 << ModuleName; 1736 HadError = true; 1737 return; 1738 } 1739 SourceLocation LBraceLoc = consumeToken(); 1740 1741 // Determine whether this (sub)module has already been defined. 1742 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1743 // We might see a (re)definition of a module that we already have a 1744 // definition for in two cases: 1745 // - If we loaded one definition from an AST file and we've just found a 1746 // corresponding definition in a module map file, or 1747 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid(); 1748 // - If we're building a (preprocessed) module and we've just loaded the 1749 // module map file from which it was created. 1750 bool ParsedAsMainInput = 1751 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 1752 Map.LangOpts.CurrentModule == ModuleName && 1753 SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 1754 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 1755 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) { 1756 // Skip the module definition. 1757 skipUntil(MMToken::RBrace); 1758 if (Tok.is(MMToken::RBrace)) 1759 consumeToken(); 1760 else { 1761 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1762 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1763 HadError = true; 1764 } 1765 return; 1766 } 1767 1768 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1769 << ModuleName; 1770 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1771 1772 // Skip the module definition. 1773 skipUntil(MMToken::RBrace); 1774 if (Tok.is(MMToken::RBrace)) 1775 consumeToken(); 1776 1777 HadError = true; 1778 return; 1779 } 1780 1781 // Start defining this module. 1782 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1783 Explicit).first; 1784 ActiveModule->DefinitionLoc = ModuleNameLoc; 1785 if (Attrs.IsSystem || IsSystem) 1786 ActiveModule->IsSystem = true; 1787 if (Attrs.IsExternC) 1788 ActiveModule->IsExternC = true; 1789 if (Attrs.NoUndeclaredIncludes || 1790 (!ActiveModule->Parent && ModuleName == "Darwin")) 1791 ActiveModule->NoUndeclaredIncludes = true; 1792 ActiveModule->Directory = Directory; 1793 1794 if (!ActiveModule->Parent) { 1795 StringRef MapFileName(ModuleMapFile->getName()); 1796 if (MapFileName.endswith("module.private.modulemap") || 1797 MapFileName.endswith("module_private.map")) { 1798 // Adding a top-level module from a private modulemap is likely a 1799 // user error; we check to see if there's another top-level module 1800 // defined in the non-private map in the same dir, and if so emit a 1801 // warning. 1802 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1803 auto const *M = E->getValue(); 1804 if (!M->Parent && 1805 M->Directory == ActiveModule->Directory && 1806 M->Name != ActiveModule->Name) { 1807 Diags.Report(ActiveModule->DefinitionLoc, 1808 diag::warn_mmap_mismatched_top_level_private) 1809 << ActiveModule->Name << M->Name; 1810 // The pattern we're defending against here is typically due to 1811 // a module named FooPrivate which is supposed to be a submodule 1812 // called Foo.Private. Emit a fixit in that case. 1813 auto D = 1814 Diags.Report(ActiveModule->DefinitionLoc, 1815 diag::note_mmap_rename_top_level_private_as_submodule); 1816 D << ActiveModule->Name << M->Name; 1817 StringRef Bad(ActiveModule->Name); 1818 if (Bad.consume_back("Private")) { 1819 SmallString<128> Fixed = Bad; 1820 Fixed.append(".Private"); 1821 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, 1822 Fixed); 1823 } 1824 break; 1825 } 1826 } 1827 } 1828 } 1829 1830 bool Done = false; 1831 do { 1832 switch (Tok.Kind) { 1833 case MMToken::EndOfFile: 1834 case MMToken::RBrace: 1835 Done = true; 1836 break; 1837 1838 case MMToken::ConfigMacros: 1839 parseConfigMacros(); 1840 break; 1841 1842 case MMToken::Conflict: 1843 parseConflict(); 1844 break; 1845 1846 case MMToken::ExplicitKeyword: 1847 case MMToken::ExternKeyword: 1848 case MMToken::FrameworkKeyword: 1849 case MMToken::ModuleKeyword: 1850 parseModuleDecl(); 1851 break; 1852 1853 case MMToken::ExportKeyword: 1854 parseExportDecl(); 1855 break; 1856 1857 case MMToken::ExportAsKeyword: 1858 parseExportAsDecl(); 1859 break; 1860 1861 case MMToken::UseKeyword: 1862 parseUseDecl(); 1863 break; 1864 1865 case MMToken::RequiresKeyword: 1866 parseRequiresDecl(); 1867 break; 1868 1869 case MMToken::TextualKeyword: 1870 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1871 break; 1872 1873 case MMToken::UmbrellaKeyword: { 1874 SourceLocation UmbrellaLoc = consumeToken(); 1875 if (Tok.is(MMToken::HeaderKeyword)) 1876 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1877 else 1878 parseUmbrellaDirDecl(UmbrellaLoc); 1879 break; 1880 } 1881 1882 case MMToken::ExcludeKeyword: 1883 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1884 break; 1885 1886 case MMToken::PrivateKeyword: 1887 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1888 break; 1889 1890 case MMToken::HeaderKeyword: 1891 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1892 break; 1893 1894 case MMToken::LinkKeyword: 1895 parseLinkDecl(); 1896 break; 1897 1898 default: 1899 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1900 consumeToken(); 1901 break; 1902 } 1903 } while (!Done); 1904 1905 if (Tok.is(MMToken::RBrace)) 1906 consumeToken(); 1907 else { 1908 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1909 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1910 HadError = true; 1911 } 1912 1913 // If the active module is a top-level framework, and there are no link 1914 // libraries, automatically link against the framework. 1915 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1916 ActiveModule->LinkLibraries.empty()) { 1917 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1918 } 1919 1920 // If the module meets all requirements but is still unavailable, mark the 1921 // whole tree as unavailable to prevent it from building. 1922 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1923 ActiveModule->Parent) { 1924 ActiveModule->getTopLevelModule()->markUnavailable(); 1925 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1926 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1927 } 1928 1929 // We're done parsing this module. Pop back to the previous module. 1930 ActiveModule = PreviousActiveModule; 1931 } 1932 1933 /// \brief Parse an extern module declaration. 1934 /// 1935 /// extern module-declaration: 1936 /// 'extern' 'module' module-id string-literal 1937 void ModuleMapParser::parseExternModuleDecl() { 1938 assert(Tok.is(MMToken::ExternKeyword)); 1939 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 1940 1941 // Parse 'module' keyword. 1942 if (!Tok.is(MMToken::ModuleKeyword)) { 1943 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1944 consumeToken(); 1945 HadError = true; 1946 return; 1947 } 1948 consumeToken(); // 'module' keyword 1949 1950 // Parse the module name. 1951 ModuleId Id; 1952 if (parseModuleId(Id)) { 1953 HadError = true; 1954 return; 1955 } 1956 1957 // Parse the referenced module map file name. 1958 if (!Tok.is(MMToken::StringLiteral)) { 1959 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1960 HadError = true; 1961 return; 1962 } 1963 std::string FileName = Tok.getString(); 1964 consumeToken(); // filename 1965 1966 StringRef FileNameRef = FileName; 1967 SmallString<128> ModuleMapFileName; 1968 if (llvm::sys::path::is_relative(FileNameRef)) { 1969 ModuleMapFileName += Directory->getName(); 1970 llvm::sys::path::append(ModuleMapFileName, FileName); 1971 FileNameRef = ModuleMapFileName; 1972 } 1973 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1974 Map.parseModuleMapFile( 1975 File, /*IsSystem=*/false, 1976 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 1977 ? Directory 1978 : File->getDir(), 1979 FileID(), nullptr, ExternLoc); 1980 } 1981 1982 /// Whether to add the requirement \p Feature to the module \p M. 1983 /// 1984 /// This preserves backwards compatibility for two hacks in the Darwin system 1985 /// module map files: 1986 /// 1987 /// 1. The use of 'requires excluded' to make headers non-modular, which 1988 /// should really be mapped to 'textual' now that we have this feature. We 1989 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 1990 /// true. Later, this bit will be used to map all the headers inside this 1991 /// module to 'textual'. 1992 /// 1993 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 1994 /// 1995 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 1996 /// was never correct and causes issues now that we check it, so drop it. 1997 static bool shouldAddRequirement(Module *M, StringRef Feature, 1998 bool &IsRequiresExcludedHack) { 1999 if (Feature == "excluded" && 2000 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 2001 M->fullModuleNameIs({"Tcl", "Private"}))) { 2002 IsRequiresExcludedHack = true; 2003 return false; 2004 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 2005 return false; 2006 } 2007 2008 return true; 2009 } 2010 2011 /// \brief Parse a requires declaration. 2012 /// 2013 /// requires-declaration: 2014 /// 'requires' feature-list 2015 /// 2016 /// feature-list: 2017 /// feature ',' feature-list 2018 /// feature 2019 /// 2020 /// feature: 2021 /// '!'[opt] identifier 2022 void ModuleMapParser::parseRequiresDecl() { 2023 assert(Tok.is(MMToken::RequiresKeyword)); 2024 2025 // Parse 'requires' keyword. 2026 consumeToken(); 2027 2028 // Parse the feature-list. 2029 do { 2030 bool RequiredState = true; 2031 if (Tok.is(MMToken::Exclaim)) { 2032 RequiredState = false; 2033 consumeToken(); 2034 } 2035 2036 if (!Tok.is(MMToken::Identifier)) { 2037 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 2038 HadError = true; 2039 return; 2040 } 2041 2042 // Consume the feature name. 2043 std::string Feature = Tok.getString(); 2044 consumeToken(); 2045 2046 bool IsRequiresExcludedHack = false; 2047 bool ShouldAddRequirement = 2048 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2049 2050 if (IsRequiresExcludedHack) 2051 UsesRequiresExcludedHack.insert(ActiveModule); 2052 2053 if (ShouldAddRequirement) { 2054 // Add this feature. 2055 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2056 *Map.Target); 2057 } 2058 2059 if (!Tok.is(MMToken::Comma)) 2060 break; 2061 2062 // Consume the comma. 2063 consumeToken(); 2064 } while (true); 2065 } 2066 2067 /// \brief Parse a header declaration. 2068 /// 2069 /// header-declaration: 2070 /// 'textual'[opt] 'header' string-literal 2071 /// 'private' 'textual'[opt] 'header' string-literal 2072 /// 'exclude' 'header' string-literal 2073 /// 'umbrella' 'header' string-literal 2074 /// 2075 /// FIXME: Support 'private textual header'. 2076 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2077 SourceLocation LeadingLoc) { 2078 // We've already consumed the first token. 2079 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2080 if (LeadingToken == MMToken::PrivateKeyword) { 2081 Role = ModuleMap::PrivateHeader; 2082 // 'private' may optionally be followed by 'textual'. 2083 if (Tok.is(MMToken::TextualKeyword)) { 2084 LeadingToken = Tok.Kind; 2085 consumeToken(); 2086 } 2087 } 2088 2089 if (LeadingToken == MMToken::TextualKeyword) 2090 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2091 2092 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2093 // Mark this header 'textual' (see doc comment for 2094 // Module::UsesRequiresExcludedHack). 2095 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2096 } 2097 2098 if (LeadingToken != MMToken::HeaderKeyword) { 2099 if (!Tok.is(MMToken::HeaderKeyword)) { 2100 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2101 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2102 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2103 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2104 return; 2105 } 2106 consumeToken(); 2107 } 2108 2109 // Parse the header name. 2110 if (!Tok.is(MMToken::StringLiteral)) { 2111 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2112 << "header"; 2113 HadError = true; 2114 return; 2115 } 2116 Module::UnresolvedHeaderDirective Header; 2117 Header.FileName = Tok.getString(); 2118 Header.FileNameLoc = consumeToken(); 2119 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2120 Header.Kind = 2121 (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded 2122 : Map.headerRoleToKind(Role)); 2123 2124 // Check whether we already have an umbrella. 2125 if (Header.IsUmbrella && ActiveModule->Umbrella) { 2126 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2127 << ActiveModule->getFullModuleName(); 2128 HadError = true; 2129 return; 2130 } 2131 2132 // If we were given stat information, parse it so we can skip looking for 2133 // the file. 2134 if (Tok.is(MMToken::LBrace)) { 2135 SourceLocation LBraceLoc = consumeToken(); 2136 2137 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2138 enum Attribute { Size, ModTime, Unknown }; 2139 StringRef Str = Tok.getString(); 2140 SourceLocation Loc = consumeToken(); 2141 switch (llvm::StringSwitch<Attribute>(Str) 2142 .Case("size", Size) 2143 .Case("mtime", ModTime) 2144 .Default(Unknown)) { 2145 case Size: 2146 if (Header.Size) 2147 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2148 if (!Tok.is(MMToken::IntegerLiteral)) { 2149 Diags.Report(Tok.getLocation(), 2150 diag::err_mmap_invalid_header_attribute_value) << Str; 2151 skipUntil(MMToken::RBrace); 2152 break; 2153 } 2154 Header.Size = Tok.getInteger(); 2155 consumeToken(); 2156 break; 2157 2158 case ModTime: 2159 if (Header.ModTime) 2160 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2161 if (!Tok.is(MMToken::IntegerLiteral)) { 2162 Diags.Report(Tok.getLocation(), 2163 diag::err_mmap_invalid_header_attribute_value) << Str; 2164 skipUntil(MMToken::RBrace); 2165 break; 2166 } 2167 Header.ModTime = Tok.getInteger(); 2168 consumeToken(); 2169 break; 2170 2171 case Unknown: 2172 Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2173 skipUntil(MMToken::RBrace); 2174 break; 2175 } 2176 } 2177 2178 if (Tok.is(MMToken::RBrace)) 2179 consumeToken(); 2180 else { 2181 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2182 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2183 HadError = true; 2184 } 2185 } 2186 2187 Map.addUnresolvedHeader(ActiveModule, std::move(Header)); 2188 } 2189 2190 static int compareModuleHeaders(const Module::Header *A, 2191 const Module::Header *B) { 2192 return A->NameAsWritten.compare(B->NameAsWritten); 2193 } 2194 2195 /// \brief Parse an umbrella directory declaration. 2196 /// 2197 /// umbrella-dir-declaration: 2198 /// umbrella string-literal 2199 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2200 // Parse the directory name. 2201 if (!Tok.is(MMToken::StringLiteral)) { 2202 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2203 << "umbrella"; 2204 HadError = true; 2205 return; 2206 } 2207 2208 std::string DirName = Tok.getString(); 2209 SourceLocation DirNameLoc = consumeToken(); 2210 2211 // Check whether we already have an umbrella. 2212 if (ActiveModule->Umbrella) { 2213 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2214 << ActiveModule->getFullModuleName(); 2215 HadError = true; 2216 return; 2217 } 2218 2219 // Look for this file. 2220 const DirectoryEntry *Dir = nullptr; 2221 if (llvm::sys::path::is_absolute(DirName)) 2222 Dir = SourceMgr.getFileManager().getDirectory(DirName); 2223 else { 2224 SmallString<128> PathName; 2225 PathName = Directory->getName(); 2226 llvm::sys::path::append(PathName, DirName); 2227 Dir = SourceMgr.getFileManager().getDirectory(PathName); 2228 } 2229 2230 if (!Dir) { 2231 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2232 << DirName; 2233 return; 2234 } 2235 2236 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2237 // Mark this header 'textual' (see doc comment for 2238 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2239 // directory is relatively expensive, in practice this only applies to the 2240 // uncommonly used Tcl module on Darwin platforms. 2241 std::error_code EC; 2242 SmallVector<Module::Header, 6> Headers; 2243 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem(); 2244 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2245 I != E && !EC; I.increment(EC)) { 2246 if (const FileEntry *FE = 2247 SourceMgr.getFileManager().getFile(I->getName())) { 2248 2249 Module::Header Header = {I->getName(), FE}; 2250 Headers.push_back(std::move(Header)); 2251 } 2252 } 2253 2254 // Sort header paths so that the pcm doesn't depend on iteration order. 2255 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2256 2257 for (auto &Header : Headers) 2258 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2259 return; 2260 } 2261 2262 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 2263 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2264 << OwningModule->getFullModuleName(); 2265 HadError = true; 2266 return; 2267 } 2268 2269 // Record this umbrella directory. 2270 Map.setUmbrellaDir(ActiveModule, Dir, DirName); 2271 } 2272 2273 /// \brief Parse a module export declaration. 2274 /// 2275 /// export-declaration: 2276 /// 'export' wildcard-module-id 2277 /// 2278 /// wildcard-module-id: 2279 /// identifier 2280 /// '*' 2281 /// identifier '.' wildcard-module-id 2282 void ModuleMapParser::parseExportDecl() { 2283 assert(Tok.is(MMToken::ExportKeyword)); 2284 SourceLocation ExportLoc = consumeToken(); 2285 2286 // Parse the module-id with an optional wildcard at the end. 2287 ModuleId ParsedModuleId; 2288 bool Wildcard = false; 2289 do { 2290 // FIXME: Support string-literal module names here. 2291 if (Tok.is(MMToken::Identifier)) { 2292 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 2293 Tok.getLocation())); 2294 consumeToken(); 2295 2296 if (Tok.is(MMToken::Period)) { 2297 consumeToken(); 2298 continue; 2299 } 2300 2301 break; 2302 } 2303 2304 if(Tok.is(MMToken::Star)) { 2305 Wildcard = true; 2306 consumeToken(); 2307 break; 2308 } 2309 2310 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2311 HadError = true; 2312 return; 2313 } while (true); 2314 2315 Module::UnresolvedExportDecl Unresolved = { 2316 ExportLoc, ParsedModuleId, Wildcard 2317 }; 2318 ActiveModule->UnresolvedExports.push_back(Unresolved); 2319 } 2320 2321 /// \brief Parse a module export_as declaration. 2322 /// 2323 /// export-as-declaration: 2324 /// 'export_as' identifier 2325 void ModuleMapParser::parseExportAsDecl() { 2326 assert(Tok.is(MMToken::ExportAsKeyword)); 2327 consumeToken(); 2328 2329 if (!Tok.is(MMToken::Identifier)) { 2330 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2331 HadError = true; 2332 return; 2333 } 2334 2335 if (ActiveModule->Parent) { 2336 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); 2337 consumeToken(); 2338 return; 2339 } 2340 2341 if (!ActiveModule->ExportAsModule.empty()) { 2342 if (ActiveModule->ExportAsModule == Tok.getString()) { 2343 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) 2344 << ActiveModule->Name << Tok.getString(); 2345 } else { 2346 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) 2347 << ActiveModule->Name << ActiveModule->ExportAsModule 2348 << Tok.getString(); 2349 } 2350 } 2351 2352 ActiveModule->ExportAsModule = Tok.getString(); 2353 consumeToken(); 2354 } 2355 2356 /// \brief Parse a module use declaration. 2357 /// 2358 /// use-declaration: 2359 /// 'use' wildcard-module-id 2360 void ModuleMapParser::parseUseDecl() { 2361 assert(Tok.is(MMToken::UseKeyword)); 2362 auto KWLoc = consumeToken(); 2363 // Parse the module-id. 2364 ModuleId ParsedModuleId; 2365 parseModuleId(ParsedModuleId); 2366 2367 if (ActiveModule->Parent) 2368 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2369 else 2370 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2371 } 2372 2373 /// \brief Parse a link declaration. 2374 /// 2375 /// module-declaration: 2376 /// 'link' 'framework'[opt] string-literal 2377 void ModuleMapParser::parseLinkDecl() { 2378 assert(Tok.is(MMToken::LinkKeyword)); 2379 SourceLocation LinkLoc = consumeToken(); 2380 2381 // Parse the optional 'framework' keyword. 2382 bool IsFramework = false; 2383 if (Tok.is(MMToken::FrameworkKeyword)) { 2384 consumeToken(); 2385 IsFramework = true; 2386 } 2387 2388 // Parse the library name 2389 if (!Tok.is(MMToken::StringLiteral)) { 2390 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2391 << IsFramework << SourceRange(LinkLoc); 2392 HadError = true; 2393 return; 2394 } 2395 2396 std::string LibraryName = Tok.getString(); 2397 consumeToken(); 2398 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2399 IsFramework)); 2400 } 2401 2402 /// \brief Parse a configuration macro declaration. 2403 /// 2404 /// module-declaration: 2405 /// 'config_macros' attributes[opt] config-macro-list? 2406 /// 2407 /// config-macro-list: 2408 /// identifier (',' identifier)? 2409 void ModuleMapParser::parseConfigMacros() { 2410 assert(Tok.is(MMToken::ConfigMacros)); 2411 SourceLocation ConfigMacrosLoc = consumeToken(); 2412 2413 // Only top-level modules can have configuration macros. 2414 if (ActiveModule->Parent) { 2415 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2416 } 2417 2418 // Parse the optional attributes. 2419 Attributes Attrs; 2420 if (parseOptionalAttributes(Attrs)) 2421 return; 2422 2423 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2424 ActiveModule->ConfigMacrosExhaustive = true; 2425 } 2426 2427 // If we don't have an identifier, we're done. 2428 // FIXME: Support macros with the same name as a keyword here. 2429 if (!Tok.is(MMToken::Identifier)) 2430 return; 2431 2432 // Consume the first identifier. 2433 if (!ActiveModule->Parent) { 2434 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2435 } 2436 consumeToken(); 2437 2438 do { 2439 // If there's a comma, consume it. 2440 if (!Tok.is(MMToken::Comma)) 2441 break; 2442 consumeToken(); 2443 2444 // We expect to see a macro name here. 2445 // FIXME: Support macros with the same name as a keyword here. 2446 if (!Tok.is(MMToken::Identifier)) { 2447 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2448 break; 2449 } 2450 2451 // Consume the macro name. 2452 if (!ActiveModule->Parent) { 2453 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2454 } 2455 consumeToken(); 2456 } while (true); 2457 } 2458 2459 /// \brief Format a module-id into a string. 2460 static std::string formatModuleId(const ModuleId &Id) { 2461 std::string result; 2462 { 2463 llvm::raw_string_ostream OS(result); 2464 2465 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2466 if (I) 2467 OS << "."; 2468 OS << Id[I].first; 2469 } 2470 } 2471 2472 return result; 2473 } 2474 2475 /// \brief Parse a conflict declaration. 2476 /// 2477 /// module-declaration: 2478 /// 'conflict' module-id ',' string-literal 2479 void ModuleMapParser::parseConflict() { 2480 assert(Tok.is(MMToken::Conflict)); 2481 SourceLocation ConflictLoc = consumeToken(); 2482 Module::UnresolvedConflict Conflict; 2483 2484 // Parse the module-id. 2485 if (parseModuleId(Conflict.Id)) 2486 return; 2487 2488 // Parse the ','. 2489 if (!Tok.is(MMToken::Comma)) { 2490 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2491 << SourceRange(ConflictLoc); 2492 return; 2493 } 2494 consumeToken(); 2495 2496 // Parse the message. 2497 if (!Tok.is(MMToken::StringLiteral)) { 2498 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2499 << formatModuleId(Conflict.Id); 2500 return; 2501 } 2502 Conflict.Message = Tok.getString().str(); 2503 consumeToken(); 2504 2505 // Add this unresolved conflict. 2506 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2507 } 2508 2509 /// \brief Parse an inferred module declaration (wildcard modules). 2510 /// 2511 /// module-declaration: 2512 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2513 /// { inferred-module-member* } 2514 /// 2515 /// inferred-module-member: 2516 /// 'export' '*' 2517 /// 'exclude' identifier 2518 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2519 assert(Tok.is(MMToken::Star)); 2520 SourceLocation StarLoc = consumeToken(); 2521 bool Failed = false; 2522 2523 // Inferred modules must be submodules. 2524 if (!ActiveModule && !Framework) { 2525 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2526 Failed = true; 2527 } 2528 2529 if (ActiveModule) { 2530 // Inferred modules must have umbrella directories. 2531 if (!Failed && ActiveModule->IsAvailable && 2532 !ActiveModule->getUmbrellaDir()) { 2533 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2534 Failed = true; 2535 } 2536 2537 // Check for redefinition of an inferred module. 2538 if (!Failed && ActiveModule->InferSubmodules) { 2539 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2540 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2541 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2542 diag::note_mmap_prev_definition); 2543 Failed = true; 2544 } 2545 2546 // Check for the 'framework' keyword, which is not permitted here. 2547 if (Framework) { 2548 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2549 Framework = false; 2550 } 2551 } else if (Explicit) { 2552 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2553 Explicit = false; 2554 } 2555 2556 // If there were any problems with this inferred submodule, skip its body. 2557 if (Failed) { 2558 if (Tok.is(MMToken::LBrace)) { 2559 consumeToken(); 2560 skipUntil(MMToken::RBrace); 2561 if (Tok.is(MMToken::RBrace)) 2562 consumeToken(); 2563 } 2564 HadError = true; 2565 return; 2566 } 2567 2568 // Parse optional attributes. 2569 Attributes Attrs; 2570 if (parseOptionalAttributes(Attrs)) 2571 return; 2572 2573 if (ActiveModule) { 2574 // Note that we have an inferred submodule. 2575 ActiveModule->InferSubmodules = true; 2576 ActiveModule->InferredSubmoduleLoc = StarLoc; 2577 ActiveModule->InferExplicitSubmodules = Explicit; 2578 } else { 2579 // We'll be inferring framework modules for this directory. 2580 Map.InferredDirectories[Directory].InferModules = true; 2581 Map.InferredDirectories[Directory].Attrs = Attrs; 2582 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2583 // FIXME: Handle the 'framework' keyword. 2584 } 2585 2586 // Parse the opening brace. 2587 if (!Tok.is(MMToken::LBrace)) { 2588 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2589 HadError = true; 2590 return; 2591 } 2592 SourceLocation LBraceLoc = consumeToken(); 2593 2594 // Parse the body of the inferred submodule. 2595 bool Done = false; 2596 do { 2597 switch (Tok.Kind) { 2598 case MMToken::EndOfFile: 2599 case MMToken::RBrace: 2600 Done = true; 2601 break; 2602 2603 case MMToken::ExcludeKeyword: 2604 if (ActiveModule) { 2605 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2606 << (ActiveModule != nullptr); 2607 consumeToken(); 2608 break; 2609 } 2610 2611 consumeToken(); 2612 // FIXME: Support string-literal module names here. 2613 if (!Tok.is(MMToken::Identifier)) { 2614 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2615 break; 2616 } 2617 2618 Map.InferredDirectories[Directory].ExcludedModules 2619 .push_back(Tok.getString()); 2620 consumeToken(); 2621 break; 2622 2623 case MMToken::ExportKeyword: 2624 if (!ActiveModule) { 2625 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2626 << (ActiveModule != nullptr); 2627 consumeToken(); 2628 break; 2629 } 2630 2631 consumeToken(); 2632 if (Tok.is(MMToken::Star)) 2633 ActiveModule->InferExportWildcard = true; 2634 else 2635 Diags.Report(Tok.getLocation(), 2636 diag::err_mmap_expected_export_wildcard); 2637 consumeToken(); 2638 break; 2639 2640 case MMToken::ExplicitKeyword: 2641 case MMToken::ModuleKeyword: 2642 case MMToken::HeaderKeyword: 2643 case MMToken::PrivateKeyword: 2644 case MMToken::UmbrellaKeyword: 2645 default: 2646 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2647 << (ActiveModule != nullptr); 2648 consumeToken(); 2649 break; 2650 } 2651 } while (!Done); 2652 2653 if (Tok.is(MMToken::RBrace)) 2654 consumeToken(); 2655 else { 2656 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2657 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2658 HadError = true; 2659 } 2660 } 2661 2662 /// \brief Parse optional attributes. 2663 /// 2664 /// attributes: 2665 /// attribute attributes 2666 /// attribute 2667 /// 2668 /// attribute: 2669 /// [ identifier ] 2670 /// 2671 /// \param Attrs Will be filled in with the parsed attributes. 2672 /// 2673 /// \returns true if an error occurred, false otherwise. 2674 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2675 bool HadError = false; 2676 2677 while (Tok.is(MMToken::LSquare)) { 2678 // Consume the '['. 2679 SourceLocation LSquareLoc = consumeToken(); 2680 2681 // Check whether we have an attribute name here. 2682 if (!Tok.is(MMToken::Identifier)) { 2683 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2684 skipUntil(MMToken::RSquare); 2685 if (Tok.is(MMToken::RSquare)) 2686 consumeToken(); 2687 HadError = true; 2688 } 2689 2690 // Decode the attribute name. 2691 AttributeKind Attribute 2692 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2693 .Case("exhaustive", AT_exhaustive) 2694 .Case("extern_c", AT_extern_c) 2695 .Case("no_undeclared_includes", AT_no_undeclared_includes) 2696 .Case("system", AT_system) 2697 .Default(AT_unknown); 2698 switch (Attribute) { 2699 case AT_unknown: 2700 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2701 << Tok.getString(); 2702 break; 2703 2704 case AT_system: 2705 Attrs.IsSystem = true; 2706 break; 2707 2708 case AT_extern_c: 2709 Attrs.IsExternC = true; 2710 break; 2711 2712 case AT_exhaustive: 2713 Attrs.IsExhaustive = true; 2714 break; 2715 2716 case AT_no_undeclared_includes: 2717 Attrs.NoUndeclaredIncludes = true; 2718 break; 2719 } 2720 consumeToken(); 2721 2722 // Consume the ']'. 2723 if (!Tok.is(MMToken::RSquare)) { 2724 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2725 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2726 skipUntil(MMToken::RSquare); 2727 HadError = true; 2728 } 2729 2730 if (Tok.is(MMToken::RSquare)) 2731 consumeToken(); 2732 } 2733 2734 return HadError; 2735 } 2736 2737 /// \brief Parse a module map file. 2738 /// 2739 /// module-map-file: 2740 /// module-declaration* 2741 bool ModuleMapParser::parseModuleMapFile() { 2742 do { 2743 switch (Tok.Kind) { 2744 case MMToken::EndOfFile: 2745 return HadError; 2746 2747 case MMToken::ExplicitKeyword: 2748 case MMToken::ExternKeyword: 2749 case MMToken::ModuleKeyword: 2750 case MMToken::FrameworkKeyword: 2751 parseModuleDecl(); 2752 break; 2753 2754 case MMToken::Comma: 2755 case MMToken::ConfigMacros: 2756 case MMToken::Conflict: 2757 case MMToken::Exclaim: 2758 case MMToken::ExcludeKeyword: 2759 case MMToken::ExportKeyword: 2760 case MMToken::ExportAsKeyword: 2761 case MMToken::HeaderKeyword: 2762 case MMToken::Identifier: 2763 case MMToken::LBrace: 2764 case MMToken::LinkKeyword: 2765 case MMToken::LSquare: 2766 case MMToken::Period: 2767 case MMToken::PrivateKeyword: 2768 case MMToken::RBrace: 2769 case MMToken::RSquare: 2770 case MMToken::RequiresKeyword: 2771 case MMToken::Star: 2772 case MMToken::StringLiteral: 2773 case MMToken::IntegerLiteral: 2774 case MMToken::TextualKeyword: 2775 case MMToken::UmbrellaKeyword: 2776 case MMToken::UseKeyword: 2777 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2778 HadError = true; 2779 consumeToken(); 2780 break; 2781 } 2782 } while (true); 2783 } 2784 2785 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2786 const DirectoryEntry *Dir, FileID ID, 2787 unsigned *Offset, 2788 SourceLocation ExternModuleLoc) { 2789 assert(Target && "Missing target information"); 2790 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2791 = ParsedModuleMap.find(File); 2792 if (Known != ParsedModuleMap.end()) 2793 return Known->second; 2794 2795 // If the module map file wasn't already entered, do so now. 2796 if (ID.isInvalid()) { 2797 auto FileCharacter = 2798 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; 2799 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 2800 } 2801 2802 assert(Target && "Missing target information"); 2803 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2804 if (!Buffer) 2805 return ParsedModuleMap[File] = true; 2806 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 2807 "invalid buffer offset"); 2808 2809 // Parse this module map file. 2810 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 2811 Buffer->getBufferStart(), 2812 Buffer->getBufferStart() + (Offset ? *Offset : 0), 2813 Buffer->getBufferEnd()); 2814 SourceLocation Start = L.getSourceLocation(); 2815 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2816 IsSystem); 2817 bool Result = Parser.parseModuleMapFile(); 2818 ParsedModuleMap[File] = Result; 2819 2820 if (Offset) { 2821 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 2822 assert(Loc.first == ID && "stopped in a different file?"); 2823 *Offset = Loc.second; 2824 } 2825 2826 // Notify callbacks that we parsed it. 2827 for (const auto &Cb : Callbacks) 2828 Cb->moduleMapFileRead(Start, *File, IsSystem); 2829 return Result; 2830 } 2831