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 737 Dir(SubframeworksDirName.str(), EC), DirEnd; 738 Dir != DirEnd && !EC; Dir.increment(EC)) { 739 if (!StringRef(Dir->path()).endswith(".framework")) 740 continue; 741 742 if (const DirectoryEntry *SubframeworkDir 743 = FileMgr.getDirectory(Dir->path())) { 744 // Note: as an egregious but useful hack, we use the real path here and 745 // check whether it is actually a subdirectory of the parent directory. 746 // This will not be the case if the 'subframework' is actually a symlink 747 // out to a top-level framework. 748 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir); 749 bool FoundParent = false; 750 do { 751 // Get the parent directory name. 752 SubframeworkDirName 753 = llvm::sys::path::parent_path(SubframeworkDirName); 754 if (SubframeworkDirName.empty()) 755 break; 756 757 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) { 758 FoundParent = true; 759 break; 760 } 761 } while (true); 762 763 if (!FoundParent) 764 continue; 765 766 // FIXME: Do we want to warn about subframeworks without umbrella headers? 767 SmallString<32> NameBuf; 768 inferFrameworkModule(sanitizeFilenameAsIdentifier( 769 llvm::sys::path::stem(Dir->path()), NameBuf), 770 SubframeworkDir, Attrs, Result); 771 } 772 } 773 774 // If the module is a top-level framework, automatically link against the 775 // framework. 776 if (!Result->isSubFramework()) { 777 inferFrameworkLink(Result, FrameworkDir, FileMgr); 778 } 779 780 return Result; 781 } 782 783 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ 784 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); 785 Mod->Umbrella = UmbrellaHeader; 786 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; 787 } 788 789 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { 790 Mod->Umbrella = UmbrellaDir; 791 UmbrellaDirs[UmbrellaDir] = Mod; 792 } 793 794 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) { 795 switch ((int)Role) { 796 default: llvm_unreachable("unknown header role"); 797 case ModuleMap::NormalHeader: 798 return Module::HK_Normal; 799 case ModuleMap::PrivateHeader: 800 return Module::HK_Private; 801 case ModuleMap::TextualHeader: 802 return Module::HK_Textual; 803 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader: 804 return Module::HK_PrivateTextual; 805 } 806 } 807 808 void ModuleMap::addHeader(Module *Mod, Module::Header Header, 809 ModuleHeaderRole Role) { 810 if (!(Role & TextualHeader)) { 811 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; 812 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, 813 isCompilingModuleHeader); 814 } 815 Headers[Header.Entry].push_back(KnownHeader(Mod, Role)); 816 817 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header)); 818 } 819 820 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { 821 // Add this as a known header so we won't implicitly add it to any 822 // umbrella directory module. 823 // FIXME: Should we only exclude it from umbrella modules within the 824 // specified module? 825 (void) Headers[Header.Entry]; 826 827 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); 828 } 829 830 const FileEntry * 831 ModuleMap::getContainingModuleMapFile(const Module *Module) const { 832 if (Module->DefinitionLoc.isInvalid()) 833 return nullptr; 834 835 return SourceMgr.getFileEntryForID( 836 SourceMgr.getFileID(Module->DefinitionLoc)); 837 } 838 839 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { 840 if (M->IsInferred) { 841 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); 842 return InferredModuleAllowedBy.find(M)->second; 843 } 844 return getContainingModuleMapFile(M); 845 } 846 847 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { 848 assert(M->IsInferred && "module not inferred"); 849 InferredModuleAllowedBy[M] = ModMap; 850 } 851 852 void ModuleMap::dump() { 853 llvm::errs() << "Modules:"; 854 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 855 MEnd = Modules.end(); 856 M != MEnd; ++M) 857 M->getValue()->print(llvm::errs(), 2); 858 859 llvm::errs() << "Headers:"; 860 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end(); 861 H != HEnd; ++H) { 862 llvm::errs() << " \"" << H->first->getName() << "\" -> "; 863 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(), 864 E = H->second.end(); 865 I != E; ++I) { 866 if (I != H->second.begin()) 867 llvm::errs() << ","; 868 llvm::errs() << I->getModule()->getFullModuleName(); 869 } 870 llvm::errs() << "\n"; 871 } 872 } 873 874 bool ModuleMap::resolveExports(Module *Mod, bool Complain) { 875 bool HadError = false; 876 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { 877 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 878 Complain); 879 if (Export.getPointer() || Export.getInt()) 880 Mod->Exports.push_back(Export); 881 else 882 HadError = true; 883 } 884 Mod->UnresolvedExports.clear(); 885 return HadError; 886 } 887 888 bool ModuleMap::resolveUses(Module *Mod, bool Complain) { 889 bool HadError = false; 890 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { 891 Module *DirectUse = 892 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); 893 if (DirectUse) 894 Mod->DirectUses.push_back(DirectUse); 895 else 896 HadError = true; 897 } 898 Mod->UnresolvedDirectUses.clear(); 899 return HadError; 900 } 901 902 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { 903 bool HadError = false; 904 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { 905 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, 906 Mod, Complain); 907 if (!OtherMod) { 908 HadError = true; 909 continue; 910 } 911 912 Module::Conflict Conflict; 913 Conflict.Other = OtherMod; 914 Conflict.Message = Mod->UnresolvedConflicts[I].Message; 915 Mod->Conflicts.push_back(Conflict); 916 } 917 Mod->UnresolvedConflicts.clear(); 918 return HadError; 919 } 920 921 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { 922 if (Loc.isInvalid()) 923 return nullptr; 924 925 // Use the expansion location to determine which module we're in. 926 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); 927 if (!ExpansionLoc.isFileID()) 928 return nullptr; 929 930 const SourceManager &SrcMgr = Loc.getManager(); 931 FileID ExpansionFileID = ExpansionLoc.getFileID(); 932 933 while (const FileEntry *ExpansionFile 934 = SrcMgr.getFileEntryForID(ExpansionFileID)) { 935 // Find the module that owns this header (if any). 936 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) 937 return Mod; 938 939 // No module owns this header, so look up the inclusion chain to see if 940 // any included header has an associated module. 941 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); 942 if (IncludeLoc.isInvalid()) 943 return nullptr; 944 945 ExpansionFileID = SrcMgr.getFileID(IncludeLoc); 946 } 947 948 return nullptr; 949 } 950 951 //----------------------------------------------------------------------------// 952 // Module map file parser 953 //----------------------------------------------------------------------------// 954 955 namespace clang { 956 /// \brief A token in a module map file. 957 struct MMToken { 958 enum TokenKind { 959 Comma, 960 ConfigMacros, 961 Conflict, 962 EndOfFile, 963 HeaderKeyword, 964 Identifier, 965 Exclaim, 966 ExcludeKeyword, 967 ExplicitKeyword, 968 ExportKeyword, 969 ExternKeyword, 970 FrameworkKeyword, 971 LinkKeyword, 972 ModuleKeyword, 973 Period, 974 PrivateKeyword, 975 UmbrellaKeyword, 976 UseKeyword, 977 RequiresKeyword, 978 Star, 979 StringLiteral, 980 TextualKeyword, 981 LBrace, 982 RBrace, 983 LSquare, 984 RSquare 985 } Kind; 986 987 unsigned Location; 988 unsigned StringLength; 989 const char *StringData; 990 991 void clear() { 992 Kind = EndOfFile; 993 Location = 0; 994 StringLength = 0; 995 StringData = nullptr; 996 } 997 998 bool is(TokenKind K) const { return Kind == K; } 999 1000 SourceLocation getLocation() const { 1001 return SourceLocation::getFromRawEncoding(Location); 1002 } 1003 1004 StringRef getString() const { 1005 return StringRef(StringData, StringLength); 1006 } 1007 }; 1008 1009 class ModuleMapParser { 1010 Lexer &L; 1011 SourceManager &SourceMgr; 1012 1013 /// \brief Default target information, used only for string literal 1014 /// parsing. 1015 const TargetInfo *Target; 1016 1017 DiagnosticsEngine &Diags; 1018 ModuleMap ⤅ 1019 1020 /// \brief The current module map file. 1021 const FileEntry *ModuleMapFile; 1022 1023 /// \brief The directory that file names in this module map file should 1024 /// be resolved relative to. 1025 const DirectoryEntry *Directory; 1026 1027 /// \brief The directory containing Clang-supplied headers. 1028 const DirectoryEntry *BuiltinIncludeDir; 1029 1030 /// \brief Whether this module map is in a system header directory. 1031 bool IsSystem; 1032 1033 /// \brief Whether an error occurred. 1034 bool HadError; 1035 1036 /// \brief Stores string data for the various string literals referenced 1037 /// during parsing. 1038 llvm::BumpPtrAllocator StringData; 1039 1040 /// \brief The current token. 1041 MMToken Tok; 1042 1043 /// \brief The active module. 1044 Module *ActiveModule; 1045 1046 /// \brief Consume the current token and return its location. 1047 SourceLocation consumeToken(); 1048 1049 /// \brief Skip tokens until we reach the a token with the given kind 1050 /// (or the end of the file). 1051 void skipUntil(MMToken::TokenKind K); 1052 1053 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; 1054 bool parseModuleId(ModuleId &Id); 1055 void parseModuleDecl(); 1056 void parseExternModuleDecl(); 1057 void parseRequiresDecl(); 1058 void parseHeaderDecl(clang::MMToken::TokenKind, 1059 SourceLocation LeadingLoc); 1060 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); 1061 void parseExportDecl(); 1062 void parseUseDecl(); 1063 void parseLinkDecl(); 1064 void parseConfigMacros(); 1065 void parseConflict(); 1066 void parseInferredModuleDecl(bool Framework, bool Explicit); 1067 1068 typedef ModuleMap::Attributes Attributes; 1069 bool parseOptionalAttributes(Attributes &Attrs); 1070 1071 public: 1072 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 1073 const TargetInfo *Target, 1074 DiagnosticsEngine &Diags, 1075 ModuleMap &Map, 1076 const FileEntry *ModuleMapFile, 1077 const DirectoryEntry *Directory, 1078 const DirectoryEntry *BuiltinIncludeDir, 1079 bool IsSystem) 1080 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 1081 ModuleMapFile(ModuleMapFile), Directory(Directory), 1082 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem), 1083 HadError(false), ActiveModule(nullptr) 1084 { 1085 Tok.clear(); 1086 consumeToken(); 1087 } 1088 1089 bool parseModuleMapFile(); 1090 }; 1091 } 1092 1093 SourceLocation ModuleMapParser::consumeToken() { 1094 retry: 1095 SourceLocation Result = Tok.getLocation(); 1096 Tok.clear(); 1097 1098 Token LToken; 1099 L.LexFromRawLexer(LToken); 1100 Tok.Location = LToken.getLocation().getRawEncoding(); 1101 switch (LToken.getKind()) { 1102 case tok::raw_identifier: { 1103 StringRef RI = LToken.getRawIdentifier(); 1104 Tok.StringData = RI.data(); 1105 Tok.StringLength = RI.size(); 1106 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI) 1107 .Case("config_macros", MMToken::ConfigMacros) 1108 .Case("conflict", MMToken::Conflict) 1109 .Case("exclude", MMToken::ExcludeKeyword) 1110 .Case("explicit", MMToken::ExplicitKeyword) 1111 .Case("export", MMToken::ExportKeyword) 1112 .Case("extern", MMToken::ExternKeyword) 1113 .Case("framework", MMToken::FrameworkKeyword) 1114 .Case("header", MMToken::HeaderKeyword) 1115 .Case("link", MMToken::LinkKeyword) 1116 .Case("module", MMToken::ModuleKeyword) 1117 .Case("private", MMToken::PrivateKeyword) 1118 .Case("requires", MMToken::RequiresKeyword) 1119 .Case("textual", MMToken::TextualKeyword) 1120 .Case("umbrella", MMToken::UmbrellaKeyword) 1121 .Case("use", MMToken::UseKeyword) 1122 .Default(MMToken::Identifier); 1123 break; 1124 } 1125 1126 case tok::comma: 1127 Tok.Kind = MMToken::Comma; 1128 break; 1129 1130 case tok::eof: 1131 Tok.Kind = MMToken::EndOfFile; 1132 break; 1133 1134 case tok::l_brace: 1135 Tok.Kind = MMToken::LBrace; 1136 break; 1137 1138 case tok::l_square: 1139 Tok.Kind = MMToken::LSquare; 1140 break; 1141 1142 case tok::period: 1143 Tok.Kind = MMToken::Period; 1144 break; 1145 1146 case tok::r_brace: 1147 Tok.Kind = MMToken::RBrace; 1148 break; 1149 1150 case tok::r_square: 1151 Tok.Kind = MMToken::RSquare; 1152 break; 1153 1154 case tok::star: 1155 Tok.Kind = MMToken::Star; 1156 break; 1157 1158 case tok::exclaim: 1159 Tok.Kind = MMToken::Exclaim; 1160 break; 1161 1162 case tok::string_literal: { 1163 if (LToken.hasUDSuffix()) { 1164 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl); 1165 HadError = true; 1166 goto retry; 1167 } 1168 1169 // Parse the string literal. 1170 LangOptions LangOpts; 1171 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target); 1172 if (StringLiteral.hadError) 1173 goto retry; 1174 1175 // Copy the string literal into our string data allocator. 1176 unsigned Length = StringLiteral.GetStringLength(); 1177 char *Saved = StringData.Allocate<char>(Length + 1); 1178 memcpy(Saved, StringLiteral.GetString().data(), Length); 1179 Saved[Length] = 0; 1180 1181 // Form the token. 1182 Tok.Kind = MMToken::StringLiteral; 1183 Tok.StringData = Saved; 1184 Tok.StringLength = Length; 1185 break; 1186 } 1187 1188 case tok::comment: 1189 goto retry; 1190 1191 default: 1192 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 1193 HadError = true; 1194 goto retry; 1195 } 1196 1197 return Result; 1198 } 1199 1200 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 1201 unsigned braceDepth = 0; 1202 unsigned squareDepth = 0; 1203 do { 1204 switch (Tok.Kind) { 1205 case MMToken::EndOfFile: 1206 return; 1207 1208 case MMToken::LBrace: 1209 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1210 return; 1211 1212 ++braceDepth; 1213 break; 1214 1215 case MMToken::LSquare: 1216 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) 1217 return; 1218 1219 ++squareDepth; 1220 break; 1221 1222 case MMToken::RBrace: 1223 if (braceDepth > 0) 1224 --braceDepth; 1225 else if (Tok.is(K)) 1226 return; 1227 break; 1228 1229 case MMToken::RSquare: 1230 if (squareDepth > 0) 1231 --squareDepth; 1232 else if (Tok.is(K)) 1233 return; 1234 break; 1235 1236 default: 1237 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) 1238 return; 1239 break; 1240 } 1241 1242 consumeToken(); 1243 } while (true); 1244 } 1245 1246 /// \brief Parse a module-id. 1247 /// 1248 /// module-id: 1249 /// identifier 1250 /// identifier '.' module-id 1251 /// 1252 /// \returns true if an error occurred, false otherwise. 1253 bool ModuleMapParser::parseModuleId(ModuleId &Id) { 1254 Id.clear(); 1255 do { 1256 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) { 1257 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); 1258 consumeToken(); 1259 } else { 1260 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 1261 return true; 1262 } 1263 1264 if (!Tok.is(MMToken::Period)) 1265 break; 1266 1267 consumeToken(); 1268 } while (true); 1269 1270 return false; 1271 } 1272 1273 namespace { 1274 /// \brief Enumerates the known attributes. 1275 enum AttributeKind { 1276 /// \brief An unknown attribute. 1277 AT_unknown, 1278 /// \brief The 'system' attribute. 1279 AT_system, 1280 /// \brief The 'extern_c' attribute. 1281 AT_extern_c, 1282 /// \brief The 'exhaustive' attribute. 1283 AT_exhaustive 1284 }; 1285 } 1286 1287 /// \brief Parse a module declaration. 1288 /// 1289 /// module-declaration: 1290 /// 'extern' 'module' module-id string-literal 1291 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] 1292 /// { module-member* } 1293 /// 1294 /// module-member: 1295 /// requires-declaration 1296 /// header-declaration 1297 /// submodule-declaration 1298 /// export-declaration 1299 /// link-declaration 1300 /// 1301 /// submodule-declaration: 1302 /// module-declaration 1303 /// inferred-submodule-declaration 1304 void ModuleMapParser::parseModuleDecl() { 1305 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 1306 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword)); 1307 if (Tok.is(MMToken::ExternKeyword)) { 1308 parseExternModuleDecl(); 1309 return; 1310 } 1311 1312 // Parse 'explicit' or 'framework' keyword, if present. 1313 SourceLocation ExplicitLoc; 1314 bool Explicit = false; 1315 bool Framework = false; 1316 1317 // Parse 'explicit' keyword, if present. 1318 if (Tok.is(MMToken::ExplicitKeyword)) { 1319 ExplicitLoc = consumeToken(); 1320 Explicit = true; 1321 } 1322 1323 // Parse 'framework' keyword, if present. 1324 if (Tok.is(MMToken::FrameworkKeyword)) { 1325 consumeToken(); 1326 Framework = true; 1327 } 1328 1329 // Parse 'module' keyword. 1330 if (!Tok.is(MMToken::ModuleKeyword)) { 1331 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1332 consumeToken(); 1333 HadError = true; 1334 return; 1335 } 1336 consumeToken(); // 'module' keyword 1337 1338 // If we have a wildcard for the module name, this is an inferred submodule. 1339 // Parse it. 1340 if (Tok.is(MMToken::Star)) 1341 return parseInferredModuleDecl(Framework, Explicit); 1342 1343 // Parse the module name. 1344 ModuleId Id; 1345 if (parseModuleId(Id)) { 1346 HadError = true; 1347 return; 1348 } 1349 1350 if (ActiveModule) { 1351 if (Id.size() > 1) { 1352 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id) 1353 << SourceRange(Id.front().second, Id.back().second); 1354 1355 HadError = true; 1356 return; 1357 } 1358 } else if (Id.size() == 1 && Explicit) { 1359 // Top-level modules can't be explicit. 1360 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level); 1361 Explicit = false; 1362 ExplicitLoc = SourceLocation(); 1363 HadError = true; 1364 } 1365 1366 Module *PreviousActiveModule = ActiveModule; 1367 if (Id.size() > 1) { 1368 // This module map defines a submodule. Go find the module of which it 1369 // is a submodule. 1370 ActiveModule = nullptr; 1371 const Module *TopLevelModule = nullptr; 1372 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { 1373 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { 1374 if (I == 0) 1375 TopLevelModule = Next; 1376 ActiveModule = Next; 1377 continue; 1378 } 1379 1380 if (ActiveModule) { 1381 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) 1382 << Id[I].first 1383 << ActiveModule->getTopLevelModule()->getFullModuleName(); 1384 } else { 1385 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name); 1386 } 1387 HadError = true; 1388 return; 1389 } 1390 1391 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { 1392 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && 1393 "submodule defined in same file as 'module *' that allowed its " 1394 "top-level module"); 1395 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); 1396 } 1397 } 1398 1399 StringRef ModuleName = Id.back().first; 1400 SourceLocation ModuleNameLoc = Id.back().second; 1401 1402 // Parse the optional attribute list. 1403 Attributes Attrs; 1404 parseOptionalAttributes(Attrs); 1405 1406 // Parse the opening brace. 1407 if (!Tok.is(MMToken::LBrace)) { 1408 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 1409 << ModuleName; 1410 HadError = true; 1411 return; 1412 } 1413 SourceLocation LBraceLoc = consumeToken(); 1414 1415 // Determine whether this (sub)module has already been defined. 1416 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { 1417 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { 1418 // Skip the module definition. 1419 skipUntil(MMToken::RBrace); 1420 if (Tok.is(MMToken::RBrace)) 1421 consumeToken(); 1422 else { 1423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1424 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1425 HadError = true; 1426 } 1427 return; 1428 } 1429 1430 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 1431 << ModuleName; 1432 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); 1433 1434 // Skip the module definition. 1435 skipUntil(MMToken::RBrace); 1436 if (Tok.is(MMToken::RBrace)) 1437 consumeToken(); 1438 1439 HadError = true; 1440 return; 1441 } 1442 1443 // Start defining this module. 1444 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, 1445 Explicit).first; 1446 ActiveModule->DefinitionLoc = ModuleNameLoc; 1447 if (Attrs.IsSystem || IsSystem) 1448 ActiveModule->IsSystem = true; 1449 if (Attrs.IsExternC) 1450 ActiveModule->IsExternC = true; 1451 ActiveModule->Directory = Directory; 1452 1453 bool Done = false; 1454 do { 1455 switch (Tok.Kind) { 1456 case MMToken::EndOfFile: 1457 case MMToken::RBrace: 1458 Done = true; 1459 break; 1460 1461 case MMToken::ConfigMacros: 1462 parseConfigMacros(); 1463 break; 1464 1465 case MMToken::Conflict: 1466 parseConflict(); 1467 break; 1468 1469 case MMToken::ExplicitKeyword: 1470 case MMToken::ExternKeyword: 1471 case MMToken::FrameworkKeyword: 1472 case MMToken::ModuleKeyword: 1473 parseModuleDecl(); 1474 break; 1475 1476 case MMToken::ExportKeyword: 1477 parseExportDecl(); 1478 break; 1479 1480 case MMToken::UseKeyword: 1481 parseUseDecl(); 1482 break; 1483 1484 case MMToken::RequiresKeyword: 1485 parseRequiresDecl(); 1486 break; 1487 1488 case MMToken::TextualKeyword: 1489 parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); 1490 break; 1491 1492 case MMToken::UmbrellaKeyword: { 1493 SourceLocation UmbrellaLoc = consumeToken(); 1494 if (Tok.is(MMToken::HeaderKeyword)) 1495 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc); 1496 else 1497 parseUmbrellaDirDecl(UmbrellaLoc); 1498 break; 1499 } 1500 1501 case MMToken::ExcludeKeyword: 1502 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); 1503 break; 1504 1505 case MMToken::PrivateKeyword: 1506 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); 1507 break; 1508 1509 case MMToken::HeaderKeyword: 1510 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); 1511 break; 1512 1513 case MMToken::LinkKeyword: 1514 parseLinkDecl(); 1515 break; 1516 1517 default: 1518 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 1519 consumeToken(); 1520 break; 1521 } 1522 } while (!Done); 1523 1524 if (Tok.is(MMToken::RBrace)) 1525 consumeToken(); 1526 else { 1527 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 1528 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 1529 HadError = true; 1530 } 1531 1532 // If the active module is a top-level framework, and there are no link 1533 // libraries, automatically link against the framework. 1534 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && 1535 ActiveModule->LinkLibraries.empty()) { 1536 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); 1537 } 1538 1539 // If the module meets all requirements but is still unavailable, mark the 1540 // whole tree as unavailable to prevent it from building. 1541 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement && 1542 ActiveModule->Parent) { 1543 ActiveModule->getTopLevelModule()->markUnavailable(); 1544 ActiveModule->getTopLevelModule()->MissingHeaders.append( 1545 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end()); 1546 } 1547 1548 // We're done parsing this module. Pop back to the previous module. 1549 ActiveModule = PreviousActiveModule; 1550 } 1551 1552 /// \brief Parse an extern module declaration. 1553 /// 1554 /// extern module-declaration: 1555 /// 'extern' 'module' module-id string-literal 1556 void ModuleMapParser::parseExternModuleDecl() { 1557 assert(Tok.is(MMToken::ExternKeyword)); 1558 consumeToken(); // 'extern' keyword 1559 1560 // Parse 'module' keyword. 1561 if (!Tok.is(MMToken::ModuleKeyword)) { 1562 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 1563 consumeToken(); 1564 HadError = true; 1565 return; 1566 } 1567 consumeToken(); // 'module' keyword 1568 1569 // Parse the module name. 1570 ModuleId Id; 1571 if (parseModuleId(Id)) { 1572 HadError = true; 1573 return; 1574 } 1575 1576 // Parse the referenced module map file name. 1577 if (!Tok.is(MMToken::StringLiteral)) { 1578 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file); 1579 HadError = true; 1580 return; 1581 } 1582 std::string FileName = Tok.getString(); 1583 consumeToken(); // filename 1584 1585 StringRef FileNameRef = FileName; 1586 SmallString<128> ModuleMapFileName; 1587 if (llvm::sys::path::is_relative(FileNameRef)) { 1588 ModuleMapFileName += Directory->getName(); 1589 llvm::sys::path::append(ModuleMapFileName, FileName); 1590 FileNameRef = ModuleMapFileName.str(); 1591 } 1592 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) 1593 Map.parseModuleMapFile( 1594 File, /*IsSystem=*/false, 1595 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd 1596 ? Directory 1597 : File->getDir()); 1598 } 1599 1600 /// \brief Parse a requires declaration. 1601 /// 1602 /// requires-declaration: 1603 /// 'requires' feature-list 1604 /// 1605 /// feature-list: 1606 /// feature ',' feature-list 1607 /// feature 1608 /// 1609 /// feature: 1610 /// '!'[opt] identifier 1611 void ModuleMapParser::parseRequiresDecl() { 1612 assert(Tok.is(MMToken::RequiresKeyword)); 1613 1614 // Parse 'requires' keyword. 1615 consumeToken(); 1616 1617 // Parse the feature-list. 1618 do { 1619 bool RequiredState = true; 1620 if (Tok.is(MMToken::Exclaim)) { 1621 RequiredState = false; 1622 consumeToken(); 1623 } 1624 1625 if (!Tok.is(MMToken::Identifier)) { 1626 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature); 1627 HadError = true; 1628 return; 1629 } 1630 1631 // Consume the feature name. 1632 std::string Feature = Tok.getString(); 1633 consumeToken(); 1634 1635 // Add this feature. 1636 ActiveModule->addRequirement(Feature, RequiredState, 1637 Map.LangOpts, *Map.Target); 1638 1639 if (!Tok.is(MMToken::Comma)) 1640 break; 1641 1642 // Consume the comma. 1643 consumeToken(); 1644 } while (true); 1645 } 1646 1647 /// \brief Append to \p Paths the set of paths needed to get to the 1648 /// subframework in which the given module lives. 1649 static void appendSubframeworkPaths(Module *Mod, 1650 SmallVectorImpl<char> &Path) { 1651 // Collect the framework names from the given module to the top-level module. 1652 SmallVector<StringRef, 2> Paths; 1653 for (; Mod; Mod = Mod->Parent) { 1654 if (Mod->IsFramework) 1655 Paths.push_back(Mod->Name); 1656 } 1657 1658 if (Paths.empty()) 1659 return; 1660 1661 // Add Frameworks/Name.framework for each subframework. 1662 for (unsigned I = Paths.size() - 1; I != 0; --I) 1663 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); 1664 } 1665 1666 /// \brief Parse a header declaration. 1667 /// 1668 /// header-declaration: 1669 /// 'textual'[opt] 'header' string-literal 1670 /// 'private' 'textual'[opt] 'header' string-literal 1671 /// 'exclude' 'header' string-literal 1672 /// 'umbrella' 'header' string-literal 1673 /// 1674 /// FIXME: Support 'private textual header'. 1675 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, 1676 SourceLocation LeadingLoc) { 1677 // We've already consumed the first token. 1678 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; 1679 if (LeadingToken == MMToken::PrivateKeyword) { 1680 Role = ModuleMap::PrivateHeader; 1681 // 'private' may optionally be followed by 'textual'. 1682 if (Tok.is(MMToken::TextualKeyword)) { 1683 LeadingToken = Tok.Kind; 1684 consumeToken(); 1685 } 1686 } 1687 if (LeadingToken == MMToken::TextualKeyword) 1688 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); 1689 1690 if (LeadingToken != MMToken::HeaderKeyword) { 1691 if (!Tok.is(MMToken::HeaderKeyword)) { 1692 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1693 << (LeadingToken == MMToken::PrivateKeyword ? "private" : 1694 LeadingToken == MMToken::ExcludeKeyword ? "exclude" : 1695 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); 1696 return; 1697 } 1698 consumeToken(); 1699 } 1700 1701 // Parse the header name. 1702 if (!Tok.is(MMToken::StringLiteral)) { 1703 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1704 << "header"; 1705 HadError = true; 1706 return; 1707 } 1708 Module::UnresolvedHeaderDirective Header; 1709 Header.FileName = Tok.getString(); 1710 Header.FileNameLoc = consumeToken(); 1711 1712 // Check whether we already have an umbrella. 1713 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { 1714 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) 1715 << ActiveModule->getFullModuleName(); 1716 HadError = true; 1717 return; 1718 } 1719 1720 // Look for this file. 1721 const FileEntry *File = nullptr; 1722 const FileEntry *BuiltinFile = nullptr; 1723 SmallString<128> RelativePathName; 1724 if (llvm::sys::path::is_absolute(Header.FileName)) { 1725 RelativePathName = Header.FileName; 1726 File = SourceMgr.getFileManager().getFile(RelativePathName); 1727 } else { 1728 // Search for the header file within the search directory. 1729 SmallString<128> FullPathName(Directory->getName()); 1730 unsigned FullPathLength = FullPathName.size(); 1731 1732 if (ActiveModule->isPartOfFramework()) { 1733 appendSubframeworkPaths(ActiveModule, RelativePathName); 1734 1735 // Check whether this file is in the public headers. 1736 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); 1737 llvm::sys::path::append(FullPathName, RelativePathName.str()); 1738 File = SourceMgr.getFileManager().getFile(FullPathName); 1739 1740 if (!File) { 1741 // Check whether this file is in the private headers. 1742 // FIXME: Should we retain the subframework paths here? 1743 RelativePathName.clear(); 1744 FullPathName.resize(FullPathLength); 1745 llvm::sys::path::append(RelativePathName, "PrivateHeaders", 1746 Header.FileName); 1747 llvm::sys::path::append(FullPathName, RelativePathName.str()); 1748 File = SourceMgr.getFileManager().getFile(FullPathName); 1749 } 1750 } else { 1751 // Lookup for normal headers. 1752 llvm::sys::path::append(RelativePathName, Header.FileName); 1753 llvm::sys::path::append(FullPathName, RelativePathName.str()); 1754 File = SourceMgr.getFileManager().getFile(FullPathName); 1755 1756 // If this is a system module with a top-level header, this header 1757 // may have a counterpart (or replacement) in the set of headers 1758 // supplied by Clang. Find that builtin header. 1759 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && 1760 BuiltinIncludeDir && BuiltinIncludeDir != Directory && 1761 isBuiltinHeader(Header.FileName)) { 1762 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); 1763 llvm::sys::path::append(BuiltinPathName, Header.FileName); 1764 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); 1765 1766 // If Clang supplies this header but the underlying system does not, 1767 // just silently swap in our builtin version. Otherwise, we'll end 1768 // up adding both (later). 1769 if (!File && BuiltinFile) { 1770 File = BuiltinFile; 1771 RelativePathName = BuiltinPathName; 1772 BuiltinFile = nullptr; 1773 } 1774 } 1775 } 1776 } 1777 1778 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 1779 // Come up with a lazy way to do this. 1780 if (File) { 1781 if (LeadingToken == MMToken::UmbrellaKeyword) { 1782 const DirectoryEntry *UmbrellaDir = File->getDir(); 1783 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { 1784 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) 1785 << UmbrellaModule->getFullModuleName(); 1786 HadError = true; 1787 } else { 1788 // Record this umbrella header. 1789 Map.setUmbrellaHeader(ActiveModule, File); 1790 } 1791 } else if (LeadingToken == MMToken::ExcludeKeyword) { 1792 Module::Header H = {RelativePathName.str(), File}; 1793 Map.excludeHeader(ActiveModule, H); 1794 } else { 1795 // If there is a builtin counterpart to this file, add it now, before 1796 // the "real" header, so we build the built-in one first when building 1797 // the module. 1798 if (BuiltinFile) { 1799 // FIXME: Taking the name from the FileEntry is unstable and can give 1800 // different results depending on how we've previously named that file 1801 // in this build. 1802 Module::Header H = { BuiltinFile->getName(), BuiltinFile }; 1803 Map.addHeader(ActiveModule, H, Role); 1804 } 1805 1806 // Record this header. 1807 Module::Header H = { RelativePathName.str(), File }; 1808 Map.addHeader(ActiveModule, H, Role); 1809 } 1810 } else if (LeadingToken != MMToken::ExcludeKeyword) { 1811 // Ignore excluded header files. They're optional anyway. 1812 1813 // If we find a module that has a missing header, we mark this module as 1814 // unavailable and store the header directive for displaying diagnostics. 1815 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; 1816 ActiveModule->markUnavailable(); 1817 ActiveModule->MissingHeaders.push_back(Header); 1818 } 1819 } 1820 1821 /// \brief Parse an umbrella directory declaration. 1822 /// 1823 /// umbrella-dir-declaration: 1824 /// umbrella string-literal 1825 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { 1826 // Parse the directory name. 1827 if (!Tok.is(MMToken::StringLiteral)) { 1828 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 1829 << "umbrella"; 1830 HadError = true; 1831 return; 1832 } 1833 1834 std::string DirName = Tok.getString(); 1835 SourceLocation DirNameLoc = consumeToken(); 1836 1837 // Check whether we already have an umbrella. 1838 if (ActiveModule->Umbrella) { 1839 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash) 1840 << ActiveModule->getFullModuleName(); 1841 HadError = true; 1842 return; 1843 } 1844 1845 // Look for this file. 1846 const DirectoryEntry *Dir = nullptr; 1847 if (llvm::sys::path::is_absolute(DirName)) 1848 Dir = SourceMgr.getFileManager().getDirectory(DirName); 1849 else { 1850 SmallString<128> PathName; 1851 PathName = Directory->getName(); 1852 llvm::sys::path::append(PathName, DirName); 1853 Dir = SourceMgr.getFileManager().getDirectory(PathName); 1854 } 1855 1856 if (!Dir) { 1857 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) 1858 << DirName; 1859 HadError = true; 1860 return; 1861 } 1862 1863 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) { 1864 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 1865 << OwningModule->getFullModuleName(); 1866 HadError = true; 1867 return; 1868 } 1869 1870 // Record this umbrella directory. 1871 Map.setUmbrellaDir(ActiveModule, Dir); 1872 } 1873 1874 /// \brief Parse a module export declaration. 1875 /// 1876 /// export-declaration: 1877 /// 'export' wildcard-module-id 1878 /// 1879 /// wildcard-module-id: 1880 /// identifier 1881 /// '*' 1882 /// identifier '.' wildcard-module-id 1883 void ModuleMapParser::parseExportDecl() { 1884 assert(Tok.is(MMToken::ExportKeyword)); 1885 SourceLocation ExportLoc = consumeToken(); 1886 1887 // Parse the module-id with an optional wildcard at the end. 1888 ModuleId ParsedModuleId; 1889 bool Wildcard = false; 1890 do { 1891 // FIXME: Support string-literal module names here. 1892 if (Tok.is(MMToken::Identifier)) { 1893 ParsedModuleId.push_back(std::make_pair(Tok.getString(), 1894 Tok.getLocation())); 1895 consumeToken(); 1896 1897 if (Tok.is(MMToken::Period)) { 1898 consumeToken(); 1899 continue; 1900 } 1901 1902 break; 1903 } 1904 1905 if(Tok.is(MMToken::Star)) { 1906 Wildcard = true; 1907 consumeToken(); 1908 break; 1909 } 1910 1911 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); 1912 HadError = true; 1913 return; 1914 } while (true); 1915 1916 Module::UnresolvedExportDecl Unresolved = { 1917 ExportLoc, ParsedModuleId, Wildcard 1918 }; 1919 ActiveModule->UnresolvedExports.push_back(Unresolved); 1920 } 1921 1922 /// \brief Parse a module uses declaration. 1923 /// 1924 /// uses-declaration: 1925 /// 'uses' wildcard-module-id 1926 void ModuleMapParser::parseUseDecl() { 1927 assert(Tok.is(MMToken::UseKeyword)); 1928 consumeToken(); 1929 // Parse the module-id. 1930 ModuleId ParsedModuleId; 1931 parseModuleId(ParsedModuleId); 1932 1933 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); 1934 } 1935 1936 /// \brief Parse a link declaration. 1937 /// 1938 /// module-declaration: 1939 /// 'link' 'framework'[opt] string-literal 1940 void ModuleMapParser::parseLinkDecl() { 1941 assert(Tok.is(MMToken::LinkKeyword)); 1942 SourceLocation LinkLoc = consumeToken(); 1943 1944 // Parse the optional 'framework' keyword. 1945 bool IsFramework = false; 1946 if (Tok.is(MMToken::FrameworkKeyword)) { 1947 consumeToken(); 1948 IsFramework = true; 1949 } 1950 1951 // Parse the library name 1952 if (!Tok.is(MMToken::StringLiteral)) { 1953 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name) 1954 << IsFramework << SourceRange(LinkLoc); 1955 HadError = true; 1956 return; 1957 } 1958 1959 std::string LibraryName = Tok.getString(); 1960 consumeToken(); 1961 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName, 1962 IsFramework)); 1963 } 1964 1965 /// \brief Parse a configuration macro declaration. 1966 /// 1967 /// module-declaration: 1968 /// 'config_macros' attributes[opt] config-macro-list? 1969 /// 1970 /// config-macro-list: 1971 /// identifier (',' identifier)? 1972 void ModuleMapParser::parseConfigMacros() { 1973 assert(Tok.is(MMToken::ConfigMacros)); 1974 SourceLocation ConfigMacrosLoc = consumeToken(); 1975 1976 // Only top-level modules can have configuration macros. 1977 if (ActiveModule->Parent) { 1978 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule); 1979 } 1980 1981 // Parse the optional attributes. 1982 Attributes Attrs; 1983 parseOptionalAttributes(Attrs); 1984 if (Attrs.IsExhaustive && !ActiveModule->Parent) { 1985 ActiveModule->ConfigMacrosExhaustive = true; 1986 } 1987 1988 // If we don't have an identifier, we're done. 1989 // FIXME: Support macros with the same name as a keyword here. 1990 if (!Tok.is(MMToken::Identifier)) 1991 return; 1992 1993 // Consume the first identifier. 1994 if (!ActiveModule->Parent) { 1995 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 1996 } 1997 consumeToken(); 1998 1999 do { 2000 // If there's a comma, consume it. 2001 if (!Tok.is(MMToken::Comma)) 2002 break; 2003 consumeToken(); 2004 2005 // We expect to see a macro name here. 2006 // FIXME: Support macros with the same name as a keyword here. 2007 if (!Tok.is(MMToken::Identifier)) { 2008 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); 2009 break; 2010 } 2011 2012 // Consume the macro name. 2013 if (!ActiveModule->Parent) { 2014 ActiveModule->ConfigMacros.push_back(Tok.getString().str()); 2015 } 2016 consumeToken(); 2017 } while (true); 2018 } 2019 2020 /// \brief Format a module-id into a string. 2021 static std::string formatModuleId(const ModuleId &Id) { 2022 std::string result; 2023 { 2024 llvm::raw_string_ostream OS(result); 2025 2026 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 2027 if (I) 2028 OS << "."; 2029 OS << Id[I].first; 2030 } 2031 } 2032 2033 return result; 2034 } 2035 2036 /// \brief Parse a conflict declaration. 2037 /// 2038 /// module-declaration: 2039 /// 'conflict' module-id ',' string-literal 2040 void ModuleMapParser::parseConflict() { 2041 assert(Tok.is(MMToken::Conflict)); 2042 SourceLocation ConflictLoc = consumeToken(); 2043 Module::UnresolvedConflict Conflict; 2044 2045 // Parse the module-id. 2046 if (parseModuleId(Conflict.Id)) 2047 return; 2048 2049 // Parse the ','. 2050 if (!Tok.is(MMToken::Comma)) { 2051 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma) 2052 << SourceRange(ConflictLoc); 2053 return; 2054 } 2055 consumeToken(); 2056 2057 // Parse the message. 2058 if (!Tok.is(MMToken::StringLiteral)) { 2059 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message) 2060 << formatModuleId(Conflict.Id); 2061 return; 2062 } 2063 Conflict.Message = Tok.getString().str(); 2064 consumeToken(); 2065 2066 // Add this unresolved conflict. 2067 ActiveModule->UnresolvedConflicts.push_back(Conflict); 2068 } 2069 2070 /// \brief Parse an inferred module declaration (wildcard modules). 2071 /// 2072 /// module-declaration: 2073 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt] 2074 /// { inferred-module-member* } 2075 /// 2076 /// inferred-module-member: 2077 /// 'export' '*' 2078 /// 'exclude' identifier 2079 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { 2080 assert(Tok.is(MMToken::Star)); 2081 SourceLocation StarLoc = consumeToken(); 2082 bool Failed = false; 2083 2084 // Inferred modules must be submodules. 2085 if (!ActiveModule && !Framework) { 2086 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule); 2087 Failed = true; 2088 } 2089 2090 if (ActiveModule) { 2091 // Inferred modules must have umbrella directories. 2092 if (!Failed && ActiveModule->IsAvailable && 2093 !ActiveModule->getUmbrellaDir()) { 2094 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella); 2095 Failed = true; 2096 } 2097 2098 // Check for redefinition of an inferred module. 2099 if (!Failed && ActiveModule->InferSubmodules) { 2100 Diags.Report(StarLoc, diag::err_mmap_inferred_redef); 2101 if (ActiveModule->InferredSubmoduleLoc.isValid()) 2102 Diags.Report(ActiveModule->InferredSubmoduleLoc, 2103 diag::note_mmap_prev_definition); 2104 Failed = true; 2105 } 2106 2107 // Check for the 'framework' keyword, which is not permitted here. 2108 if (Framework) { 2109 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule); 2110 Framework = false; 2111 } 2112 } else if (Explicit) { 2113 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework); 2114 Explicit = false; 2115 } 2116 2117 // If there were any problems with this inferred submodule, skip its body. 2118 if (Failed) { 2119 if (Tok.is(MMToken::LBrace)) { 2120 consumeToken(); 2121 skipUntil(MMToken::RBrace); 2122 if (Tok.is(MMToken::RBrace)) 2123 consumeToken(); 2124 } 2125 HadError = true; 2126 return; 2127 } 2128 2129 // Parse optional attributes. 2130 Attributes Attrs; 2131 parseOptionalAttributes(Attrs); 2132 2133 if (ActiveModule) { 2134 // Note that we have an inferred submodule. 2135 ActiveModule->InferSubmodules = true; 2136 ActiveModule->InferredSubmoduleLoc = StarLoc; 2137 ActiveModule->InferExplicitSubmodules = Explicit; 2138 } else { 2139 // We'll be inferring framework modules for this directory. 2140 Map.InferredDirectories[Directory].InferModules = true; 2141 Map.InferredDirectories[Directory].Attrs = Attrs; 2142 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; 2143 // FIXME: Handle the 'framework' keyword. 2144 } 2145 2146 // Parse the opening brace. 2147 if (!Tok.is(MMToken::LBrace)) { 2148 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard); 2149 HadError = true; 2150 return; 2151 } 2152 SourceLocation LBraceLoc = consumeToken(); 2153 2154 // Parse the body of the inferred submodule. 2155 bool Done = false; 2156 do { 2157 switch (Tok.Kind) { 2158 case MMToken::EndOfFile: 2159 case MMToken::RBrace: 2160 Done = true; 2161 break; 2162 2163 case MMToken::ExcludeKeyword: { 2164 if (ActiveModule) { 2165 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2166 << (ActiveModule != nullptr); 2167 consumeToken(); 2168 break; 2169 } 2170 2171 consumeToken(); 2172 // FIXME: Support string-literal module names here. 2173 if (!Tok.is(MMToken::Identifier)) { 2174 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); 2175 break; 2176 } 2177 2178 Map.InferredDirectories[Directory].ExcludedModules 2179 .push_back(Tok.getString()); 2180 consumeToken(); 2181 break; 2182 } 2183 2184 case MMToken::ExportKeyword: 2185 if (!ActiveModule) { 2186 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2187 << (ActiveModule != nullptr); 2188 consumeToken(); 2189 break; 2190 } 2191 2192 consumeToken(); 2193 if (Tok.is(MMToken::Star)) 2194 ActiveModule->InferExportWildcard = true; 2195 else 2196 Diags.Report(Tok.getLocation(), 2197 diag::err_mmap_expected_export_wildcard); 2198 consumeToken(); 2199 break; 2200 2201 case MMToken::ExplicitKeyword: 2202 case MMToken::ModuleKeyword: 2203 case MMToken::HeaderKeyword: 2204 case MMToken::PrivateKeyword: 2205 case MMToken::UmbrellaKeyword: 2206 default: 2207 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) 2208 << (ActiveModule != nullptr); 2209 consumeToken(); 2210 break; 2211 } 2212 } while (!Done); 2213 2214 if (Tok.is(MMToken::RBrace)) 2215 consumeToken(); 2216 else { 2217 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 2218 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 2219 HadError = true; 2220 } 2221 } 2222 2223 /// \brief Parse optional attributes. 2224 /// 2225 /// attributes: 2226 /// attribute attributes 2227 /// attribute 2228 /// 2229 /// attribute: 2230 /// [ identifier ] 2231 /// 2232 /// \param Attrs Will be filled in with the parsed attributes. 2233 /// 2234 /// \returns true if an error occurred, false otherwise. 2235 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) { 2236 bool HadError = false; 2237 2238 while (Tok.is(MMToken::LSquare)) { 2239 // Consume the '['. 2240 SourceLocation LSquareLoc = consumeToken(); 2241 2242 // Check whether we have an attribute name here. 2243 if (!Tok.is(MMToken::Identifier)) { 2244 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); 2245 skipUntil(MMToken::RSquare); 2246 if (Tok.is(MMToken::RSquare)) 2247 consumeToken(); 2248 HadError = true; 2249 } 2250 2251 // Decode the attribute name. 2252 AttributeKind Attribute 2253 = llvm::StringSwitch<AttributeKind>(Tok.getString()) 2254 .Case("exhaustive", AT_exhaustive) 2255 .Case("extern_c", AT_extern_c) 2256 .Case("system", AT_system) 2257 .Default(AT_unknown); 2258 switch (Attribute) { 2259 case AT_unknown: 2260 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) 2261 << Tok.getString(); 2262 break; 2263 2264 case AT_system: 2265 Attrs.IsSystem = true; 2266 break; 2267 2268 case AT_extern_c: 2269 Attrs.IsExternC = true; 2270 break; 2271 2272 case AT_exhaustive: 2273 Attrs.IsExhaustive = true; 2274 break; 2275 } 2276 consumeToken(); 2277 2278 // Consume the ']'. 2279 if (!Tok.is(MMToken::RSquare)) { 2280 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); 2281 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); 2282 skipUntil(MMToken::RSquare); 2283 HadError = true; 2284 } 2285 2286 if (Tok.is(MMToken::RSquare)) 2287 consumeToken(); 2288 } 2289 2290 return HadError; 2291 } 2292 2293 /// \brief Parse a module map file. 2294 /// 2295 /// module-map-file: 2296 /// module-declaration* 2297 bool ModuleMapParser::parseModuleMapFile() { 2298 do { 2299 switch (Tok.Kind) { 2300 case MMToken::EndOfFile: 2301 return HadError; 2302 2303 case MMToken::ExplicitKeyword: 2304 case MMToken::ExternKeyword: 2305 case MMToken::ModuleKeyword: 2306 case MMToken::FrameworkKeyword: 2307 parseModuleDecl(); 2308 break; 2309 2310 case MMToken::Comma: 2311 case MMToken::ConfigMacros: 2312 case MMToken::Conflict: 2313 case MMToken::Exclaim: 2314 case MMToken::ExcludeKeyword: 2315 case MMToken::ExportKeyword: 2316 case MMToken::HeaderKeyword: 2317 case MMToken::Identifier: 2318 case MMToken::LBrace: 2319 case MMToken::LinkKeyword: 2320 case MMToken::LSquare: 2321 case MMToken::Period: 2322 case MMToken::PrivateKeyword: 2323 case MMToken::RBrace: 2324 case MMToken::RSquare: 2325 case MMToken::RequiresKeyword: 2326 case MMToken::Star: 2327 case MMToken::StringLiteral: 2328 case MMToken::TextualKeyword: 2329 case MMToken::UmbrellaKeyword: 2330 case MMToken::UseKeyword: 2331 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 2332 HadError = true; 2333 consumeToken(); 2334 break; 2335 } 2336 } while (true); 2337 } 2338 2339 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, 2340 const DirectoryEntry *Dir) { 2341 llvm::DenseMap<const FileEntry *, bool>::iterator Known 2342 = ParsedModuleMap.find(File); 2343 if (Known != ParsedModuleMap.end()) 2344 return Known->second; 2345 2346 assert(Target && "Missing target information"); 2347 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; 2348 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter); 2349 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); 2350 if (!Buffer) 2351 return ParsedModuleMap[File] = true; 2352 2353 // Parse this module map file. 2354 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); 2355 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, 2356 BuiltinIncludeDir, IsSystem); 2357 bool Result = Parser.parseModuleMapFile(); 2358 ParsedModuleMap[File] = Result; 2359 return Result; 2360 } 2361