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