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::ExportDecl 40 ModuleMap::resolveExport(Module *Mod, 41 const Module::UnresolvedExportDecl &Unresolved, 42 bool Complain) const { 43 // We may have just a wildcard. 44 if (Unresolved.Id.empty()) { 45 assert(Unresolved.Wildcard && "Invalid unresolved export"); 46 return Module::ExportDecl(nullptr, true); 47 } 48 49 // Resolve the module-id. 50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); 51 if (!Context) 52 return Module::ExportDecl(); 53 54 return Module::ExportDecl(Context, Unresolved.Wildcard); 55 } 56 57 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, 58 bool Complain) const { 59 // Find the starting module. 60 Module *Context = lookupModuleUnqualified(Id[0].first, Mod); 61 if (!Context) { 62 if (Complain) 63 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) 64 << Id[0].first << Mod->getFullModuleName(); 65 66 return nullptr; 67 } 68 69 // Dig into the module path. 70 for (unsigned I = 1, N = Id.size(); I != N; ++I) { 71 Module *Sub = lookupModuleQualified(Id[I].first, Context); 72 if (!Sub) { 73 if (Complain) 74 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 75 << Id[I].first << Context->getFullModuleName() 76 << SourceRange(Id[0].second, Id[I-1].second); 77 78 return nullptr; 79 } 80 81 Context = Sub; 82 } 83 84 return Context; 85 } 86 87 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, 88 const LangOptions &LangOpts, const TargetInfo *Target, 89 HeaderSearch &HeaderInfo) 90 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), 91 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), 92 CompilingModule(nullptr), SourceModule(nullptr) { 93 MMapLangOpts.LineComment = true; 94 } 95 96 ModuleMap::~ModuleMap() { 97 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 98 IEnd = Modules.end(); 99 I != IEnd; ++I) { 100 delete I->getValue(); 101 } 102 } 103 104 void ModuleMap::setTarget(const TargetInfo &Target) { 105 assert((!this->Target || this->Target == &Target) && 106 "Improper target override"); 107 this->Target = &Target; 108 } 109 110 /// \brief "Sanitize" a filename so that it can be used as an identifier. 111 static StringRef sanitizeFilenameAsIdentifier(StringRef Name, 112 SmallVectorImpl<char> &Buffer) { 113 if (Name.empty()) 114 return Name; 115 116 if (!isValidIdentifier(Name)) { 117 // If we don't already have something with the form of an identifier, 118 // create a buffer with the sanitized name. 119 Buffer.clear(); 120 if (isDigit(Name[0])) 121 Buffer.push_back('_'); 122 Buffer.reserve(Buffer.size() + Name.size()); 123 for (unsigned I = 0, N = Name.size(); I != N; ++I) { 124 if (isIdentifierBody(Name[I])) 125 Buffer.push_back(Name[I]); 126 else 127 Buffer.push_back('_'); 128 } 129 130 Name = StringRef(Buffer.data(), Buffer.size()); 131 } 132 133 while (llvm::StringSwitch<bool>(Name) 134 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true) 135 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true) 136 #include "clang/Basic/TokenKinds.def" 137 .Default(false)) { 138 if (Name.data() != Buffer.data()) 139 Buffer.append(Name.begin(), Name.end()); 140 Buffer.push_back('_'); 141 Name = StringRef(Buffer.data(), Buffer.size()); 142 } 143 144 return Name; 145 } 146 147 /// \brief Determine whether the given file name is the name of a builtin 148 /// header, supplied by Clang to replace, override, or augment existing system 149 /// headers. 150 static bool isBuiltinHeader(StringRef FileName) { 151 return llvm::StringSwitch<bool>(FileName) 152 .Case("float.h", true) 153 .Case("iso646.h", true) 154 .Case("limits.h", true) 155 .Case("stdalign.h", true) 156 .Case("stdarg.h", true) 157 .Case("stdbool.h", true) 158 .Case("stddef.h", true) 159 .Case("stdint.h", true) 160 .Case("tgmath.h", true) 161 .Case("unwind.h", true) 162 .Default(false); 163 } 164 165 ModuleMap::HeadersMap::iterator 166 ModuleMap::findKnownHeader(const FileEntry *File) { 167 HeadersMap::iterator Known = Headers.find(File); 168 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir && 169 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { 170 HeaderInfo.loadTopLevelSystemModules(); 171 return Headers.find(File); 172 } 173 return Known; 174 } 175 176 ModuleMap::KnownHeader 177 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, 178 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { 179 const DirectoryEntry *Dir = File->getDir(); 180 assert(Dir && "file in no directory"); 181 182 // Note: as an egregious but useful hack we use the real path here, because 183 // frameworks moving from top-level frameworks to embedded frameworks tend 184 // to be symlinked from the top-level location to the embedded location, 185 // and we need to resolve lookups as if we had found the embedded location. 186 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir); 187 188 // Keep walking up the directory hierarchy, looking for a directory with 189 // an umbrella header. 190 do { 191 auto KnownDir = UmbrellaDirs.find(Dir); 192 if (KnownDir != UmbrellaDirs.end()) 193 return KnownHeader(KnownDir->second, NormalHeader); 194 195 IntermediateDirs.push_back(Dir); 196 197 // Retrieve our parent path. 198 DirName = llvm::sys::path::parent_path(DirName); 199 if (DirName.empty()) 200 break; 201 202 // Resolve the parent path to a directory entry. 203 Dir = SourceMgr.getFileManager().getDirectory(DirName); 204 } while (Dir); 205 return KnownHeader(); 206 } 207 208 // Returns true if RequestingModule directly uses RequestedModule. 209 static bool directlyUses(const Module *RequestingModule, 210 const Module *RequestedModule) { 211 for (const Module* DirectUse : RequestingModule->DirectUses) { 212 if (RequestedModule->isSubModuleOf(DirectUse)) 213 return true; 214 } 215 return false; 216 } 217 218 static bool violatesPrivateInclude(Module *RequestingModule, 219 const FileEntry *IncFileEnt, 220 ModuleMap::ModuleHeaderRole Role, 221 Module *RequestedModule) { 222 bool IsPrivateRole = Role & ModuleMap::PrivateHeader; 223 #ifndef NDEBUG 224 if (IsPrivateRole) { 225 // Check for consistency between the module header role 226 // as obtained from the lookup and as obtained from the module. 227 // This check is not cheap, so enable it only for debugging. 228 bool IsPrivate = false; 229 SmallVectorImpl<Module::Header> *HeaderList[] = { 230 &RequestedModule->Headers[Module::HK_Private], 231 &RequestedModule->Headers[Module::HK_PrivateTextual]}; 232 for (auto *Hs : HeaderList) 233 IsPrivate |= 234 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) { 235 return H.Entry == IncFileEnt; 236 }) != Hs->end(); 237 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles"); 238 } 239 #endif 240 return IsPrivateRole && 241 RequestedModule->getTopLevelModule() != RequestingModule; 242 } 243 244 static Module *getTopLevelOrNull(Module *M) { 245 return M ? M->getTopLevelModule() : nullptr; 246 } 247 248 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, 249 SourceLocation FilenameLoc, 250 StringRef Filename, 251 const FileEntry *File) { 252 // No errors for indirect modules. This may be a bit of a problem for modules 253 // with no source files. 254 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) 255 return; 256 257 if (RequestingModule) 258 resolveUses(RequestingModule, /*Complain=*/false); 259 260 bool Excluded = false; 261 Module *Private = nullptr; 262 Module *NotUsed = nullptr; 263 264 HeadersMap::iterator Known = findKnownHeader(File); 265 if (Known != Headers.end()) { 266 for (const KnownHeader &Header : Known->second) { 267 // If 'File' is part of 'RequestingModule' we can definitely include it. 268 if (Header.getModule() && 269 Header.getModule()->isSubModuleOf(RequestingModule)) 270 return; 271 272 // Remember private headers for later printing of a diagnostic. 273 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(), 274 Header.getModule())) { 275 Private = Header.getModule(); 276 continue; 277 } 278 279 // If uses need to be specified explicitly, we are only allowed to return 280 // modules that are explicitly used by the requesting module. 281 if (RequestingModule && LangOpts.ModulesDeclUse && 282 !directlyUses(RequestingModule, Header.getModule())) { 283 NotUsed = Header.getModule(); 284 continue; 285 } 286 287 // We have found a module that we can happily use. 288 return; 289 } 290 291 Excluded = true; 292 } 293 294 // We have found a header, but it is private. 295 if (Private) { 296 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module) 297 << Filename; 298 return; 299 } 300 301 // We have found a module, but we don't use it. 302 if (NotUsed) { 303 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 304 << RequestingModule->getFullModuleName() << Filename; 305 return; 306 } 307 308 if (Excluded || isHeaderInUmbrellaDirs(File)) 309 return; 310 311 // At this point, only non-modular includes remain. 312 313 if (LangOpts.ModulesStrictDeclUse) { 314 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) 315 << RequestingModule->getFullModuleName() << Filename; 316 } else if (RequestingModule) { 317 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? 318 diag::warn_non_modular_include_in_framework_module : 319 diag::warn_non_modular_include_in_module; 320 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName(); 321 } 322 } 323 324 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, 325 const ModuleMap::KnownHeader &Old) { 326 // Prefer a public header over a private header. 327 if ((New.getRole() & ModuleMap::PrivateHeader) != 328 (Old.getRole() & ModuleMap::PrivateHeader)) 329 return !(New.getRole() & ModuleMap::PrivateHeader); 330 331 // Prefer a non-textual header over a textual header. 332 if ((New.getRole() & ModuleMap::TextualHeader) != 333 (Old.getRole() & ModuleMap::TextualHeader)) 334 return !(New.getRole() & ModuleMap::TextualHeader); 335 336 // Don't have a reason to choose between these. Just keep the first one. 337 return false; 338 } 339 340 ModuleMap::KnownHeader 341 ModuleMap::findModuleForHeader(const FileEntry *File, 342 Module *RequestingModule, 343 bool IncludeTextualHeaders) { 344 HeadersMap::iterator Known = findKnownHeader(File); 345 346 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { 347 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader)) 348 return ModuleMap::KnownHeader(); 349 return R; 350 }; 351 352 if (Known != Headers.end()) { 353 ModuleMap::KnownHeader Result; 354 355 // Iterate over all modules that 'File' is part of to find the best fit. 356 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), 357 E = Known->second.end(); 358 I != E; ++I) { 359 // Cannot use a module if it is unavailable. 360 if (!I->getModule()->isAvailable()) 361 continue; 362 363 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the 364 // module we are looking for. 365 if (I->getModule() == RequestingModule) 366 return MakeResult(*I); 367 368 // If uses need to be specified explicitly, we are only allowed to return 369 // modules that are explicitly used by the requesting module. 370 if (RequestingModule && LangOpts.ModulesDeclUse && 371 !directlyUses(RequestingModule, I->getModule())) 372 continue; 373 374 if (!Result || isBetterKnownHeader(*I, Result)) 375 Result = *I; 376 } 377 return MakeResult(Result); 378 } 379 380 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 381 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs); 382 if (H) { 383 Module *Result = H.getModule(); 384 385 // Search up the module stack until we find a module with an umbrella 386 // directory. 387 Module *UmbrellaModule = Result; 388 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 389 UmbrellaModule = UmbrellaModule->Parent; 390 391 if (UmbrellaModule->InferSubmodules) { 392 const FileEntry *UmbrellaModuleMap = 393 getModuleMapFileForUniquing(UmbrellaModule); 394 395 // Infer submodules for each of the directories we found between 396 // the directory of the umbrella header and the directory where 397 // the actual header is located. 398 bool Explicit = UmbrellaModule->InferExplicitSubmodules; 399 400 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 401 // Find or create the module that corresponds to this directory name. 402 SmallString<32> NameBuf; 403 StringRef Name = sanitizeFilenameAsIdentifier( 404 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf); 405 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 406 Explicit).first; 407 InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 408 Result->IsInferred = true; 409 410 // Associate the module and the directory. 411 UmbrellaDirs[SkippedDirs[I-1]] = Result; 412 413 // If inferred submodules export everything they import, add a 414 // wildcard to the set of exports. 415 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 416 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 417 } 418 419 // Infer a submodule with the same name as this header file. 420 SmallString<32> NameBuf; 421 StringRef Name = sanitizeFilenameAsIdentifier( 422 llvm::sys::path::stem(File->getName()), NameBuf); 423 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, 424 Explicit).first; 425 InferredModuleAllowedBy[Result] = UmbrellaModuleMap; 426 Result->IsInferred = true; 427 Result->addTopHeader(File); 428 429 // If inferred submodules export everything they import, add a 430 // wildcard to the set of exports. 431 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty()) 432 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 433 } else { 434 // Record each of the directories we stepped through as being part of 435 // the module we found, since the umbrella header covers them all. 436 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 437 UmbrellaDirs[SkippedDirs[I]] = Result; 438 } 439 440 Headers[File].push_back(KnownHeader(Result, NormalHeader)); 441 442 // If a header corresponds to an unavailable module, don't report 443 // that it maps to anything. 444 if (!Result->isAvailable()) 445 return KnownHeader(); 446 447 return MakeResult(Headers[File].back()); 448 } 449 450 return KnownHeader(); 451 } 452 453 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { 454 return isHeaderUnavailableInModule(Header, nullptr); 455 } 456 457 bool 458 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, 459 const Module *RequestingModule) const { 460 HeadersMap::const_iterator Known = Headers.find(Header); 461 if (Known != Headers.end()) { 462 for (SmallVectorImpl<KnownHeader>::const_iterator 463 I = Known->second.begin(), 464 E = Known->second.end(); 465 I != E; ++I) { 466 if (I->isAvailable() && (!RequestingModule || 467 I->getModule()->isSubModuleOf(RequestingModule))) 468 return false; 469 } 470 return true; 471 } 472 473 const DirectoryEntry *Dir = Header->getDir(); 474 SmallVector<const DirectoryEntry *, 2> SkippedDirs; 475 StringRef DirName = Dir->getName(); 476 477 auto IsUnavailable = [&](const Module *M) { 478 return !M->isAvailable() && (!RequestingModule || 479 M->isSubModuleOf(RequestingModule)); 480 }; 481 482 // Keep walking up the directory hierarchy, looking for a directory with 483 // an umbrella header. 484 do { 485 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir 486 = UmbrellaDirs.find(Dir); 487 if (KnownDir != UmbrellaDirs.end()) { 488 Module *Found = KnownDir->second; 489 if (IsUnavailable(Found)) 490 return true; 491 492 // Search up the module stack until we find a module with an umbrella 493 // directory. 494 Module *UmbrellaModule = Found; 495 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent) 496 UmbrellaModule = UmbrellaModule->Parent; 497 498 if (UmbrellaModule->InferSubmodules) { 499 for (unsigned I = SkippedDirs.size(); I != 0; --I) { 500 // Find or create the module that corresponds to this directory name. 501 SmallString<32> NameBuf; 502 StringRef Name = sanitizeFilenameAsIdentifier( 503 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), 504 NameBuf); 505 Found = lookupModuleQualified(Name, Found); 506 if (!Found) 507 return false; 508 if (IsUnavailable(Found)) 509 return true; 510 } 511 512 // Infer a submodule with the same name as this header file. 513 SmallString<32> NameBuf; 514 StringRef Name = sanitizeFilenameAsIdentifier( 515 llvm::sys::path::stem(Header->getName()), 516 NameBuf); 517 Found = lookupModuleQualified(Name, Found); 518 if (!Found) 519 return false; 520 } 521 522 return IsUnavailable(Found); 523 } 524 525 SkippedDirs.push_back(Dir); 526 527 // Retrieve our parent path. 528 DirName = llvm::sys::path::parent_path(DirName); 529 if (DirName.empty()) 530 break; 531 532 // Resolve the parent path to a directory entry. 533 Dir = SourceMgr.getFileManager().getDirectory(DirName); 534 } while (Dir); 535 536 return false; 537 } 538 539 Module *ModuleMap::findModule(StringRef Name) const { 540 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name); 541 if (Known != Modules.end()) 542 return Known->getValue(); 543 544 return nullptr; 545 } 546 547 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, 548 Module *Context) const { 549 for(; Context; Context = Context->Parent) { 550 if (Module *Sub = lookupModuleQualified(Name, Context)) 551 return Sub; 552 } 553 554 return findModule(Name); 555 } 556 557 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ 558 if (!Context) 559 return findModule(Name); 560 561 return Context->findSubmodule(Name); 562 } 563 564 std::pair<Module *, bool> 565 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, 566 bool IsExplicit) { 567 // Try to find an existing module with this name. 568 if (Module *Sub = lookupModuleQualified(Name, Parent)) 569 return std::make_pair(Sub, false); 570 571 // Create a new module with this name. 572 Module *Result = new Module(Name, SourceLocation(), Parent, 573 IsFramework, IsExplicit); 574 if (LangOpts.CurrentModule == Name) { 575 SourceModule = Result; 576 SourceModuleName = Name; 577 } 578 if (!Parent) { 579 Modules[Name] = Result; 580 if (!LangOpts.CurrentModule.empty() && !CompilingModule && 581 Name == LangOpts.CurrentModule) { 582 CompilingModule = Result; 583 } 584 } 585 return std::make_pair(Result, true); 586 } 587 588 /// \brief For a framework module, infer the framework against which we 589 /// should link. 590 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, 591 FileManager &FileMgr) { 592 assert(Mod->IsFramework && "Can only infer linking for framework modules"); 593 assert(!Mod->isSubFramework() && 594 "Can only infer linking for top-level frameworks"); 595 596 SmallString<128> LibName; 597 LibName += FrameworkDir->getName(); 598 llvm::sys::path::append(LibName, Mod->Name); 599 if (FileMgr.getFile(LibName)) { 600 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, 601 /*IsFramework=*/true)); 602 } 603 } 604 605 Module * 606 ModuleMap::inferFrameworkModule(StringRef ModuleName, 607 const DirectoryEntry *FrameworkDir, 608 bool IsSystem, 609 Module *Parent) { 610 Attributes Attrs; 611 Attrs.IsSystem = IsSystem; 612 return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent); 613 } 614 615 Module *ModuleMap::inferFrameworkModule(StringRef ModuleName, 616 const DirectoryEntry *FrameworkDir, 617 Attributes Attrs, Module *Parent) { 618 619 // Check whether we've already found this module. 620 if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) 621 return Mod; 622 623 FileManager &FileMgr = SourceMgr.getFileManager(); 624 625 // If the framework has a parent path from which we're allowed to infer 626 // a framework module, do so. 627 const FileEntry *ModuleMapFile = nullptr; 628 if (!Parent) { 629 // Determine whether we're allowed to infer a module map. 630 631 // Note: as an egregious but useful hack we use the real path here, because 632 // we might be looking at an embedded framework that symlinks out to a 633 // top-level framework, and we need to infer as if we were naming the 634 // top-level framework. 635 StringRef FrameworkDirName 636 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir); 637 638 // In case this is a case-insensitive filesystem, make sure the canonical 639 // directory name matches ModuleName exactly. Modules are case-sensitive. 640 // FIXME: we should be able to give a fix-it hint for the correct spelling. 641 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName) 642 return nullptr; 643 644 bool canInfer = false; 645 if (llvm::sys::path::has_parent_path(FrameworkDirName)) { 646 // Figure out the parent path. 647 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName); 648 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) { 649 // Check whether we have already looked into the parent directory 650 // for a module map. 651 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator 652 inferred = InferredDirectories.find(ParentDir); 653 if (inferred == InferredDirectories.end()) { 654 // We haven't looked here before. Load a module map, if there is 655 // one. 656 bool IsFrameworkDir = Parent.endswith(".framework"); 657 if (const FileEntry *ModMapFile = 658 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { 659 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir); 660 inferred = InferredDirectories.find(ParentDir); 661 } 662 663 if (inferred == InferredDirectories.end()) 664 inferred = InferredDirectories.insert( 665 std::make_pair(ParentDir, InferredDirectory())).first; 666 } 667 668 if (inferred->second.InferModules) { 669 // We're allowed to infer for this directory, but make sure it's okay 670 // to infer this particular module. 671 StringRef Name = llvm::sys::path::stem(FrameworkDirName); 672 canInfer = std::find(inferred->second.ExcludedModules.begin(), 673 inferred->second.ExcludedModules.end(), 674 Name) == inferred->second.ExcludedModules.end(); 675 676 Attrs.IsSystem |= inferred->second.Attrs.IsSystem; 677 Attrs.IsExternC |= inferred->second.Attrs.IsExternC; 678 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; 679 ModuleMapFile = inferred->second.ModuleMapFile; 680 } 681 } 682 } 683 684 // If we're not allowed to infer a framework module, don't. 685 if (!canInfer) 686 return nullptr; 687 } else 688 ModuleMapFile = getModuleMapFileForUniquing(Parent); 689 690 691 // Look for an umbrella header. 692 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 693 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h"); 694 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName); 695 696 // FIXME: If there's no umbrella header, we could probably scan the 697 // framework to load *everything*. But, it's not clear that this is a good 698 // idea. 699 if (!UmbrellaHeader) 700 return nullptr; 701 702 Module *Result = new Module(ModuleName, SourceLocation(), Parent, 703 /*IsFramework=*/true, /*IsExplicit=*/false); 704 InferredModuleAllowedBy[Result] = ModuleMapFile; 705 Result->IsInferred = true; 706 if (LangOpts.CurrentModule == ModuleName) { 707 SourceModule = Result; 708 SourceModuleName = ModuleName; 709 } 710 711 Result->IsSystem |= Attrs.IsSystem; 712 Result->IsExternC |= Attrs.IsExternC; 713 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; 714 715 if (!Parent) 716 Modules[ModuleName] = Result; 717 718 // umbrella header "umbrella-header-name" 719 Result->Umbrella = UmbrellaHeader; 720 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); 721 UmbrellaDirs[UmbrellaHeader->getDir()] = Result; 722 723 // export * 724 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 725 726 // module * { export * } 727 Result->InferSubmodules = true; 728 Result->InferExportWildcard = true; 729 730 // Look for subframeworks. 731 std::error_code EC; 732 SmallString<128> SubframeworksDirName 733 = StringRef(FrameworkDir->getName()); 734 llvm::sys::path::append(SubframeworksDirName, "Frameworks"); 735 llvm::sys::path::native(SubframeworksDirName); 736 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd; 737 Dir != DirEnd && !EC; Dir.increment(EC)) { 738 if (!StringRef(Dir->path()).endswith(".framework")) 739 continue; 740 741 if (const DirectoryEntry *SubframeworkDir 742 = FileMgr.getDirectory(Dir->path())) { 743 // Note: as an egregious but useful hack, we use the real path here and 744 // check whether it is actually a subdirectory of the parent directory. 745 // This will not be the case if the 'subframework' is actually a symlink 746 // out to a top-level framework. 747 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 748 bool FoundParent = false; 749 do { 750 // Get the parent directory name. 751 SubframeworkDirName 752 = llvm::sys::path::parent_path(SubframeworkDirName); 753 if (SubframeworkDirName.empty()) 754 break; 755 756 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 757 FoundParent = true; 758 break; 759 } 760 } while (true); 761 762 if (!FoundParent) 763 continue; 764 765 // FIXME: Do we want to warn about subframeworks without umbrella headers? 766 SmallString<32> NameBuf; 767 inferFrameworkModule(sanitizeFilenameAsIdentifier( 768 llvm::sys::path::stem(Dir->path()), NameBuf), 769 SubframeworkDir, Attrs, Result); 770 } 771 } 772 773 // If the module is a top-level framework, automatically link against the 774 // framework. 775 if (!Result->isSubFramework()) { 776 inferFrameworkLink(Result, FrameworkDir, FileMgr); 777 } 778 779 return Result; 780 } 781 782 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 783 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 784 Mod->Umbrella = UmbrellaHeader; 785 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 786 } 787 788 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 789 Mod->Umbrella = UmbrellaDir; 790 UmbrellaDirs[UmbrellaDir] = Mod; 791 } 792 793 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) { 794 switch ((int)Role) { 795 default: llvm_unreachable("unknown header role"); 796 case ModuleMap::NormalHeader: 797 return Module::HK_Normal; 798 case ModuleMap::PrivateHeader: 799 return Module::HK_Private; 800 case ModuleMap::TextualHeader: 801 return Module::HK_Textual; 802 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader: 803 return Module::HK_PrivateTextual; 804 } 805 } 806 807 void ModuleMap::addHeader(Module *Mod, Module::Header Header, 808 ModuleHeaderRole Role) { 809 if (!(Role & TextualHeader)) { 810 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 811 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 812 isCompilingModuleHeader); 813 } 814 Headers[Header.Entry].push_back(KnownHeader(Mod, Role)); 815 816 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header)); 817 } 818 819 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { 820 // Add this as a known header so we won't implicitly add it to any 821 // umbrella directory module. 822 // FIXME: Should we only exclude it from umbrella modules within the 823 // specified module? 824 (void) Headers[Header.Entry]; 825 826 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); 827 } 828 829 const FileEntry * 830 ModuleMap::getContainingModuleMapFile(const Module *Module) const { 831 if (Module->DefinitionLoc.isInvalid()) 832 return nullptr; 833 834 return SourceMgr.getFileEntryForID( 835 SourceMgr.getFileID(Module->DefinitionLoc)); 836 } 837 838 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 839 if (M->IsInferred) { 840 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 841 return InferredModuleAllowedBy.find(M)->second; 842 } 843 return getContainingModuleMapFile(M); 844 } 845 846 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 847 assert(M->IsInferred && "module not inferred"); 848 InferredModuleAllowedBy[M] = ModMap; 849 } 850 851 void ModuleMap::dump() { 852 llvm::errs() << "Modules:"; 853 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 854 MEnd = Modules.end(); 855 M != MEnd; ++M) 856 M->getValue()->print(llvm::errs(), 2); 857 858 llvm::errs() << "Headers:"; 859 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 860 H != HEnd; ++H) { 861 llvm::errs() << " \"" << H->first->getName() << "\" -> "; 862 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 863 E = H->second.end(); 864 I != E; ++I) { 865 if (I != H->second.begin()) 866 llvm::errs() << ","; 867 llvm::errs() << I->getModule()->getFullModuleName(); 868 } 869 llvm::errs() << "\n"; 870 } 871 } 872 873 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 874 bool HadError = false; 875 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 876 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 877 Complain); 878 if (Export.getPointer() || Export.getInt()) 879 Mod->Exports.push_back(Export); 880 else 881 HadError = true; 882 } 883 Mod->UnresolvedExports.clear(); 884 return HadError; 885 } 886 887 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 888 bool HadError = false; 889 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 890 Module *DirectUse = 891 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 892 if (DirectUse) 893 Mod->DirectUses.push_back(DirectUse); 894 else 895 HadError = true; 896 } 897 Mod->UnresolvedDirectUses.clear(); 898 return HadError; 899 } 900 901 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 902 bool HadError = false; 903 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 904 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 905 Mod, Complain); 906 if (!OtherMod) { 907 HadError = true; 908 continue; 909 } 910 911 Module::Conflict Conflict; 912 Conflict.Other = OtherMod; 913 Conflict.Message = Mod->UnresolvedConflicts[I].Message; 914 Mod->Conflicts.push_back(Conflict); 915 } 916 Mod->UnresolvedConflicts.clear(); 917 return HadError; 918 } 919 920 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 921 if (Loc.isInvalid()) 922 return nullptr; 923 924 // Use the expansion location to determine which module we're in. 925 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 926 if (!ExpansionLoc.isFileID()) 927 return nullptr; 928 929 const SourceManager &SrcMgr = Loc.getManager(); 930 FileID ExpansionFileID = ExpansionLoc.getFileID(); 931 932 while (const FileEntry *ExpansionFile 933 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 934 // Find the module that owns this header (if any). 935 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 936 return Mod; 937 938 // No module owns this header, so look up the inclusion chain to see if 939 // any included header has an associated module. 940 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 941 if (IncludeLoc.isInvalid()) 942 return nullptr; 943 944 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 945 } 946 947 return nullptr; 948 } 949 950 //----------------------------------------------------------------------------// 951 // Module map file parser 952 //----------------------------------------------------------------------------// 953 954 namespace clang { 955 /// \brief A token in a module map file. 956 struct MMToken { 957 enum TokenKind { 958 Comma, 959 ConfigMacros, 960 Conflict, 961 EndOfFile, 962 HeaderKeyword, 963 Identifier, 964 Exclaim, 965 ExcludeKeyword, 966 ExplicitKeyword, 967 ExportKeyword, 968 ExternKeyword, 969 FrameworkKeyword, 970 LinkKeyword, 971 ModuleKeyword, 972 Period, 973 PrivateKeyword, 974 UmbrellaKeyword, 975 UseKeyword, 976 RequiresKeyword, 977 Star, 978 StringLiteral, 979 TextualKeyword, 980 LBrace, 981 RBrace, 982 LSquare, 983 RSquare 984 } Kind; 985 986 unsigned Location; 987 unsigned StringLength; 988 const char *StringData; 989 990 void clear() { 991 Kind = EndOfFile; 992 Location = 0; 993 StringLength = 0; 994 StringData = nullptr; 995 } 996 997 bool is(TokenKind K) const { return Kind == K; } 998 999 SourceLocation getLocation() const { 1000 return SourceLocation::getFromRawEncoding(Location); 1001 } 1002 1003 StringRef getString() const { 1004 return StringRef(StringData, StringLength); 1005 } 1006 }; 1007 1008 class ModuleMapParser { 1009 Lexer &L; 1010 SourceManager &SourceMgr; 1011 1012 /// \brief Default target information, used only for string literal 1013 /// parsing. 1014 const TargetInfo *Target; 1015 1016 DiagnosticsEngine &Diags; 1017 ModuleMap ⤅ 1018 1019 /// \brief The current module map file. 1020 const FileEntry *ModuleMapFile; 1021 1022 /// \brief The directory that file names in this module map file should 1023 /// be resolved relative to. 1024 const DirectoryEntry *Directory; 1025 1026 /// \brief The directory containing Clang-supplied headers. 1027 const DirectoryEntry *BuiltinIncludeDir; 1028 1029 /// \brief Whether this module map is in a system header directory. 1030 bool IsSystem; 1031 1032 /// \brief Whether an error occurred. 1033 bool HadError; 1034 1035 /// \brief Stores string data for the various string literals referenced 1036 /// during parsing. 1037 llvm::BumpPtrAllocator StringData; 1038 1039 /// \brief The current token. 1040 MMToken Tok; 1041 1042 /// \brief The active module. 1043 Module *ActiveModule; 1044 1045 /// \brief Consume the current token and return its location. 1046 SourceLocation consumeToken(); 1047 1048 /// \brief Skip tokens until we reach the a token with the given kind 1049 /// (or the end of the file). 1050 void skipUntil(MMToken::TokenKind K); 1051 1052 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1053 bool parseModuleId(ModuleId &Id); 1054 void parseModuleDecl(); 1055 void parseExternModuleDecl(); 1056 void parseRequiresDecl(); 1057 void parseHeaderDecl(clang::MMToken::TokenKind, 1058 SourceLocation LeadingLoc); 1059 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1060 void parseExportDecl(); 1061 void parseUseDecl(); 1062 void parseLinkDecl(); 1063 void parseConfigMacros(); 1064 void parseConflict(); 1065 void parseInferredModuleDecl(bool Framework, bool Explicit); 1066 1067 typedef ModuleMap::Attributes Attributes; 1068 bool parseOptionalAttributes(Attributes &Attrs); 1069 1070 public: 1071 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1072 const TargetInfo *Target, 1073 DiagnosticsEngine &Diags, 1074 ModuleMap &Map, 1075 const FileEntry *ModuleMapFile, 1076 const DirectoryEntry *Directory, 1077 const DirectoryEntry *BuiltinIncludeDir, 1078 bool IsSystem) 1079 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1080 ModuleMapFile(ModuleMapFile), Directory(Directory), 1081 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem), 1082 HadError(false), ActiveModule(nullptr) 1083 { 1084 Tok.clear(); 1085 consumeToken(); 1086 } 1087 1088 bool parseModuleMapFile(); 1089 }; 1090 } 1091 1092 SourceLocation ModuleMapParser::consumeToken() { 1093 retry: 1094 SourceLocation Result = Tok.getLocation(); 1095 Tok.clear(); 1096 1097 Token LToken; 1098 L.LexFromRawLexer(LToken); 1099 Tok.Location = LToken.getLocation().getRawEncoding(); 1100 switch (LToken.getKind()) { 1101 case tok::raw_identifier: { 1102 StringRef RI = LToken.getRawIdentifier(); 1103 Tok.StringData = RI.data(); 1104 Tok.StringLength = RI.size(); 1105 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1106 .Case("config_macros", MMToken::ConfigMacros) 1107 .Case("conflict", MMToken::Conflict) 1108 .Case("exclude", MMToken::ExcludeKeyword) 1109 .Case("explicit", MMToken::ExplicitKeyword) 1110 .Case("export", MMToken::ExportKeyword) 1111 .Case("extern", MMToken::ExternKeyword) 1112 .Case("framework", MMToken::FrameworkKeyword) 1113 .Case("header", MMToken::HeaderKeyword) 1114 .Case("link", MMToken::LinkKeyword) 1115 .Case("module", MMToken::ModuleKeyword) 1116 .Case("private", MMToken::PrivateKeyword) 1117 .Case("requires", MMToken::RequiresKeyword) 1118 .Case("textual", MMToken::TextualKeyword) 1119 .Case("umbrella", MMToken::UmbrellaKeyword) 1120 .Case("use", MMToken::UseKeyword) 1121 .Default(MMToken::Identifier); 1122 break; 1123 } 1124 1125 case tok::comma: 1126 Tok.Kind = MMToken::Comma; 1127 break; 1128 1129 case tok::eof: 1130 Tok.Kind = MMToken::EndOfFile; 1131 break; 1132 1133 case tok::l_brace: 1134 Tok.Kind = MMToken::LBrace; 1135 break; 1136 1137 case tok::l_square: 1138 Tok.Kind = MMToken::LSquare; 1139 break; 1140 1141 case tok::period: 1142 Tok.Kind = MMToken::Period; 1143 break; 1144 1145 case tok::r_brace: 1146 Tok.Kind = MMToken::RBrace; 1147 break; 1148 1149 case tok::r_square: 1150 Tok.Kind = MMToken::RSquare; 1151 break; 1152 1153 case tok::star: 1154 Tok.Kind = MMToken::Star; 1155 break; 1156 1157 case tok::exclaim: 1158 Tok.Kind = MMToken::Exclaim; 1159 break; 1160 1161 case tok::string_literal: { 1162 if (LToken.hasUDSuffix()) { 1163 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1164 HadError = true; 1165 goto retry; 1166 } 1167 1168 // Parse the string literal. 1169 LangOptions LangOpts; 1170 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1171 if (StringLiteral.hadError) 1172 goto retry; 1173 1174 // Copy the string literal into our string data allocator. 1175 unsigned Length = StringLiteral.GetStringLength(); 1176 char *Saved = StringData.Allocate<char>(Length + 1); 1177 memcpy(Saved, StringLiteral.GetString().data(), Length); 1178 Saved[Length] = 0; 1179 1180 // Form the token. 1181 Tok.Kind = MMToken::StringLiteral; 1182 Tok.StringData = Saved; 1183 Tok.StringLength = Length; 1184 break; 1185 } 1186 1187 case tok::comment: 1188 goto retry; 1189 1190 default: 1191 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1192 HadError = true; 1193 goto retry; 1194 } 1195 1196 return Result; 1197 } 1198 1199 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1200 unsigned braceDepth = 0; 1201 unsigned squareDepth = 0; 1202 do { 1203 switch (Tok.Kind) { 1204 case MMToken::EndOfFile: 1205 return; 1206 1207 case MMToken::LBrace: 1208 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1209 return; 1210 1211 ++braceDepth; 1212 break; 1213 1214 case MMToken::LSquare: 1215 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1216 return; 1217 1218 ++squareDepth; 1219 break; 1220 1221 case MMToken::RBrace: 1222 if (braceDepth > 0) 1223 --braceDepth; 1224 else if (Tok.is(K)) 1225 return; 1226 break; 1227 1228 case MMToken::RSquare: 1229 if (squareDepth > 0) 1230 --squareDepth; 1231 else if (Tok.is(K)) 1232 return; 1233 break; 1234 1235 default: 1236 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1237 return; 1238 break; 1239 } 1240 1241 consumeToken(); 1242 } while (true); 1243 } 1244 1245 /// \brief Parse a module-id. 1246 /// 1247 /// module-id: 1248 /// identifier 1249 /// identifier '.' module-id 1250 /// 1251 /// \returns true if an error occurred, false otherwise. 1252 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1253 Id.clear(); 1254 do { 1255 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1256 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1257 consumeToken(); 1258 } else { 1259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1260 return true; 1261 } 1262 1263 if (!Tok.is(MMToken::Period)) 1264 break; 1265 1266 consumeToken(); 1267 } while (true); 1268 1269 return false; 1270 } 1271 1272 namespace { 1273 /// \brief Enumerates the known attributes. 1274 enum AttributeKind { 1275 /// \brief An unknown attribute. 1276 AT_unknown, 1277 /// \brief The 'system' attribute. 1278 AT_system, 1279 /// \brief The 'extern_c' attribute. 1280 AT_extern_c, 1281 /// \brief The 'exhaustive' attribute. 1282 AT_exhaustive 1283 }; 1284 } 1285 1286 /// \brief Parse a module declaration. 1287 /// 1288 /// module-declaration: 1289 /// 'extern' 'module' module-id string-literal 1290 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1291 /// { module-member* } 1292 /// 1293 /// module-member: 1294 /// requires-declaration 1295 /// header-declaration 1296 /// submodule-declaration 1297 /// export-declaration 1298 /// link-declaration 1299 /// 1300 /// submodule-declaration: 1301 /// module-declaration 1302 /// inferred-submodule-declaration 1303 void ModuleMapParser::parseModuleDecl() { 1304 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1305 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1306 if (Tok.is(MMToken::ExternKeyword)) { 1307 parseExternModuleDecl(); 1308 return; 1309 } 1310 1311 // Parse 'explicit' or 'framework' keyword, if present. 1312 SourceLocation ExplicitLoc; 1313 bool Explicit = false; 1314 bool Framework = false; 1315 1316 // Parse 'explicit' keyword, if present. 1317 if (Tok.is(MMToken::ExplicitKeyword)) { 1318 ExplicitLoc = consumeToken(); 1319 Explicit = true; 1320 } 1321 1322 // Parse 'framework' keyword, if present. 1323 if (Tok.is(MMToken::FrameworkKeyword)) { 1324 consumeToken(); 1325 Framework = true; 1326 } 1327 1328 // Parse 'module' keyword. 1329 if (!Tok.is(MMToken::ModuleKeyword)) { 1330 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1331 consumeToken(); 1332 HadError = true; 1333 return; 1334 } 1335 consumeToken(); // 'module' keyword 1336 1337 // If we have a wildcard for the module name, this is an inferred submodule. 1338 // Parse it. 1339 if (Tok.is(MMToken::Star)) 1340 return parseInferredModuleDecl(Framework, Explicit); 1341 1342 // Parse the module name. 1343 ModuleId Id; 1344 if (parseModuleId(Id)) { 1345 HadError = true; 1346 return; 1347 } 1348 1349 if (ActiveModule) { 1350 if (Id.size() > 1) { 1351 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1352 << SourceRange(Id.front().second, Id.back().second); 1353 1354 HadError = true; 1355 return; 1356 } 1357 } else if (Id.size() == 1 && Explicit) { 1358 // Top-level modules can't be explicit. 1359 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1360 Explicit = false; 1361 ExplicitLoc = SourceLocation(); 1362 HadError = true; 1363 } 1364 1365 Module *PreviousActiveModule = ActiveModule; 1366 if (Id.size() > 1) { 1367 // This module map defines a submodule. Go find the module of which it 1368 // is a submodule. 1369 ActiveModule = nullptr; 1370 const Module *TopLevelModule = nullptr; 1371 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1372 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1373 if (I == 0) 1374 TopLevelModule = Next; 1375 ActiveModule = Next; 1376 continue; 1377 } 1378 1379 if (ActiveModule) { 1380 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1381 << Id[I].first 1382 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1383 } else { 1384 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1385 } 1386 HadError = true; 1387 return; 1388 } 1389 1390 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1391 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1392 "submodule defined in same file as 'module *' that allowed its " 1393 "top-level module"); 1394 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1395 } 1396 } 1397 1398 StringRef ModuleName = Id.back().first; 1399 SourceLocation ModuleNameLoc = Id.back().second; 1400 1401 // Parse the optional attribute list. 1402 Attributes Attrs; 1403 parseOptionalAttributes(Attrs); 1404 1405 // Parse the opening brace. 1406 if (!Tok.is(MMToken::LBrace)) { 1407 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1408 << ModuleName; 1409 HadError = true; 1410 return; 1411 } 1412 SourceLocation LBraceLoc = consumeToken(); 1413 1414 // Determine whether this (sub)module has already been defined. 1415 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1416 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1417 // Skip the module definition. 1418 skipUntil(MMToken::RBrace); 1419 if (Tok.is(MMToken::RBrace)) 1420 consumeToken(); 1421 else { 1422 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1423 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1424 HadError = true; 1425 } 1426 return; 1427 } 1428 1429 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1430 << ModuleName; 1431 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1432 1433 // Skip the module definition. 1434 skipUntil(MMToken::RBrace); 1435 if (Tok.is(MMToken::RBrace)) 1436 consumeToken(); 1437 1438 HadError = true; 1439 return; 1440 } 1441 1442 // Start defining this module. 1443 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1444 Explicit).first; 1445 ActiveModule->DefinitionLoc = ModuleNameLoc; 1446 if (Attrs.IsSystem || IsSystem) 1447 ActiveModule->IsSystem = true; 1448 if (Attrs.IsExternC) 1449 ActiveModule->IsExternC = true; 1450 ActiveModule->Directory = Directory; 1451 1452 bool Done = false; 1453 do { 1454 switch (Tok.Kind) { 1455 case MMToken::EndOfFile: 1456 case MMToken::RBrace: 1457 Done = true; 1458 break; 1459 1460 case MMToken::ConfigMacros: 1461 parseConfigMacros(); 1462 break; 1463 1464 case MMToken::Conflict: 1465 parseConflict(); 1466 break; 1467 1468 case MMToken::ExplicitKeyword: 1469 case MMToken::ExternKeyword: 1470 case MMToken::FrameworkKeyword: 1471 case MMToken::ModuleKeyword: 1472 parseModuleDecl(); 1473 break; 1474 1475 case MMToken::ExportKeyword: 1476 parseExportDecl(); 1477 break; 1478 1479 case MMToken::UseKeyword: 1480 parseUseDecl(); 1481 break; 1482 1483 case MMToken::RequiresKeyword: 1484 parseRequiresDecl(); 1485 break; 1486 1487 case MMToken::TextualKeyword: 1488 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1489 break; 1490 1491 case MMToken::UmbrellaKeyword: { 1492 SourceLocation UmbrellaLoc = consumeToken(); 1493 if (Tok.is(MMToken::HeaderKeyword)) 1494 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1495 else 1496 parseUmbrellaDirDecl(UmbrellaLoc); 1497 break; 1498 } 1499 1500 case MMToken::ExcludeKeyword: 1501 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1502 break; 1503 1504 case MMToken::PrivateKeyword: 1505 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1506 break; 1507 1508 case MMToken::HeaderKeyword: 1509 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1510 break; 1511 1512 case MMToken::LinkKeyword: 1513 parseLinkDecl(); 1514 break; 1515 1516 default: 1517 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1518 consumeToken(); 1519 break; 1520 } 1521 } while (!Done); 1522 1523 if (Tok.is(MMToken::RBrace)) 1524 consumeToken(); 1525 else { 1526 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1527 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1528 HadError = true; 1529 } 1530 1531 // If the active module is a top-level framework, and there are no link 1532 // libraries, automatically link against the framework. 1533 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1534 ActiveModule->LinkLibraries.empty()) { 1535 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1536 } 1537 1538 // If the module meets all requirements but is still unavailable, mark the 1539 // whole tree as unavailable to prevent it from building. 1540 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1541 ActiveModule->Parent) { 1542 ActiveModule->getTopLevelModule()->markUnavailable(); 1543 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1544 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1545 } 1546 1547 // We're done parsing this module. Pop back to the previous module. 1548 ActiveModule = PreviousActiveModule; 1549 } 1550 1551 /// \brief Parse an extern module declaration. 1552 /// 1553 /// extern module-declaration: 1554 /// 'extern' 'module' module-id string-literal 1555 void ModuleMapParser::parseExternModuleDecl() { 1556 assert(Tok.is(MMToken::ExternKeyword)); 1557 consumeToken(); // 'extern' keyword 1558 1559 // Parse 'module' keyword. 1560 if (!Tok.is(MMToken::ModuleKeyword)) { 1561 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1562 consumeToken(); 1563 HadError = true; 1564 return; 1565 } 1566 consumeToken(); // 'module' keyword 1567 1568 // Parse the module name. 1569 ModuleId Id; 1570 if (parseModuleId(Id)) { 1571 HadError = true; 1572 return; 1573 } 1574 1575 // Parse the referenced module map file name. 1576 if (!Tok.is(MMToken::StringLiteral)) { 1577 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1578 HadError = true; 1579 return; 1580 } 1581 std::string FileName = Tok.getString(); 1582 consumeToken(); // filename 1583 1584 StringRef FileNameRef = FileName; 1585 SmallString<128> ModuleMapFileName; 1586 if (llvm::sys::path::is_relative(FileNameRef)) { 1587 ModuleMapFileName += Directory->getName(); 1588 llvm::sys::path::append(ModuleMapFileName, FileName); 1589 FileNameRef = ModuleMapFileName; 1590 } 1591 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1592 Map.parseModuleMapFile( 1593 File, /*IsSystem=*/false, 1594 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 1595 ? Directory 1596 : File->getDir()); 1597 } 1598 1599 /// \brief Parse a requires declaration. 1600 /// 1601 /// requires-declaration: 1602 /// 'requires' feature-list 1603 /// 1604 /// feature-list: 1605 /// feature ',' feature-list 1606 /// feature 1607 /// 1608 /// feature: 1609 /// '!'[opt] identifier 1610 void ModuleMapParser::parseRequiresDecl() { 1611 assert(Tok.is(MMToken::RequiresKeyword)); 1612 1613 // Parse 'requires' keyword. 1614 consumeToken(); 1615 1616 // Parse the feature-list. 1617 do { 1618 bool RequiredState = true; 1619 if (Tok.is(MMToken::Exclaim)) { 1620 RequiredState = false; 1621 consumeToken(); 1622 } 1623 1624 if (!Tok.is(MMToken::Identifier)) { 1625 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1626 HadError = true; 1627 return; 1628 } 1629 1630 // Consume the feature name. 1631 std::string Feature = Tok.getString(); 1632 consumeToken(); 1633 1634 // Add this feature. 1635 ActiveModule->addRequirement(Feature, RequiredState, 1636 Map.LangOpts, *Map.Target); 1637 1638 if (!Tok.is(MMToken::Comma)) 1639 break; 1640 1641 // Consume the comma. 1642 consumeToken(); 1643 } while (true); 1644 } 1645 1646 /// \brief Append to \p Paths the set of paths needed to get to the 1647 /// subframework in which the given module lives. 1648 static void appendSubframeworkPaths(Module *Mod, 1649 SmallVectorImpl<char> &Path) { 1650 // Collect the framework names from the given module to the top-level module. 1651 SmallVector<StringRef, 2> Paths; 1652 for (; Mod; Mod = Mod->Parent) { 1653 if (Mod->IsFramework) 1654 Paths.push_back(Mod->Name); 1655 } 1656 1657 if (Paths.empty()) 1658 return; 1659 1660 // Add Frameworks/Name.framework for each subframework. 1661 for (unsigned I = Paths.size() - 1; I != 0; --I) 1662 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1663 } 1664 1665 /// \brief Parse a header declaration. 1666 /// 1667 /// header-declaration: 1668 /// 'textual'[opt] 'header' string-literal 1669 /// 'private' 'textual'[opt] 'header' string-literal 1670 /// 'exclude' 'header' string-literal 1671 /// 'umbrella' 'header' string-literal 1672 /// 1673 /// FIXME: Support 'private textual header'. 1674 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1675 SourceLocation LeadingLoc) { 1676 // We've already consumed the first token. 1677 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1678 if (LeadingToken == MMToken::PrivateKeyword) { 1679 Role = ModuleMap::PrivateHeader; 1680 // 'private' may optionally be followed by 'textual'. 1681 if (Tok.is(MMToken::TextualKeyword)) { 1682 LeadingToken = Tok.Kind; 1683 consumeToken(); 1684 } 1685 } 1686 if (LeadingToken == MMToken::TextualKeyword) 1687 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1688 1689 if (LeadingToken != MMToken::HeaderKeyword) { 1690 if (!Tok.is(MMToken::HeaderKeyword)) { 1691 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1692 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 1693 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 1694 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 1695 return; 1696 } 1697 consumeToken(); 1698 } 1699 1700 // Parse the header name. 1701 if (!Tok.is(MMToken::StringLiteral)) { 1702 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1703 << "header"; 1704 HadError = true; 1705 return; 1706 } 1707 Module::UnresolvedHeaderDirective Header; 1708 Header.FileName = Tok.getString(); 1709 Header.FileNameLoc = consumeToken(); 1710 1711 // Check whether we already have an umbrella. 1712 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1713 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 1714 << ActiveModule->getFullModuleName(); 1715 HadError = true; 1716 return; 1717 } 1718 1719 // Look for this file. 1720 const FileEntry *File = nullptr; 1721 const FileEntry *BuiltinFile = nullptr; 1722 SmallString<128> RelativePathName; 1723 if (llvm::sys::path::is_absolute(Header.FileName)) { 1724 RelativePathName = Header.FileName; 1725 File = SourceMgr.getFileManager().getFile(RelativePathName); 1726 } else { 1727 // Search for the header file within the search directory. 1728 SmallString<128> FullPathName(Directory->getName()); 1729 unsigned FullPathLength = FullPathName.size(); 1730 1731 if (ActiveModule->isPartOfFramework()) { 1732 appendSubframeworkPaths(ActiveModule, RelativePathName); 1733 1734 // Check whether this file is in the public headers. 1735 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); 1736 llvm::sys::path::append(FullPathName, RelativePathName); 1737 File = SourceMgr.getFileManager().getFile(FullPathName); 1738 1739 if (!File) { 1740 // Check whether this file is in the private headers. 1741 // FIXME: Should we retain the subframework paths here? 1742 RelativePathName.clear(); 1743 FullPathName.resize(FullPathLength); 1744 llvm::sys::path::append(RelativePathName, "PrivateHeaders", 1745 Header.FileName); 1746 llvm::sys::path::append(FullPathName, RelativePathName); 1747 File = SourceMgr.getFileManager().getFile(FullPathName); 1748 } 1749 } else { 1750 // Lookup for normal headers. 1751 llvm::sys::path::append(RelativePathName, Header.FileName); 1752 llvm::sys::path::append(FullPathName, RelativePathName); 1753 File = SourceMgr.getFileManager().getFile(FullPathName); 1754 1755 // If this is a system module with a top-level header, this header 1756 // may have a counterpart (or replacement) in the set of headers 1757 // supplied by Clang. Find that builtin header. 1758 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1759 BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1760 isBuiltinHeader(Header.FileName)) { 1761 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1762 llvm::sys::path::append(BuiltinPathName, Header.FileName); 1763 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1764 1765 // If Clang supplies this header but the underlying system does not, 1766 // just silently swap in our builtin version. Otherwise, we'll end 1767 // up adding both (later). 1768 if (!File && BuiltinFile) { 1769 File = BuiltinFile; 1770 RelativePathName = BuiltinPathName; 1771 BuiltinFile = nullptr; 1772 } 1773 } 1774 } 1775 } 1776 1777 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1778 // Come up with a lazy way to do this. 1779 if (File) { 1780 if (LeadingToken == MMToken::UmbrellaKeyword) { 1781 const DirectoryEntry *UmbrellaDir = File->getDir(); 1782 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1783 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 1784 << UmbrellaModule->getFullModuleName(); 1785 HadError = true; 1786 } else { 1787 // Record this umbrella header. 1788 Map.setUmbrellaHeader(ActiveModule, File); 1789 } 1790 } else if (LeadingToken == MMToken::ExcludeKeyword) { 1791 Module::Header H = {RelativePathName.str(), File}; 1792 Map.excludeHeader(ActiveModule, H); 1793 } else { 1794 // If there is a builtin counterpart to this file, add it now, before 1795 // the "real" header, so we build the built-in one first when building 1796 // the module. 1797 if (BuiltinFile) { 1798 // FIXME: Taking the name from the FileEntry is unstable and can give 1799 // different results depending on how we've previously named that file 1800 // in this build. 1801 Module::Header H = { BuiltinFile->getName(), BuiltinFile }; 1802 Map.addHeader(ActiveModule, H, Role); 1803 } 1804 1805 // Record this header. 1806 Module::Header H = { RelativePathName.str(), File }; 1807 Map.addHeader(ActiveModule, H, Role); 1808 } 1809 } else if (LeadingToken != MMToken::ExcludeKeyword) { 1810 // Ignore excluded header files. They're optional anyway. 1811 1812 // If we find a module that has a missing header, we mark this module as 1813 // unavailable and store the header directive for displaying diagnostics. 1814 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 1815 ActiveModule->markUnavailable(); 1816 ActiveModule->MissingHeaders.push_back(Header); 1817 } 1818 } 1819 1820 /// \brief Parse an umbrella directory declaration. 1821 /// 1822 /// umbrella-dir-declaration: 1823 /// umbrella string-literal 1824 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1825 // Parse the directory name. 1826 if (!Tok.is(MMToken::StringLiteral)) { 1827 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1828 << "umbrella"; 1829 HadError = true; 1830 return; 1831 } 1832 1833 std::string DirName = Tok.getString(); 1834 SourceLocation DirNameLoc = consumeToken(); 1835 1836 // Check whether we already have an umbrella. 1837 if (ActiveModule->Umbrella) { 1838 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1839 << ActiveModule->getFullModuleName(); 1840 HadError = true; 1841 return; 1842 } 1843 1844 // Look for this file. 1845 const DirectoryEntry *Dir = nullptr; 1846 if (llvm::sys::path::is_absolute(DirName)) 1847 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1848 else { 1849 SmallString<128> PathName; 1850 PathName = Directory->getName(); 1851 llvm::sys::path::append(PathName, DirName); 1852 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1853 } 1854 1855 if (!Dir) { 1856 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1857 << DirName; 1858 HadError = true; 1859 return; 1860 } 1861 1862 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1863 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1864 << OwningModule->getFullModuleName(); 1865 HadError = true; 1866 return; 1867 } 1868 1869 // Record this umbrella directory. 1870 Map.setUmbrellaDir(ActiveModule, Dir); 1871 } 1872 1873 /// \brief Parse a module export declaration. 1874 /// 1875 /// export-declaration: 1876 /// 'export' wildcard-module-id 1877 /// 1878 /// wildcard-module-id: 1879 /// identifier 1880 /// '*' 1881 /// identifier '.' wildcard-module-id 1882 void ModuleMapParser::parseExportDecl() { 1883 assert(Tok.is(MMToken::ExportKeyword)); 1884 SourceLocation ExportLoc = consumeToken(); 1885 1886 // Parse the module-id with an optional wildcard at the end. 1887 ModuleId ParsedModuleId; 1888 bool Wildcard = false; 1889 do { 1890 // FIXME: Support string-literal module names here. 1891 if (Tok.is(MMToken::Identifier)) { 1892 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1893 Tok.getLocation())); 1894 consumeToken(); 1895 1896 if (Tok.is(MMToken::Period)) { 1897 consumeToken(); 1898 continue; 1899 } 1900 1901 break; 1902 } 1903 1904 if(Tok.is(MMToken::Star)) { 1905 Wildcard = true; 1906 consumeToken(); 1907 break; 1908 } 1909 1910 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 1911 HadError = true; 1912 return; 1913 } while (true); 1914 1915 Module::UnresolvedExportDecl Unresolved = { 1916 ExportLoc, ParsedModuleId, Wildcard 1917 }; 1918 ActiveModule->UnresolvedExports.push_back(Unresolved); 1919 } 1920 1921 /// \brief Parse a module uses declaration. 1922 /// 1923 /// uses-declaration: 1924 /// 'uses' wildcard-module-id 1925 void ModuleMapParser::parseUseDecl() { 1926 assert(Tok.is(MMToken::UseKeyword)); 1927 consumeToken(); 1928 // Parse the module-id. 1929 ModuleId ParsedModuleId; 1930 parseModuleId(ParsedModuleId); 1931 1932 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1933 } 1934 1935 /// \brief Parse a link declaration. 1936 /// 1937 /// module-declaration: 1938 /// 'link' 'framework'[opt] string-literal 1939 void ModuleMapParser::parseLinkDecl() { 1940 assert(Tok.is(MMToken::LinkKeyword)); 1941 SourceLocation LinkLoc = consumeToken(); 1942 1943 // Parse the optional 'framework' keyword. 1944 bool IsFramework = false; 1945 if (Tok.is(MMToken::FrameworkKeyword)) { 1946 consumeToken(); 1947 IsFramework = true; 1948 } 1949 1950 // Parse the library name 1951 if (!Tok.is(MMToken::StringLiteral)) { 1952 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1953 << IsFramework << SourceRange(LinkLoc); 1954 HadError = true; 1955 return; 1956 } 1957 1958 std::string LibraryName = Tok.getString(); 1959 consumeToken(); 1960 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1961 IsFramework)); 1962 } 1963 1964 /// \brief Parse a configuration macro declaration. 1965 /// 1966 /// module-declaration: 1967 /// 'config_macros' attributes[opt] config-macro-list? 1968 /// 1969 /// config-macro-list: 1970 /// identifier (',' identifier)? 1971 void ModuleMapParser::parseConfigMacros() { 1972 assert(Tok.is(MMToken::ConfigMacros)); 1973 SourceLocation ConfigMacrosLoc = consumeToken(); 1974 1975 // Only top-level modules can have configuration macros. 1976 if (ActiveModule->Parent) { 1977 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 1978 } 1979 1980 // Parse the optional attributes. 1981 Attributes Attrs; 1982 parseOptionalAttributes(Attrs); 1983 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 1984 ActiveModule->ConfigMacrosExhaustive = true; 1985 } 1986 1987 // If we don't have an identifier, we're done. 1988 // FIXME: Support macros with the same name as a keyword here. 1989 if (!Tok.is(MMToken::Identifier)) 1990 return; 1991 1992 // Consume the first identifier. 1993 if (!ActiveModule->Parent) { 1994 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1995 } 1996 consumeToken(); 1997 1998 do { 1999 // If there's a comma, consume it. 2000 if (!Tok.is(MMToken::Comma)) 2001 break; 2002 consumeToken(); 2003 2004 // We expect to see a macro name here. 2005 // FIXME: Support macros with the same name as a keyword here. 2006 if (!Tok.is(MMToken::Identifier)) { 2007 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2008 break; 2009 } 2010 2011 // Consume the macro name. 2012 if (!ActiveModule->Parent) { 2013 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2014 } 2015 consumeToken(); 2016 } while (true); 2017 } 2018 2019 /// \brief Format a module-id into a string. 2020 static std::string formatModuleId(const ModuleId &Id) { 2021 std::string result; 2022 { 2023 llvm::raw_string_ostream OS(result); 2024 2025 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2026 if (I) 2027 OS << "."; 2028 OS << Id[I].first; 2029 } 2030 } 2031 2032 return result; 2033 } 2034 2035 /// \brief Parse a conflict declaration. 2036 /// 2037 /// module-declaration: 2038 /// 'conflict' module-id ',' string-literal 2039 void ModuleMapParser::parseConflict() { 2040 assert(Tok.is(MMToken::Conflict)); 2041 SourceLocation ConflictLoc = consumeToken(); 2042 Module::UnresolvedConflict Conflict; 2043 2044 // Parse the module-id. 2045 if (parseModuleId(Conflict.Id)) 2046 return; 2047 2048 // Parse the ','. 2049 if (!Tok.is(MMToken::Comma)) { 2050 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2051 << SourceRange(ConflictLoc); 2052 return; 2053 } 2054 consumeToken(); 2055 2056 // Parse the message. 2057 if (!Tok.is(MMToken::StringLiteral)) { 2058 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2059 << formatModuleId(Conflict.Id); 2060 return; 2061 } 2062 Conflict.Message = Tok.getString().str(); 2063 consumeToken(); 2064 2065 // Add this unresolved conflict. 2066 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2067 } 2068 2069 /// \brief Parse an inferred module declaration (wildcard modules). 2070 /// 2071 /// module-declaration: 2072 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2073 /// { inferred-module-member* } 2074 /// 2075 /// inferred-module-member: 2076 /// 'export' '*' 2077 /// 'exclude' identifier 2078 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2079 assert(Tok.is(MMToken::Star)); 2080 SourceLocation StarLoc = consumeToken(); 2081 bool Failed = false; 2082 2083 // Inferred modules must be submodules. 2084 if (!ActiveModule && !Framework) { 2085 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2086 Failed = true; 2087 } 2088 2089 if (ActiveModule) { 2090 // Inferred modules must have umbrella directories. 2091 if (!Failed && ActiveModule->IsAvailable && 2092 !ActiveModule->getUmbrellaDir()) { 2093 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2094 Failed = true; 2095 } 2096 2097 // Check for redefinition of an inferred module. 2098 if (!Failed && ActiveModule->InferSubmodules) { 2099 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2100 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2101 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2102 diag::note_mmap_prev_definition); 2103 Failed = true; 2104 } 2105 2106 // Check for the 'framework' keyword, which is not permitted here. 2107 if (Framework) { 2108 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2109 Framework = false; 2110 } 2111 } else if (Explicit) { 2112 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2113 Explicit = false; 2114 } 2115 2116 // If there were any problems with this inferred submodule, skip its body. 2117 if (Failed) { 2118 if (Tok.is(MMToken::LBrace)) { 2119 consumeToken(); 2120 skipUntil(MMToken::RBrace); 2121 if (Tok.is(MMToken::RBrace)) 2122 consumeToken(); 2123 } 2124 HadError = true; 2125 return; 2126 } 2127 2128 // Parse optional attributes. 2129 Attributes Attrs; 2130 parseOptionalAttributes(Attrs); 2131 2132 if (ActiveModule) { 2133 // Note that we have an inferred submodule. 2134 ActiveModule->InferSubmodules = true; 2135 ActiveModule->InferredSubmoduleLoc = StarLoc; 2136 ActiveModule->InferExplicitSubmodules = Explicit; 2137 } else { 2138 // We'll be inferring framework modules for this directory. 2139 Map.InferredDirectories[Directory].InferModules = true; 2140 Map.InferredDirectories[Directory].Attrs = Attrs; 2141 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2142 // FIXME: Handle the 'framework' keyword. 2143 } 2144 2145 // Parse the opening brace. 2146 if (!Tok.is(MMToken::LBrace)) { 2147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2148 HadError = true; 2149 return; 2150 } 2151 SourceLocation LBraceLoc = consumeToken(); 2152 2153 // Parse the body of the inferred submodule. 2154 bool Done = false; 2155 do { 2156 switch (Tok.Kind) { 2157 case MMToken::EndOfFile: 2158 case MMToken::RBrace: 2159 Done = true; 2160 break; 2161 2162 case MMToken::ExcludeKeyword: { 2163 if (ActiveModule) { 2164 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2165 << (ActiveModule != nullptr); 2166 consumeToken(); 2167 break; 2168 } 2169 2170 consumeToken(); 2171 // FIXME: Support string-literal module names here. 2172 if (!Tok.is(MMToken::Identifier)) { 2173 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2174 break; 2175 } 2176 2177 Map.InferredDirectories[Directory].ExcludedModules 2178 .push_back(Tok.getString()); 2179 consumeToken(); 2180 break; 2181 } 2182 2183 case MMToken::ExportKeyword: 2184 if (!ActiveModule) { 2185 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2186 << (ActiveModule != nullptr); 2187 consumeToken(); 2188 break; 2189 } 2190 2191 consumeToken(); 2192 if (Tok.is(MMToken::Star)) 2193 ActiveModule->InferExportWildcard = true; 2194 else 2195 Diags.Report(Tok.getLocation(), 2196 diag::err_mmap_expected_export_wildcard); 2197 consumeToken(); 2198 break; 2199 2200 case MMToken::ExplicitKeyword: 2201 case MMToken::ModuleKeyword: 2202 case MMToken::HeaderKeyword: 2203 case MMToken::PrivateKeyword: 2204 case MMToken::UmbrellaKeyword: 2205 default: 2206 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2207 << (ActiveModule != nullptr); 2208 consumeToken(); 2209 break; 2210 } 2211 } while (!Done); 2212 2213 if (Tok.is(MMToken::RBrace)) 2214 consumeToken(); 2215 else { 2216 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2217 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2218 HadError = true; 2219 } 2220 } 2221 2222 /// \brief Parse optional attributes. 2223 /// 2224 /// attributes: 2225 /// attribute attributes 2226 /// attribute 2227 /// 2228 /// attribute: 2229 /// [ identifier ] 2230 /// 2231 /// \param Attrs Will be filled in with the parsed attributes. 2232 /// 2233 /// \returns true if an error occurred, false otherwise. 2234 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2235 bool HadError = false; 2236 2237 while (Tok.is(MMToken::LSquare)) { 2238 // Consume the '['. 2239 SourceLocation LSquareLoc = consumeToken(); 2240 2241 // Check whether we have an attribute name here. 2242 if (!Tok.is(MMToken::Identifier)) { 2243 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2244 skipUntil(MMToken::RSquare); 2245 if (Tok.is(MMToken::RSquare)) 2246 consumeToken(); 2247 HadError = true; 2248 } 2249 2250 // Decode the attribute name. 2251 AttributeKind Attribute 2252 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2253 .Case("exhaustive", AT_exhaustive) 2254 .Case("extern_c", AT_extern_c) 2255 .Case("system", AT_system) 2256 .Default(AT_unknown); 2257 switch (Attribute) { 2258 case AT_unknown: 2259 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2260 << Tok.getString(); 2261 break; 2262 2263 case AT_system: 2264 Attrs.IsSystem = true; 2265 break; 2266 2267 case AT_extern_c: 2268 Attrs.IsExternC = true; 2269 break; 2270 2271 case AT_exhaustive: 2272 Attrs.IsExhaustive = true; 2273 break; 2274 } 2275 consumeToken(); 2276 2277 // Consume the ']'. 2278 if (!Tok.is(MMToken::RSquare)) { 2279 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2280 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2281 skipUntil(MMToken::RSquare); 2282 HadError = true; 2283 } 2284 2285 if (Tok.is(MMToken::RSquare)) 2286 consumeToken(); 2287 } 2288 2289 return HadError; 2290 } 2291 2292 /// \brief Parse a module map file. 2293 /// 2294 /// module-map-file: 2295 /// module-declaration* 2296 bool ModuleMapParser::parseModuleMapFile() { 2297 do { 2298 switch (Tok.Kind) { 2299 case MMToken::EndOfFile: 2300 return HadError; 2301 2302 case MMToken::ExplicitKeyword: 2303 case MMToken::ExternKeyword: 2304 case MMToken::ModuleKeyword: 2305 case MMToken::FrameworkKeyword: 2306 parseModuleDecl(); 2307 break; 2308 2309 case MMToken::Comma: 2310 case MMToken::ConfigMacros: 2311 case MMToken::Conflict: 2312 case MMToken::Exclaim: 2313 case MMToken::ExcludeKeyword: 2314 case MMToken::ExportKeyword: 2315 case MMToken::HeaderKeyword: 2316 case MMToken::Identifier: 2317 case MMToken::LBrace: 2318 case MMToken::LinkKeyword: 2319 case MMToken::LSquare: 2320 case MMToken::Period: 2321 case MMToken::PrivateKeyword: 2322 case MMToken::RBrace: 2323 case MMToken::RSquare: 2324 case MMToken::RequiresKeyword: 2325 case MMToken::Star: 2326 case MMToken::StringLiteral: 2327 case MMToken::TextualKeyword: 2328 case MMToken::UmbrellaKeyword: 2329 case MMToken::UseKeyword: 2330 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2331 HadError = true; 2332 consumeToken(); 2333 break; 2334 } 2335 } while (true); 2336 } 2337 2338 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2339 const DirectoryEntry *Dir) { 2340 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2341 = ParsedModuleMap.find(File); 2342 if (Known != ParsedModuleMap.end()) 2343 return Known->second; 2344 2345 assert(Target && "Missing target information"); 2346 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2347 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter); 2348 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2349 if (!Buffer) 2350 return ParsedModuleMap[File] = true; 2351 2352 // Parse this module map file. 2353 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 2354 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2355 BuiltinIncludeDir, IsSystem); 2356 bool Result = Parser.parseModuleMapFile(); 2357 ParsedModuleMap[File] = Result; 2358 return Result; 2359 } 2360