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