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::createModuleForInterfaceUnit(SourceLocation Loc, 750 StringRef Name) { 751 assert(LangOpts.CurrentModule == Name && "module name mismatch"); 752 assert(!Modules[Name] && "redefining existing module"); 753 754 auto *Result = 755 new Module(Name, Loc, nullptr, /*IsFramework*/ false, 756 /*IsExplicit*/ false, NumCreatedModules++); 757 Result->Kind = Module::ModuleInterfaceUnit; 758 Modules[Name] = SourceModule = Result; 759 760 // Mark the main source file as being within the newly-created module so that 761 // declarations and macros are properly visibility-restricted to it. 762 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); 763 assert(MainFile && "no input file for module interface"); 764 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader)); 765 766 return Result; 767 } 768 769 /// \brief For a framework module, infer the framework against which we 770 /// should link. 771 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 772 FileManager &FileMgr) { 773 assert(Mod->IsFramework && "Can only infer linking for framework modules"); 774 assert(!Mod->isSubFramework() && 775 "Can only infer linking for top-level frameworks"); 776 777 SmallString<128> LibName; 778 LibName += FrameworkDir->getName(); 779 llvm::sys::path::append(LibName, Mod->Name); 780 781 // The library name of a framework has more than one possible extension since 782 // the introduction of the text-based dynamic library format. We need to check 783 // for both before we give up. 784 for (const char *extension : {"", ".tbd"}) { 785 llvm::sys::path::replace_extension(LibName, extension); 786 if (FileMgr.getFile(LibName)) { 787 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 788 /*IsFramework=*/true)); 789 return; 790 } 791 } 792 } 793 794 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, 795 bool IsSystem, Module *Parent) { 796 Attributes Attrs; 797 Attrs.IsSystem = IsSystem; 798 return inferFrameworkModule(FrameworkDir, Attrs, Parent); 799 } 800 801 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, 802 Attributes Attrs, Module *Parent) { 803 // Note: as an egregious but useful hack we use the real path here, because 804 // we might be looking at an embedded framework that symlinks out to a 805 // top-level framework, and we need to infer as if we were naming the 806 // top-level framework. 807 StringRef FrameworkDirName = 808 SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 809 810 // In case this is a case-insensitive filesystem, use the canonical 811 // directory name as the ModuleName, since modules are case-sensitive. 812 // FIXME: we should be able to give a fix-it hint for the correct spelling. 813 SmallString<32> ModuleNameStorage; 814 StringRef ModuleName = sanitizeFilenameAsIdentifier( 815 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage); 816 817 // Check whether we've already found this module. 818 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 819 return Mod; 820 821 FileManager &FileMgr = SourceMgr.getFileManager(); 822 823 // If the framework has a parent path from which we're allowed to infer 824 // a framework module, do so. 825 const FileEntry *ModuleMapFile = nullptr; 826 if (!Parent) { 827 // Determine whether we're allowed to infer a module map. 828 bool canInfer = false; 829 if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 830 // Figure out the parent path. 831 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 832 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 833 // Check whether we have already looked into the parent directory 834 // for a module map. 835 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 836 inferred = InferredDirectories.find(ParentDir); 837 if (inferred == InferredDirectories.end()) { 838 // We haven't looked here before. Load a module map, if there is 839 // one. 840 bool IsFrameworkDir = Parent.endswith(".framework"); 841 if (const FileEntry *ModMapFile = 842 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { 843 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir); 844 inferred = InferredDirectories.find(ParentDir); 845 } 846 847 if (inferred == InferredDirectories.end()) 848 inferred = InferredDirectories.insert( 849 std::make_pair(ParentDir, InferredDirectory())).first; 850 } 851 852 if (inferred->second.InferModules) { 853 // We're allowed to infer for this directory, but make sure it's okay 854 // to infer this particular module. 855 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 856 canInfer = std::find(inferred->second.ExcludedModules.begin(), 857 inferred->second.ExcludedModules.end(), 858 Name) == inferred->second.ExcludedModules.end(); 859 860 Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 861 Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 862 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 863 Attrs.NoUndeclaredIncludes |= 864 inferred->second.Attrs.NoUndeclaredIncludes; 865 ModuleMapFile = inferred->second.ModuleMapFile; 866 } 867 } 868 } 869 870 // If we're not allowed to infer a framework module, don't. 871 if (!canInfer) 872 return nullptr; 873 } else 874 ModuleMapFile = getModuleMapFileForUniquing(Parent); 875 876 877 // Look for an umbrella header. 878 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 879 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 880 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 881 882 // FIXME: If there's no umbrella header, we could probably scan the 883 // framework to load *everything*. But, it's not clear that this is a good 884 // idea. 885 if (!UmbrellaHeader) 886 return nullptr; 887 888 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 889 /*IsFramework=*/true, /*IsExplicit=*/false, 890 NumCreatedModules++); 891 InferredModuleAllowedBy[Result] = ModuleMapFile; 892 Result->IsInferred = true; 893 if (!Parent) { 894 if (LangOpts.CurrentModule == ModuleName) 895 SourceModule = Result; 896 Modules[ModuleName] = Result; 897 } 898 899 Result->IsSystem |= Attrs.IsSystem; 900 Result->IsExternC |= Attrs.IsExternC; 901 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; 902 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes; 903 Result->Directory = FrameworkDir; 904 905 // umbrella header "umbrella-header-name" 906 // 907 // The "Headers/" component of the name is implied because this is 908 // a framework module. 909 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h"); 910 911 // export * 912 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 913 914 // module * { export * } 915 Result->InferSubmodules = true; 916 Result->InferExportWildcard = true; 917 918 // Look for subframeworks. 919 std::error_code EC; 920 SmallString<128> SubframeworksDirName 921 = StringRef(FrameworkDir->getName()); 922 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 923 llvm::sys::path::native(SubframeworksDirName); 924 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); 925 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC), 926 DirEnd; 927 Dir != DirEnd && !EC; Dir.increment(EC)) { 928 if (!StringRef(Dir->getName()).endswith(".framework")) 929 continue; 930 931 if (const DirectoryEntry *SubframeworkDir = 932 FileMgr.getDirectory(Dir->getName())) { 933 // Note: as an egregious but useful hack, we use the real path here and 934 // check whether it is actually a subdirectory of the parent directory. 935 // This will not be the case if the 'subframework' is actually a symlink 936 // out to a top-level framework. 937 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 938 bool FoundParent = false; 939 do { 940 // Get the parent directory name. 941 SubframeworkDirName 942 = llvm::sys::path::parent_path(SubframeworkDirName); 943 if (SubframeworkDirName.empty()) 944 break; 945 946 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 947 FoundParent = true; 948 break; 949 } 950 } while (true); 951 952 if (!FoundParent) 953 continue; 954 955 // FIXME: Do we want to warn about subframeworks without umbrella headers? 956 inferFrameworkModule(SubframeworkDir, Attrs, Result); 957 } 958 } 959 960 // If the module is a top-level framework, automatically link against the 961 // framework. 962 if (!Result->isSubFramework()) { 963 inferFrameworkLink(Result, FrameworkDir, FileMgr); 964 } 965 966 return Result; 967 } 968 969 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, 970 Twine NameAsWritten) { 971 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 972 Mod->Umbrella = UmbrellaHeader; 973 Mod->UmbrellaAsWritten = NameAsWritten.str(); 974 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 975 976 // Notify callbacks that we just added a new header. 977 for (const auto &Cb : Callbacks) 978 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader); 979 } 980 981 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, 982 Twine NameAsWritten) { 983 Mod->Umbrella = UmbrellaDir; 984 Mod->UmbrellaAsWritten = NameAsWritten.str(); 985 UmbrellaDirs[UmbrellaDir] = Mod; 986 } 987 988 void ModuleMap::addUnresolvedHeader(Module *Mod, 989 Module::UnresolvedHeaderDirective Header) { 990 // If there is a builtin counterpart to this file, add it now so it can 991 // wrap the system header. 992 if (resolveAsBuiltinHeader(Mod, Header)) { 993 // If we have both a builtin and system version of the file, the 994 // builtin version may want to inject macros into the system header, so 995 // force the system header to be treated as a textual header in this 996 // case. 997 Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole( 998 headerKindToRole(Header.Kind) | ModuleMap::TextualHeader)); 999 Header.HasBuiltinHeader = true; 1000 } 1001 1002 // If possible, don't stat the header until we need to. This requires the 1003 // user to have provided us with some stat information about the file. 1004 // FIXME: Add support for lazily stat'ing umbrella headers and excluded 1005 // headers. 1006 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella && 1007 Header.Kind != Module::HK_Excluded) { 1008 // We expect more variation in mtime than size, so if we're given both, 1009 // use the mtime as the key. 1010 if (Header.ModTime) 1011 LazyHeadersByModTime[*Header.ModTime].push_back(Mod); 1012 else 1013 LazyHeadersBySize[*Header.Size].push_back(Mod); 1014 Mod->UnresolvedHeaders.push_back(Header); 1015 return; 1016 } 1017 1018 // We don't have stat information or can't defer looking this file up. 1019 // Perform the lookup now. 1020 resolveHeader(Mod, Header); 1021 } 1022 1023 void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const { 1024 auto BySize = LazyHeadersBySize.find(File->getSize()); 1025 if (BySize != LazyHeadersBySize.end()) { 1026 for (auto *M : BySize->second) 1027 resolveHeaderDirectives(M); 1028 LazyHeadersBySize.erase(BySize); 1029 } 1030 1031 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime()); 1032 if (ByModTime != LazyHeadersByModTime.end()) { 1033 for (auto *M : ByModTime->second) 1034 resolveHeaderDirectives(M); 1035 LazyHeadersByModTime.erase(ByModTime); 1036 } 1037 } 1038 1039 void ModuleMap::resolveHeaderDirectives(Module *Mod) const { 1040 for (auto &Header : Mod->UnresolvedHeaders) 1041 // This operation is logically const; we're just changing how we represent 1042 // the header information for this file. 1043 const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header); 1044 Mod->UnresolvedHeaders.clear(); 1045 } 1046 1047 void ModuleMap::addHeader(Module *Mod, Module::Header Header, 1048 ModuleHeaderRole Role, bool Imported) { 1049 KnownHeader KH(Mod, Role); 1050 1051 // Only add each header to the headers list once. 1052 // FIXME: Should we diagnose if a header is listed twice in the 1053 // same module definition? 1054 auto &HeaderList = Headers[Header.Entry]; 1055 for (auto H : HeaderList) 1056 if (H == KH) 1057 return; 1058 1059 HeaderList.push_back(KH); 1060 Mod->Headers[headerRoleToKind(Role)].push_back(Header); 1061 1062 bool isCompilingModuleHeader = 1063 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule; 1064 if (!Imported || isCompilingModuleHeader) { 1065 // When we import HeaderFileInfo, the external source is expected to 1066 // set the isModuleHeader flag itself. 1067 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 1068 isCompilingModuleHeader); 1069 } 1070 1071 // Notify callbacks that we just added a new header. 1072 for (const auto &Cb : Callbacks) 1073 Cb->moduleMapAddHeader(Header.Entry->getName()); 1074 } 1075 1076 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { 1077 // Add this as a known header so we won't implicitly add it to any 1078 // umbrella directory module. 1079 // FIXME: Should we only exclude it from umbrella modules within the 1080 // specified module? 1081 (void) Headers[Header.Entry]; 1082 1083 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); 1084 } 1085 1086 const FileEntry * 1087 ModuleMap::getContainingModuleMapFile(const Module *Module) const { 1088 if (Module->DefinitionLoc.isInvalid()) 1089 return nullptr; 1090 1091 return SourceMgr.getFileEntryForID( 1092 SourceMgr.getFileID(Module->DefinitionLoc)); 1093 } 1094 1095 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 1096 if (M->IsInferred) { 1097 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 1098 return InferredModuleAllowedBy.find(M)->second; 1099 } 1100 return getContainingModuleMapFile(M); 1101 } 1102 1103 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 1104 assert(M->IsInferred && "module not inferred"); 1105 InferredModuleAllowedBy[M] = ModMap; 1106 } 1107 1108 LLVM_DUMP_METHOD void ModuleMap::dump() { 1109 llvm::errs() << "Modules:"; 1110 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 1111 MEnd = Modules.end(); 1112 M != MEnd; ++M) 1113 M->getValue()->print(llvm::errs(), 2); 1114 1115 llvm::errs() << "Headers:"; 1116 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 1117 H != HEnd; ++H) { 1118 llvm::errs() << " \"" << H->first->getName() << "\" -> "; 1119 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 1120 E = H->second.end(); 1121 I != E; ++I) { 1122 if (I != H->second.begin()) 1123 llvm::errs() << ","; 1124 llvm::errs() << I->getModule()->getFullModuleName(); 1125 } 1126 llvm::errs() << "\n"; 1127 } 1128 } 1129 1130 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 1131 auto Unresolved = std::move(Mod->UnresolvedExports); 1132 Mod->UnresolvedExports.clear(); 1133 for (auto &UE : Unresolved) { 1134 Module::ExportDecl Export = resolveExport(Mod, UE, Complain); 1135 if (Export.getPointer() || Export.getInt()) 1136 Mod->Exports.push_back(Export); 1137 else 1138 Mod->UnresolvedExports.push_back(UE); 1139 } 1140 return !Mod->UnresolvedExports.empty(); 1141 } 1142 1143 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 1144 auto Unresolved = std::move(Mod->UnresolvedDirectUses); 1145 Mod->UnresolvedDirectUses.clear(); 1146 for (auto &UDU : Unresolved) { 1147 Module *DirectUse = resolveModuleId(UDU, Mod, Complain); 1148 if (DirectUse) 1149 Mod->DirectUses.push_back(DirectUse); 1150 else 1151 Mod->UnresolvedDirectUses.push_back(UDU); 1152 } 1153 return !Mod->UnresolvedDirectUses.empty(); 1154 } 1155 1156 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 1157 auto Unresolved = std::move(Mod->UnresolvedConflicts); 1158 Mod->UnresolvedConflicts.clear(); 1159 for (auto &UC : Unresolved) { 1160 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) { 1161 Module::Conflict Conflict; 1162 Conflict.Other = OtherMod; 1163 Conflict.Message = UC.Message; 1164 Mod->Conflicts.push_back(Conflict); 1165 } else 1166 Mod->UnresolvedConflicts.push_back(UC); 1167 } 1168 return !Mod->UnresolvedConflicts.empty(); 1169 } 1170 1171 //----------------------------------------------------------------------------// 1172 // Module map file parser 1173 //----------------------------------------------------------------------------// 1174 1175 namespace clang { 1176 /// \brief A token in a module map file. 1177 struct MMToken { 1178 enum TokenKind { 1179 Comma, 1180 ConfigMacros, 1181 Conflict, 1182 EndOfFile, 1183 HeaderKeyword, 1184 Identifier, 1185 Exclaim, 1186 ExcludeKeyword, 1187 ExplicitKeyword, 1188 ExportKeyword, 1189 ExternKeyword, 1190 FrameworkKeyword, 1191 LinkKeyword, 1192 ModuleKeyword, 1193 Period, 1194 PrivateKeyword, 1195 UmbrellaKeyword, 1196 UseKeyword, 1197 RequiresKeyword, 1198 Star, 1199 StringLiteral, 1200 IntegerLiteral, 1201 TextualKeyword, 1202 LBrace, 1203 RBrace, 1204 LSquare, 1205 RSquare 1206 } Kind; 1207 1208 unsigned Location; 1209 unsigned StringLength; 1210 union { 1211 // If Kind != IntegerLiteral. 1212 const char *StringData; 1213 // If Kind == IntegerLiteral. 1214 uint64_t IntegerValue; 1215 }; 1216 1217 void clear() { 1218 Kind = EndOfFile; 1219 Location = 0; 1220 StringLength = 0; 1221 StringData = nullptr; 1222 } 1223 1224 bool is(TokenKind K) const { return Kind == K; } 1225 1226 SourceLocation getLocation() const { 1227 return SourceLocation::getFromRawEncoding(Location); 1228 } 1229 1230 uint64_t getInteger() const { 1231 return Kind == IntegerLiteral ? IntegerValue : 0; 1232 } 1233 1234 StringRef getString() const { 1235 return Kind == IntegerLiteral ? StringRef() 1236 : StringRef(StringData, StringLength); 1237 } 1238 }; 1239 1240 class ModuleMapParser { 1241 Lexer &L; 1242 SourceManager &SourceMgr; 1243 1244 /// \brief Default target information, used only for string literal 1245 /// parsing. 1246 const TargetInfo *Target; 1247 1248 DiagnosticsEngine &Diags; 1249 ModuleMap ⤅ 1250 1251 /// \brief The current module map file. 1252 const FileEntry *ModuleMapFile; 1253 1254 /// \brief The directory that file names in this module map file should 1255 /// be resolved relative to. 1256 const DirectoryEntry *Directory; 1257 1258 /// \brief Whether this module map is in a system header directory. 1259 bool IsSystem; 1260 1261 /// \brief Whether an error occurred. 1262 bool HadError; 1263 1264 /// \brief Stores string data for the various string literals referenced 1265 /// during parsing. 1266 llvm::BumpPtrAllocator StringData; 1267 1268 /// \brief The current token. 1269 MMToken Tok; 1270 1271 /// \brief The active module. 1272 Module *ActiveModule; 1273 1274 /// \brief Whether a module uses the 'requires excluded' hack to mark its 1275 /// contents as 'textual'. 1276 /// 1277 /// On older Darwin SDK versions, 'requires excluded' is used to mark the 1278 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as 1279 /// non-modular headers. For backwards compatibility, we continue to 1280 /// support this idiom for just these modules, and map the headers to 1281 /// 'textual' to match the original intent. 1282 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack; 1283 1284 /// \brief Consume the current token and return its location. 1285 SourceLocation consumeToken(); 1286 1287 /// \brief Skip tokens until we reach the a token with the given kind 1288 /// (or the end of the file). 1289 void skipUntil(MMToken::TokenKind K); 1290 1291 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1292 bool parseModuleId(ModuleId &Id); 1293 void parseModuleDecl(); 1294 void parseExternModuleDecl(); 1295 void parseRequiresDecl(); 1296 void parseHeaderDecl(clang::MMToken::TokenKind, 1297 SourceLocation LeadingLoc); 1298 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1299 void parseExportDecl(); 1300 void parseUseDecl(); 1301 void parseLinkDecl(); 1302 void parseConfigMacros(); 1303 void parseConflict(); 1304 void parseInferredModuleDecl(bool Framework, bool Explicit); 1305 1306 typedef ModuleMap::Attributes Attributes; 1307 bool parseOptionalAttributes(Attributes &Attrs); 1308 1309 public: 1310 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1311 const TargetInfo *Target, 1312 DiagnosticsEngine &Diags, 1313 ModuleMap &Map, 1314 const FileEntry *ModuleMapFile, 1315 const DirectoryEntry *Directory, 1316 bool IsSystem) 1317 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1318 ModuleMapFile(ModuleMapFile), Directory(Directory), 1319 IsSystem(IsSystem), HadError(false), ActiveModule(nullptr) 1320 { 1321 Tok.clear(); 1322 consumeToken(); 1323 } 1324 1325 bool parseModuleMapFile(); 1326 1327 bool terminatedByDirective() { return false; } 1328 SourceLocation getLocation() { return Tok.getLocation(); } 1329 }; 1330 } 1331 1332 SourceLocation ModuleMapParser::consumeToken() { 1333 SourceLocation Result = Tok.getLocation(); 1334 1335 retry: 1336 Tok.clear(); 1337 Token LToken; 1338 L.LexFromRawLexer(LToken); 1339 Tok.Location = LToken.getLocation().getRawEncoding(); 1340 switch (LToken.getKind()) { 1341 case tok::raw_identifier: { 1342 StringRef RI = LToken.getRawIdentifier(); 1343 Tok.StringData = RI.data(); 1344 Tok.StringLength = RI.size(); 1345 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1346 .Case("config_macros", MMToken::ConfigMacros) 1347 .Case("conflict", MMToken::Conflict) 1348 .Case("exclude", MMToken::ExcludeKeyword) 1349 .Case("explicit", MMToken::ExplicitKeyword) 1350 .Case("export", MMToken::ExportKeyword) 1351 .Case("extern", MMToken::ExternKeyword) 1352 .Case("framework", MMToken::FrameworkKeyword) 1353 .Case("header", MMToken::HeaderKeyword) 1354 .Case("link", MMToken::LinkKeyword) 1355 .Case("module", MMToken::ModuleKeyword) 1356 .Case("private", MMToken::PrivateKeyword) 1357 .Case("requires", MMToken::RequiresKeyword) 1358 .Case("textual", MMToken::TextualKeyword) 1359 .Case("umbrella", MMToken::UmbrellaKeyword) 1360 .Case("use", MMToken::UseKeyword) 1361 .Default(MMToken::Identifier); 1362 break; 1363 } 1364 1365 case tok::comma: 1366 Tok.Kind = MMToken::Comma; 1367 break; 1368 1369 case tok::eof: 1370 Tok.Kind = MMToken::EndOfFile; 1371 break; 1372 1373 case tok::l_brace: 1374 Tok.Kind = MMToken::LBrace; 1375 break; 1376 1377 case tok::l_square: 1378 Tok.Kind = MMToken::LSquare; 1379 break; 1380 1381 case tok::period: 1382 Tok.Kind = MMToken::Period; 1383 break; 1384 1385 case tok::r_brace: 1386 Tok.Kind = MMToken::RBrace; 1387 break; 1388 1389 case tok::r_square: 1390 Tok.Kind = MMToken::RSquare; 1391 break; 1392 1393 case tok::star: 1394 Tok.Kind = MMToken::Star; 1395 break; 1396 1397 case tok::exclaim: 1398 Tok.Kind = MMToken::Exclaim; 1399 break; 1400 1401 case tok::string_literal: { 1402 if (LToken.hasUDSuffix()) { 1403 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1404 HadError = true; 1405 goto retry; 1406 } 1407 1408 // Parse the string literal. 1409 LangOptions LangOpts; 1410 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1411 if (StringLiteral.hadError) 1412 goto retry; 1413 1414 // Copy the string literal into our string data allocator. 1415 unsigned Length = StringLiteral.GetStringLength(); 1416 char *Saved = StringData.Allocate<char>(Length + 1); 1417 memcpy(Saved, StringLiteral.GetString().data(), Length); 1418 Saved[Length] = 0; 1419 1420 // Form the token. 1421 Tok.Kind = MMToken::StringLiteral; 1422 Tok.StringData = Saved; 1423 Tok.StringLength = Length; 1424 break; 1425 } 1426 1427 case tok::numeric_constant: { 1428 // We don't support any suffixes or other complications. 1429 SmallString<32> SpellingBuffer; 1430 SpellingBuffer.resize(LToken.getLength() + 1); 1431 const char *Start = SpellingBuffer.data(); 1432 unsigned Length = 1433 Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts()); 1434 uint64_t Value; 1435 if (StringRef(Start, Length).getAsInteger(0, Value)) { 1436 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1437 HadError = true; 1438 goto retry; 1439 } 1440 1441 Tok.Kind = MMToken::IntegerLiteral; 1442 Tok.IntegerValue = Value; 1443 break; 1444 } 1445 1446 case tok::comment: 1447 goto retry; 1448 1449 case tok::hash: 1450 // A module map can be terminated prematurely by 1451 // #pragma clang module contents 1452 // When building the module, we'll treat the rest of the file as the 1453 // contents of the module. 1454 { 1455 auto NextIsIdent = [&](StringRef Str) -> bool { 1456 L.LexFromRawLexer(LToken); 1457 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && 1458 LToken.getRawIdentifier() == Str; 1459 }; 1460 if (NextIsIdent("pragma") && NextIsIdent("clang") && 1461 NextIsIdent("module") && NextIsIdent("contents")) { 1462 Tok.Kind = MMToken::EndOfFile; 1463 break; 1464 } 1465 } 1466 LLVM_FALLTHROUGH; 1467 1468 default: 1469 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); 1470 HadError = true; 1471 goto retry; 1472 } 1473 1474 return Result; 1475 } 1476 1477 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1478 unsigned braceDepth = 0; 1479 unsigned squareDepth = 0; 1480 do { 1481 switch (Tok.Kind) { 1482 case MMToken::EndOfFile: 1483 return; 1484 1485 case MMToken::LBrace: 1486 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1487 return; 1488 1489 ++braceDepth; 1490 break; 1491 1492 case MMToken::LSquare: 1493 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1494 return; 1495 1496 ++squareDepth; 1497 break; 1498 1499 case MMToken::RBrace: 1500 if (braceDepth > 0) 1501 --braceDepth; 1502 else if (Tok.is(K)) 1503 return; 1504 break; 1505 1506 case MMToken::RSquare: 1507 if (squareDepth > 0) 1508 --squareDepth; 1509 else if (Tok.is(K)) 1510 return; 1511 break; 1512 1513 default: 1514 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1515 return; 1516 break; 1517 } 1518 1519 consumeToken(); 1520 } while (true); 1521 } 1522 1523 /// \brief Parse a module-id. 1524 /// 1525 /// module-id: 1526 /// identifier 1527 /// identifier '.' module-id 1528 /// 1529 /// \returns true if an error occurred, false otherwise. 1530 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1531 Id.clear(); 1532 do { 1533 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1534 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1535 consumeToken(); 1536 } else { 1537 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1538 return true; 1539 } 1540 1541 if (!Tok.is(MMToken::Period)) 1542 break; 1543 1544 consumeToken(); 1545 } while (true); 1546 1547 return false; 1548 } 1549 1550 namespace { 1551 /// \brief Enumerates the known attributes. 1552 enum AttributeKind { 1553 /// \brief An unknown attribute. 1554 AT_unknown, 1555 /// \brief The 'system' attribute. 1556 AT_system, 1557 /// \brief The 'extern_c' attribute. 1558 AT_extern_c, 1559 /// \brief The 'exhaustive' attribute. 1560 AT_exhaustive, 1561 /// \brief The 'no_undeclared_includes' attribute. 1562 AT_no_undeclared_includes 1563 }; 1564 } 1565 1566 /// \brief Parse a module declaration. 1567 /// 1568 /// module-declaration: 1569 /// 'extern' 'module' module-id string-literal 1570 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1571 /// { module-member* } 1572 /// 1573 /// module-member: 1574 /// requires-declaration 1575 /// header-declaration 1576 /// submodule-declaration 1577 /// export-declaration 1578 /// link-declaration 1579 /// 1580 /// submodule-declaration: 1581 /// module-declaration 1582 /// inferred-submodule-declaration 1583 void ModuleMapParser::parseModuleDecl() { 1584 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1585 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1586 if (Tok.is(MMToken::ExternKeyword)) { 1587 parseExternModuleDecl(); 1588 return; 1589 } 1590 1591 // Parse 'explicit' or 'framework' keyword, if present. 1592 SourceLocation ExplicitLoc; 1593 bool Explicit = false; 1594 bool Framework = false; 1595 1596 // Parse 'explicit' keyword, if present. 1597 if (Tok.is(MMToken::ExplicitKeyword)) { 1598 ExplicitLoc = consumeToken(); 1599 Explicit = true; 1600 } 1601 1602 // Parse 'framework' keyword, if present. 1603 if (Tok.is(MMToken::FrameworkKeyword)) { 1604 consumeToken(); 1605 Framework = true; 1606 } 1607 1608 // Parse 'module' keyword. 1609 if (!Tok.is(MMToken::ModuleKeyword)) { 1610 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1611 consumeToken(); 1612 HadError = true; 1613 return; 1614 } 1615 consumeToken(); // 'module' keyword 1616 1617 // If we have a wildcard for the module name, this is an inferred submodule. 1618 // Parse it. 1619 if (Tok.is(MMToken::Star)) 1620 return parseInferredModuleDecl(Framework, Explicit); 1621 1622 // Parse the module name. 1623 ModuleId Id; 1624 if (parseModuleId(Id)) { 1625 HadError = true; 1626 return; 1627 } 1628 1629 if (ActiveModule) { 1630 if (Id.size() > 1) { 1631 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1632 << SourceRange(Id.front().second, Id.back().second); 1633 1634 HadError = true; 1635 return; 1636 } 1637 } else if (Id.size() == 1 && Explicit) { 1638 // Top-level modules can't be explicit. 1639 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1640 Explicit = false; 1641 ExplicitLoc = SourceLocation(); 1642 HadError = true; 1643 } 1644 1645 Module *PreviousActiveModule = ActiveModule; 1646 if (Id.size() > 1) { 1647 // This module map defines a submodule. Go find the module of which it 1648 // is a submodule. 1649 ActiveModule = nullptr; 1650 const Module *TopLevelModule = nullptr; 1651 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1652 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1653 if (I == 0) 1654 TopLevelModule = Next; 1655 ActiveModule = Next; 1656 continue; 1657 } 1658 1659 if (ActiveModule) { 1660 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1661 << Id[I].first 1662 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1663 } else { 1664 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1665 } 1666 HadError = true; 1667 return; 1668 } 1669 1670 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1671 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1672 "submodule defined in same file as 'module *' that allowed its " 1673 "top-level module"); 1674 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1675 } 1676 } 1677 1678 StringRef ModuleName = Id.back().first; 1679 SourceLocation ModuleNameLoc = Id.back().second; 1680 1681 // Parse the optional attribute list. 1682 Attributes Attrs; 1683 if (parseOptionalAttributes(Attrs)) 1684 return; 1685 1686 1687 // Parse the opening brace. 1688 if (!Tok.is(MMToken::LBrace)) { 1689 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1690 << ModuleName; 1691 HadError = true; 1692 return; 1693 } 1694 SourceLocation LBraceLoc = consumeToken(); 1695 1696 // Determine whether this (sub)module has already been defined. 1697 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1698 // We might see a (re)definition of a module that we already have a 1699 // definition for in two cases: 1700 // - If we loaded one definition from an AST file and we've just found a 1701 // corresponding definition in a module map file, or 1702 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid(); 1703 // - If we're building a (preprocessed) module and we've just loaded the 1704 // module map file from which it was created. 1705 bool ParsedAsMainInput = 1706 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && 1707 Map.LangOpts.CurrentModule == ModuleName && 1708 SourceMgr.getDecomposedLoc(ModuleNameLoc).first != 1709 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; 1710 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) { 1711 // Skip the module definition. 1712 skipUntil(MMToken::RBrace); 1713 if (Tok.is(MMToken::RBrace)) 1714 consumeToken(); 1715 else { 1716 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1717 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1718 HadError = true; 1719 } 1720 return; 1721 } 1722 1723 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1724 << ModuleName; 1725 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1726 1727 // Skip the module definition. 1728 skipUntil(MMToken::RBrace); 1729 if (Tok.is(MMToken::RBrace)) 1730 consumeToken(); 1731 1732 HadError = true; 1733 return; 1734 } 1735 1736 // Start defining this module. 1737 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1738 Explicit).first; 1739 ActiveModule->DefinitionLoc = ModuleNameLoc; 1740 if (Attrs.IsSystem || IsSystem) 1741 ActiveModule->IsSystem = true; 1742 if (Attrs.IsExternC) 1743 ActiveModule->IsExternC = true; 1744 if (Attrs.NoUndeclaredIncludes || 1745 (!ActiveModule->Parent && ModuleName == "Darwin")) 1746 ActiveModule->NoUndeclaredIncludes = true; 1747 ActiveModule->Directory = Directory; 1748 1749 if (!ActiveModule->Parent) { 1750 StringRef MapFileName(ModuleMapFile->getName()); 1751 if (MapFileName.endswith("module.private.modulemap") || 1752 MapFileName.endswith("module_private.map")) { 1753 // Adding a top-level module from a private modulemap is likely a 1754 // user error; we check to see if there's another top-level module 1755 // defined in the non-private map in the same dir, and if so emit a 1756 // warning. 1757 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { 1758 auto const *M = E->getValue(); 1759 if (!M->Parent && 1760 M->Directory == ActiveModule->Directory && 1761 M->Name != ActiveModule->Name) { 1762 Diags.Report(ActiveModule->DefinitionLoc, 1763 diag::warn_mmap_mismatched_top_level_private) 1764 << ActiveModule->Name << M->Name; 1765 // The pattern we're defending against here is typically due to 1766 // a module named FooPrivate which is supposed to be a submodule 1767 // called Foo.Private. Emit a fixit in that case. 1768 auto D = 1769 Diags.Report(ActiveModule->DefinitionLoc, 1770 diag::note_mmap_rename_top_level_private_as_submodule); 1771 D << ActiveModule->Name << M->Name; 1772 StringRef Bad(ActiveModule->Name); 1773 if (Bad.consume_back("Private")) { 1774 SmallString<128> Fixed = Bad; 1775 Fixed.append(".Private"); 1776 D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, 1777 Fixed); 1778 } 1779 break; 1780 } 1781 } 1782 } 1783 } 1784 1785 bool Done = false; 1786 do { 1787 switch (Tok.Kind) { 1788 case MMToken::EndOfFile: 1789 case MMToken::RBrace: 1790 Done = true; 1791 break; 1792 1793 case MMToken::ConfigMacros: 1794 parseConfigMacros(); 1795 break; 1796 1797 case MMToken::Conflict: 1798 parseConflict(); 1799 break; 1800 1801 case MMToken::ExplicitKeyword: 1802 case MMToken::ExternKeyword: 1803 case MMToken::FrameworkKeyword: 1804 case MMToken::ModuleKeyword: 1805 parseModuleDecl(); 1806 break; 1807 1808 case MMToken::ExportKeyword: 1809 parseExportDecl(); 1810 break; 1811 1812 case MMToken::UseKeyword: 1813 parseUseDecl(); 1814 break; 1815 1816 case MMToken::RequiresKeyword: 1817 parseRequiresDecl(); 1818 break; 1819 1820 case MMToken::TextualKeyword: 1821 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1822 break; 1823 1824 case MMToken::UmbrellaKeyword: { 1825 SourceLocation UmbrellaLoc = consumeToken(); 1826 if (Tok.is(MMToken::HeaderKeyword)) 1827 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1828 else 1829 parseUmbrellaDirDecl(UmbrellaLoc); 1830 break; 1831 } 1832 1833 case MMToken::ExcludeKeyword: 1834 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1835 break; 1836 1837 case MMToken::PrivateKeyword: 1838 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1839 break; 1840 1841 case MMToken::HeaderKeyword: 1842 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1843 break; 1844 1845 case MMToken::LinkKeyword: 1846 parseLinkDecl(); 1847 break; 1848 1849 default: 1850 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1851 consumeToken(); 1852 break; 1853 } 1854 } while (!Done); 1855 1856 if (Tok.is(MMToken::RBrace)) 1857 consumeToken(); 1858 else { 1859 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1860 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1861 HadError = true; 1862 } 1863 1864 // If the active module is a top-level framework, and there are no link 1865 // libraries, automatically link against the framework. 1866 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1867 ActiveModule->LinkLibraries.empty()) { 1868 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1869 } 1870 1871 // If the module meets all requirements but is still unavailable, mark the 1872 // whole tree as unavailable to prevent it from building. 1873 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1874 ActiveModule->Parent) { 1875 ActiveModule->getTopLevelModule()->markUnavailable(); 1876 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1877 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1878 } 1879 1880 // We're done parsing this module. Pop back to the previous module. 1881 ActiveModule = PreviousActiveModule; 1882 } 1883 1884 /// \brief Parse an extern module declaration. 1885 /// 1886 /// extern module-declaration: 1887 /// 'extern' 'module' module-id string-literal 1888 void ModuleMapParser::parseExternModuleDecl() { 1889 assert(Tok.is(MMToken::ExternKeyword)); 1890 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword 1891 1892 // Parse 'module' keyword. 1893 if (!Tok.is(MMToken::ModuleKeyword)) { 1894 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1895 consumeToken(); 1896 HadError = true; 1897 return; 1898 } 1899 consumeToken(); // 'module' keyword 1900 1901 // Parse the module name. 1902 ModuleId Id; 1903 if (parseModuleId(Id)) { 1904 HadError = true; 1905 return; 1906 } 1907 1908 // Parse the referenced module map file name. 1909 if (!Tok.is(MMToken::StringLiteral)) { 1910 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1911 HadError = true; 1912 return; 1913 } 1914 std::string FileName = Tok.getString(); 1915 consumeToken(); // filename 1916 1917 StringRef FileNameRef = FileName; 1918 SmallString<128> ModuleMapFileName; 1919 if (llvm::sys::path::is_relative(FileNameRef)) { 1920 ModuleMapFileName += Directory->getName(); 1921 llvm::sys::path::append(ModuleMapFileName, FileName); 1922 FileNameRef = ModuleMapFileName; 1923 } 1924 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1925 Map.parseModuleMapFile( 1926 File, /*IsSystem=*/false, 1927 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 1928 ? Directory 1929 : File->getDir(), 1930 FileID(), nullptr, ExternLoc); 1931 } 1932 1933 /// Whether to add the requirement \p Feature to the module \p M. 1934 /// 1935 /// This preserves backwards compatibility for two hacks in the Darwin system 1936 /// module map files: 1937 /// 1938 /// 1. The use of 'requires excluded' to make headers non-modular, which 1939 /// should really be mapped to 'textual' now that we have this feature. We 1940 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to 1941 /// true. Later, this bit will be used to map all the headers inside this 1942 /// module to 'textual'. 1943 /// 1944 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private. 1945 /// 1946 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement 1947 /// was never correct and causes issues now that we check it, so drop it. 1948 static bool shouldAddRequirement(Module *M, StringRef Feature, 1949 bool &IsRequiresExcludedHack) { 1950 if (Feature == "excluded" && 1951 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) || 1952 M->fullModuleNameIs({"Tcl", "Private"}))) { 1953 IsRequiresExcludedHack = true; 1954 return false; 1955 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) { 1956 return false; 1957 } 1958 1959 return true; 1960 } 1961 1962 /// \brief Parse a requires declaration. 1963 /// 1964 /// requires-declaration: 1965 /// 'requires' feature-list 1966 /// 1967 /// feature-list: 1968 /// feature ',' feature-list 1969 /// feature 1970 /// 1971 /// feature: 1972 /// '!'[opt] identifier 1973 void ModuleMapParser::parseRequiresDecl() { 1974 assert(Tok.is(MMToken::RequiresKeyword)); 1975 1976 // Parse 'requires' keyword. 1977 consumeToken(); 1978 1979 // Parse the feature-list. 1980 do { 1981 bool RequiredState = true; 1982 if (Tok.is(MMToken::Exclaim)) { 1983 RequiredState = false; 1984 consumeToken(); 1985 } 1986 1987 if (!Tok.is(MMToken::Identifier)) { 1988 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1989 HadError = true; 1990 return; 1991 } 1992 1993 // Consume the feature name. 1994 std::string Feature = Tok.getString(); 1995 consumeToken(); 1996 1997 bool IsRequiresExcludedHack = false; 1998 bool ShouldAddRequirement = 1999 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack); 2000 2001 if (IsRequiresExcludedHack) 2002 UsesRequiresExcludedHack.insert(ActiveModule); 2003 2004 if (ShouldAddRequirement) { 2005 // Add this feature. 2006 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts, 2007 *Map.Target); 2008 } 2009 2010 if (!Tok.is(MMToken::Comma)) 2011 break; 2012 2013 // Consume the comma. 2014 consumeToken(); 2015 } while (true); 2016 } 2017 2018 /// \brief Parse a header declaration. 2019 /// 2020 /// header-declaration: 2021 /// 'textual'[opt] 'header' string-literal 2022 /// 'private' 'textual'[opt] 'header' string-literal 2023 /// 'exclude' 'header' string-literal 2024 /// 'umbrella' 'header' string-literal 2025 /// 2026 /// FIXME: Support 'private textual header'. 2027 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 2028 SourceLocation LeadingLoc) { 2029 // We've already consumed the first token. 2030 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 2031 if (LeadingToken == MMToken::PrivateKeyword) { 2032 Role = ModuleMap::PrivateHeader; 2033 // 'private' may optionally be followed by 'textual'. 2034 if (Tok.is(MMToken::TextualKeyword)) { 2035 LeadingToken = Tok.Kind; 2036 consumeToken(); 2037 } 2038 } 2039 2040 if (LeadingToken == MMToken::TextualKeyword) 2041 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2042 2043 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2044 // Mark this header 'textual' (see doc comment for 2045 // Module::UsesRequiresExcludedHack). 2046 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 2047 } 2048 2049 if (LeadingToken != MMToken::HeaderKeyword) { 2050 if (!Tok.is(MMToken::HeaderKeyword)) { 2051 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2052 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 2053 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 2054 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 2055 return; 2056 } 2057 consumeToken(); 2058 } 2059 2060 // Parse the header name. 2061 if (!Tok.is(MMToken::StringLiteral)) { 2062 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2063 << "header"; 2064 HadError = true; 2065 return; 2066 } 2067 Module::UnresolvedHeaderDirective Header; 2068 Header.FileName = Tok.getString(); 2069 Header.FileNameLoc = consumeToken(); 2070 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 2071 Header.Kind = 2072 (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded 2073 : Map.headerRoleToKind(Role)); 2074 2075 // Check whether we already have an umbrella. 2076 if (Header.IsUmbrella && ActiveModule->Umbrella) { 2077 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 2078 << ActiveModule->getFullModuleName(); 2079 HadError = true; 2080 return; 2081 } 2082 2083 // If we were given stat information, parse it so we can skip looking for 2084 // the file. 2085 if (Tok.is(MMToken::LBrace)) { 2086 SourceLocation LBraceLoc = consumeToken(); 2087 2088 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { 2089 enum Attribute { Size, ModTime, Unknown }; 2090 StringRef Str = Tok.getString(); 2091 SourceLocation Loc = consumeToken(); 2092 switch (llvm::StringSwitch<Attribute>(Str) 2093 .Case("size", Size) 2094 .Case("mtime", ModTime) 2095 .Default(Unknown)) { 2096 case Size: 2097 if (Header.Size) 2098 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2099 if (!Tok.is(MMToken::IntegerLiteral)) { 2100 Diags.Report(Tok.getLocation(), 2101 diag::err_mmap_invalid_header_attribute_value) << Str; 2102 skipUntil(MMToken::RBrace); 2103 break; 2104 } 2105 Header.Size = Tok.getInteger(); 2106 consumeToken(); 2107 break; 2108 2109 case ModTime: 2110 if (Header.ModTime) 2111 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; 2112 if (!Tok.is(MMToken::IntegerLiteral)) { 2113 Diags.Report(Tok.getLocation(), 2114 diag::err_mmap_invalid_header_attribute_value) << Str; 2115 skipUntil(MMToken::RBrace); 2116 break; 2117 } 2118 Header.ModTime = Tok.getInteger(); 2119 consumeToken(); 2120 break; 2121 2122 case Unknown: 2123 Diags.Report(Loc, diag::err_mmap_expected_header_attribute); 2124 skipUntil(MMToken::RBrace); 2125 break; 2126 } 2127 } 2128 2129 if (Tok.is(MMToken::RBrace)) 2130 consumeToken(); 2131 else { 2132 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2133 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2134 HadError = true; 2135 } 2136 } 2137 2138 Map.addUnresolvedHeader(ActiveModule, std::move(Header)); 2139 } 2140 2141 static int compareModuleHeaders(const Module::Header *A, 2142 const Module::Header *B) { 2143 return A->NameAsWritten.compare(B->NameAsWritten); 2144 } 2145 2146 /// \brief Parse an umbrella directory declaration. 2147 /// 2148 /// umbrella-dir-declaration: 2149 /// umbrella string-literal 2150 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 2151 // Parse the directory name. 2152 if (!Tok.is(MMToken::StringLiteral)) { 2153 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 2154 << "umbrella"; 2155 HadError = true; 2156 return; 2157 } 2158 2159 std::string DirName = Tok.getString(); 2160 SourceLocation DirNameLoc = consumeToken(); 2161 2162 // Check whether we already have an umbrella. 2163 if (ActiveModule->Umbrella) { 2164 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 2165 << ActiveModule->getFullModuleName(); 2166 HadError = true; 2167 return; 2168 } 2169 2170 // Look for this file. 2171 const DirectoryEntry *Dir = nullptr; 2172 if (llvm::sys::path::is_absolute(DirName)) 2173 Dir = SourceMgr.getFileManager().getDirectory(DirName); 2174 else { 2175 SmallString<128> PathName; 2176 PathName = Directory->getName(); 2177 llvm::sys::path::append(PathName, DirName); 2178 Dir = SourceMgr.getFileManager().getDirectory(PathName); 2179 } 2180 2181 if (!Dir) { 2182 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) 2183 << DirName; 2184 return; 2185 } 2186 2187 if (UsesRequiresExcludedHack.count(ActiveModule)) { 2188 // Mark this header 'textual' (see doc comment for 2189 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the 2190 // directory is relatively expensive, in practice this only applies to the 2191 // uncommonly used Tcl module on Darwin platforms. 2192 std::error_code EC; 2193 SmallVector<Module::Header, 6> Headers; 2194 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem(); 2195 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E; 2196 I != E && !EC; I.increment(EC)) { 2197 if (const FileEntry *FE = 2198 SourceMgr.getFileManager().getFile(I->getName())) { 2199 2200 Module::Header Header = {I->getName(), FE}; 2201 Headers.push_back(std::move(Header)); 2202 } 2203 } 2204 2205 // Sort header paths so that the pcm doesn't depend on iteration order. 2206 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders); 2207 2208 for (auto &Header : Headers) 2209 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader); 2210 return; 2211 } 2212 2213 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 2214 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 2215 << OwningModule->getFullModuleName(); 2216 HadError = true; 2217 return; 2218 } 2219 2220 // Record this umbrella directory. 2221 Map.setUmbrellaDir(ActiveModule, Dir, DirName); 2222 } 2223 2224 /// \brief Parse a module export declaration. 2225 /// 2226 /// export-declaration: 2227 /// 'export' wildcard-module-id 2228 /// 2229 /// wildcard-module-id: 2230 /// identifier 2231 /// '*' 2232 /// identifier '.' wildcard-module-id 2233 void ModuleMapParser::parseExportDecl() { 2234 assert(Tok.is(MMToken::ExportKeyword)); 2235 SourceLocation ExportLoc = consumeToken(); 2236 2237 // Parse the module-id with an optional wildcard at the end. 2238 ModuleId ParsedModuleId; 2239 bool Wildcard = false; 2240 do { 2241 // FIXME: Support string-literal module names here. 2242 if (Tok.is(MMToken::Identifier)) { 2243 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 2244 Tok.getLocation())); 2245 consumeToken(); 2246 2247 if (Tok.is(MMToken::Period)) { 2248 consumeToken(); 2249 continue; 2250 } 2251 2252 break; 2253 } 2254 2255 if(Tok.is(MMToken::Star)) { 2256 Wildcard = true; 2257 consumeToken(); 2258 break; 2259 } 2260 2261 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 2262 HadError = true; 2263 return; 2264 } while (true); 2265 2266 Module::UnresolvedExportDecl Unresolved = { 2267 ExportLoc, ParsedModuleId, Wildcard 2268 }; 2269 ActiveModule->UnresolvedExports.push_back(Unresolved); 2270 } 2271 2272 /// \brief Parse a module use declaration. 2273 /// 2274 /// use-declaration: 2275 /// 'use' wildcard-module-id 2276 void ModuleMapParser::parseUseDecl() { 2277 assert(Tok.is(MMToken::UseKeyword)); 2278 auto KWLoc = consumeToken(); 2279 // Parse the module-id. 2280 ModuleId ParsedModuleId; 2281 parseModuleId(ParsedModuleId); 2282 2283 if (ActiveModule->Parent) 2284 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); 2285 else 2286 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 2287 } 2288 2289 /// \brief Parse a link declaration. 2290 /// 2291 /// module-declaration: 2292 /// 'link' 'framework'[opt] string-literal 2293 void ModuleMapParser::parseLinkDecl() { 2294 assert(Tok.is(MMToken::LinkKeyword)); 2295 SourceLocation LinkLoc = consumeToken(); 2296 2297 // Parse the optional 'framework' keyword. 2298 bool IsFramework = false; 2299 if (Tok.is(MMToken::FrameworkKeyword)) { 2300 consumeToken(); 2301 IsFramework = true; 2302 } 2303 2304 // Parse the library name 2305 if (!Tok.is(MMToken::StringLiteral)) { 2306 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 2307 << IsFramework << SourceRange(LinkLoc); 2308 HadError = true; 2309 return; 2310 } 2311 2312 std::string LibraryName = Tok.getString(); 2313 consumeToken(); 2314 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 2315 IsFramework)); 2316 } 2317 2318 /// \brief Parse a configuration macro declaration. 2319 /// 2320 /// module-declaration: 2321 /// 'config_macros' attributes[opt] config-macro-list? 2322 /// 2323 /// config-macro-list: 2324 /// identifier (',' identifier)? 2325 void ModuleMapParser::parseConfigMacros() { 2326 assert(Tok.is(MMToken::ConfigMacros)); 2327 SourceLocation ConfigMacrosLoc = consumeToken(); 2328 2329 // Only top-level modules can have configuration macros. 2330 if (ActiveModule->Parent) { 2331 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 2332 } 2333 2334 // Parse the optional attributes. 2335 Attributes Attrs; 2336 if (parseOptionalAttributes(Attrs)) 2337 return; 2338 2339 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 2340 ActiveModule->ConfigMacrosExhaustive = true; 2341 } 2342 2343 // If we don't have an identifier, we're done. 2344 // FIXME: Support macros with the same name as a keyword here. 2345 if (!Tok.is(MMToken::Identifier)) 2346 return; 2347 2348 // Consume the first identifier. 2349 if (!ActiveModule->Parent) { 2350 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2351 } 2352 consumeToken(); 2353 2354 do { 2355 // If there's a comma, consume it. 2356 if (!Tok.is(MMToken::Comma)) 2357 break; 2358 consumeToken(); 2359 2360 // We expect to see a macro name here. 2361 // FIXME: Support macros with the same name as a keyword here. 2362 if (!Tok.is(MMToken::Identifier)) { 2363 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2364 break; 2365 } 2366 2367 // Consume the macro name. 2368 if (!ActiveModule->Parent) { 2369 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2370 } 2371 consumeToken(); 2372 } while (true); 2373 } 2374 2375 /// \brief Format a module-id into a string. 2376 static std::string formatModuleId(const ModuleId &Id) { 2377 std::string result; 2378 { 2379 llvm::raw_string_ostream OS(result); 2380 2381 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2382 if (I) 2383 OS << "."; 2384 OS << Id[I].first; 2385 } 2386 } 2387 2388 return result; 2389 } 2390 2391 /// \brief Parse a conflict declaration. 2392 /// 2393 /// module-declaration: 2394 /// 'conflict' module-id ',' string-literal 2395 void ModuleMapParser::parseConflict() { 2396 assert(Tok.is(MMToken::Conflict)); 2397 SourceLocation ConflictLoc = consumeToken(); 2398 Module::UnresolvedConflict Conflict; 2399 2400 // Parse the module-id. 2401 if (parseModuleId(Conflict.Id)) 2402 return; 2403 2404 // Parse the ','. 2405 if (!Tok.is(MMToken::Comma)) { 2406 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2407 << SourceRange(ConflictLoc); 2408 return; 2409 } 2410 consumeToken(); 2411 2412 // Parse the message. 2413 if (!Tok.is(MMToken::StringLiteral)) { 2414 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2415 << formatModuleId(Conflict.Id); 2416 return; 2417 } 2418 Conflict.Message = Tok.getString().str(); 2419 consumeToken(); 2420 2421 // Add this unresolved conflict. 2422 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2423 } 2424 2425 /// \brief Parse an inferred module declaration (wildcard modules). 2426 /// 2427 /// module-declaration: 2428 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2429 /// { inferred-module-member* } 2430 /// 2431 /// inferred-module-member: 2432 /// 'export' '*' 2433 /// 'exclude' identifier 2434 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2435 assert(Tok.is(MMToken::Star)); 2436 SourceLocation StarLoc = consumeToken(); 2437 bool Failed = false; 2438 2439 // Inferred modules must be submodules. 2440 if (!ActiveModule && !Framework) { 2441 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2442 Failed = true; 2443 } 2444 2445 if (ActiveModule) { 2446 // Inferred modules must have umbrella directories. 2447 if (!Failed && ActiveModule->IsAvailable && 2448 !ActiveModule->getUmbrellaDir()) { 2449 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2450 Failed = true; 2451 } 2452 2453 // Check for redefinition of an inferred module. 2454 if (!Failed && ActiveModule->InferSubmodules) { 2455 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2456 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2457 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2458 diag::note_mmap_prev_definition); 2459 Failed = true; 2460 } 2461 2462 // Check for the 'framework' keyword, which is not permitted here. 2463 if (Framework) { 2464 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2465 Framework = false; 2466 } 2467 } else if (Explicit) { 2468 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2469 Explicit = false; 2470 } 2471 2472 // If there were any problems with this inferred submodule, skip its body. 2473 if (Failed) { 2474 if (Tok.is(MMToken::LBrace)) { 2475 consumeToken(); 2476 skipUntil(MMToken::RBrace); 2477 if (Tok.is(MMToken::RBrace)) 2478 consumeToken(); 2479 } 2480 HadError = true; 2481 return; 2482 } 2483 2484 // Parse optional attributes. 2485 Attributes Attrs; 2486 if (parseOptionalAttributes(Attrs)) 2487 return; 2488 2489 if (ActiveModule) { 2490 // Note that we have an inferred submodule. 2491 ActiveModule->InferSubmodules = true; 2492 ActiveModule->InferredSubmoduleLoc = StarLoc; 2493 ActiveModule->InferExplicitSubmodules = Explicit; 2494 } else { 2495 // We'll be inferring framework modules for this directory. 2496 Map.InferredDirectories[Directory].InferModules = true; 2497 Map.InferredDirectories[Directory].Attrs = Attrs; 2498 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2499 // FIXME: Handle the 'framework' keyword. 2500 } 2501 2502 // Parse the opening brace. 2503 if (!Tok.is(MMToken::LBrace)) { 2504 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2505 HadError = true; 2506 return; 2507 } 2508 SourceLocation LBraceLoc = consumeToken(); 2509 2510 // Parse the body of the inferred submodule. 2511 bool Done = false; 2512 do { 2513 switch (Tok.Kind) { 2514 case MMToken::EndOfFile: 2515 case MMToken::RBrace: 2516 Done = true; 2517 break; 2518 2519 case MMToken::ExcludeKeyword: { 2520 if (ActiveModule) { 2521 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2522 << (ActiveModule != nullptr); 2523 consumeToken(); 2524 break; 2525 } 2526 2527 consumeToken(); 2528 // FIXME: Support string-literal module names here. 2529 if (!Tok.is(MMToken::Identifier)) { 2530 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2531 break; 2532 } 2533 2534 Map.InferredDirectories[Directory].ExcludedModules 2535 .push_back(Tok.getString()); 2536 consumeToken(); 2537 break; 2538 } 2539 2540 case MMToken::ExportKeyword: 2541 if (!ActiveModule) { 2542 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2543 << (ActiveModule != nullptr); 2544 consumeToken(); 2545 break; 2546 } 2547 2548 consumeToken(); 2549 if (Tok.is(MMToken::Star)) 2550 ActiveModule->InferExportWildcard = true; 2551 else 2552 Diags.Report(Tok.getLocation(), 2553 diag::err_mmap_expected_export_wildcard); 2554 consumeToken(); 2555 break; 2556 2557 case MMToken::ExplicitKeyword: 2558 case MMToken::ModuleKeyword: 2559 case MMToken::HeaderKeyword: 2560 case MMToken::PrivateKeyword: 2561 case MMToken::UmbrellaKeyword: 2562 default: 2563 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2564 << (ActiveModule != nullptr); 2565 consumeToken(); 2566 break; 2567 } 2568 } while (!Done); 2569 2570 if (Tok.is(MMToken::RBrace)) 2571 consumeToken(); 2572 else { 2573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2574 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2575 HadError = true; 2576 } 2577 } 2578 2579 /// \brief Parse optional attributes. 2580 /// 2581 /// attributes: 2582 /// attribute attributes 2583 /// attribute 2584 /// 2585 /// attribute: 2586 /// [ identifier ] 2587 /// 2588 /// \param Attrs Will be filled in with the parsed attributes. 2589 /// 2590 /// \returns true if an error occurred, false otherwise. 2591 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2592 bool HadError = false; 2593 2594 while (Tok.is(MMToken::LSquare)) { 2595 // Consume the '['. 2596 SourceLocation LSquareLoc = consumeToken(); 2597 2598 // Check whether we have an attribute name here. 2599 if (!Tok.is(MMToken::Identifier)) { 2600 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2601 skipUntil(MMToken::RSquare); 2602 if (Tok.is(MMToken::RSquare)) 2603 consumeToken(); 2604 HadError = true; 2605 } 2606 2607 // Decode the attribute name. 2608 AttributeKind Attribute 2609 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2610 .Case("exhaustive", AT_exhaustive) 2611 .Case("extern_c", AT_extern_c) 2612 .Case("no_undeclared_includes", AT_no_undeclared_includes) 2613 .Case("system", AT_system) 2614 .Default(AT_unknown); 2615 switch (Attribute) { 2616 case AT_unknown: 2617 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2618 << Tok.getString(); 2619 break; 2620 2621 case AT_system: 2622 Attrs.IsSystem = true; 2623 break; 2624 2625 case AT_extern_c: 2626 Attrs.IsExternC = true; 2627 break; 2628 2629 case AT_exhaustive: 2630 Attrs.IsExhaustive = true; 2631 break; 2632 2633 case AT_no_undeclared_includes: 2634 Attrs.NoUndeclaredIncludes = true; 2635 break; 2636 } 2637 consumeToken(); 2638 2639 // Consume the ']'. 2640 if (!Tok.is(MMToken::RSquare)) { 2641 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2642 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2643 skipUntil(MMToken::RSquare); 2644 HadError = true; 2645 } 2646 2647 if (Tok.is(MMToken::RSquare)) 2648 consumeToken(); 2649 } 2650 2651 return HadError; 2652 } 2653 2654 /// \brief Parse a module map file. 2655 /// 2656 /// module-map-file: 2657 /// module-declaration* 2658 bool ModuleMapParser::parseModuleMapFile() { 2659 do { 2660 switch (Tok.Kind) { 2661 case MMToken::EndOfFile: 2662 return HadError; 2663 2664 case MMToken::ExplicitKeyword: 2665 case MMToken::ExternKeyword: 2666 case MMToken::ModuleKeyword: 2667 case MMToken::FrameworkKeyword: 2668 parseModuleDecl(); 2669 break; 2670 2671 case MMToken::Comma: 2672 case MMToken::ConfigMacros: 2673 case MMToken::Conflict: 2674 case MMToken::Exclaim: 2675 case MMToken::ExcludeKeyword: 2676 case MMToken::ExportKeyword: 2677 case MMToken::HeaderKeyword: 2678 case MMToken::Identifier: 2679 case MMToken::LBrace: 2680 case MMToken::LinkKeyword: 2681 case MMToken::LSquare: 2682 case MMToken::Period: 2683 case MMToken::PrivateKeyword: 2684 case MMToken::RBrace: 2685 case MMToken::RSquare: 2686 case MMToken::RequiresKeyword: 2687 case MMToken::Star: 2688 case MMToken::StringLiteral: 2689 case MMToken::IntegerLiteral: 2690 case MMToken::TextualKeyword: 2691 case MMToken::UmbrellaKeyword: 2692 case MMToken::UseKeyword: 2693 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2694 HadError = true; 2695 consumeToken(); 2696 break; 2697 } 2698 } while (true); 2699 } 2700 2701 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2702 const DirectoryEntry *Dir, FileID ID, 2703 unsigned *Offset, 2704 SourceLocation ExternModuleLoc) { 2705 assert(Target && "Missing target information"); 2706 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2707 = ParsedModuleMap.find(File); 2708 if (Known != ParsedModuleMap.end()) 2709 return Known->second; 2710 2711 // If the module map file wasn't already entered, do so now. 2712 if (ID.isInvalid()) { 2713 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2714 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); 2715 } 2716 2717 assert(Target && "Missing target information"); 2718 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2719 if (!Buffer) 2720 return ParsedModuleMap[File] = true; 2721 assert((!Offset || *Offset <= Buffer->getBufferSize()) && 2722 "invalid buffer offset"); 2723 2724 // Parse this module map file. 2725 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, 2726 Buffer->getBufferStart(), 2727 Buffer->getBufferStart() + (Offset ? *Offset : 0), 2728 Buffer->getBufferEnd()); 2729 SourceLocation Start = L.getSourceLocation(); 2730 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2731 IsSystem); 2732 bool Result = Parser.parseModuleMapFile(); 2733 ParsedModuleMap[File] = Result; 2734 2735 if (Offset) { 2736 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); 2737 assert(Loc.first == ID && "stopped in a different file?"); 2738 *Offset = Loc.second; 2739 } 2740 2741 // Notify callbacks that we parsed it. 2742 for (const auto &Cb : Callbacks) 2743 Cb->moduleMapFileRead(Start, *File, IsSystem); 2744 return Result; 2745 } 2746