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/Lex/Lexer.h" 16 #include "clang/Lex/LiteralSupport.h" 17 #include "clang/Lex/LexDiagnostic.h" 18 #include "clang/Basic/Diagnostic.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/TargetInfo.h" 21 #include "clang/Basic/TargetOptions.h" 22 #include "llvm/Support/Allocator.h" 23 #include "llvm/Support/Host.h" 24 #include "llvm/Support/PathV2.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/ADT/StringSwitch.h" 28 using namespace clang; 29 30 //----------------------------------------------------------------------------// 31 // Module 32 //----------------------------------------------------------------------------// 33 34 ModuleMap::Module::~Module() { 35 for (llvm::StringMap<Module *>::iterator I = SubModules.begin(), 36 IEnd = SubModules.end(); 37 I != IEnd; ++I) { 38 delete I->getValue(); 39 } 40 41 } 42 43 std::string ModuleMap::Module::getFullModuleName() const { 44 llvm::SmallVector<StringRef, 2> Names; 45 46 // Build up the set of module names (from innermost to outermost). 47 for (const Module *M = this; M; M = M->Parent) 48 Names.push_back(M->Name); 49 50 std::string Result; 51 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 52 IEnd = Names.rend(); 53 I != IEnd; ++I) { 54 if (!Result.empty()) 55 Result += '.'; 56 57 Result += *I; 58 } 59 60 return Result; 61 } 62 63 StringRef ModuleMap::Module::getTopLevelModuleName() const { 64 const Module *Top = this; 65 while (Top->Parent) 66 Top = Top->Parent; 67 68 return Top->Name; 69 } 70 71 static void indent(llvm::raw_ostream &OS, unsigned Spaces) { 72 OS << std::string(' ', Spaces); 73 } 74 75 void ModuleMap::Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 76 indent(OS, Indent); 77 if (IsFramework) 78 OS << "framework "; 79 if (IsExplicit) 80 OS << "explicit "; 81 OS << Name << " {\n"; 82 83 if (UmbrellaHeader) { 84 indent(OS, Indent + 2); 85 OS << "umbrella \"" << UmbrellaHeader->getName() << "\"\n"; 86 } 87 88 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 89 indent(OS, Indent + 2); 90 OS << "header \"" << Headers[I]->getName() << "\"\n"; 91 } 92 93 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(), 94 MIEnd = SubModules.end(); 95 MI != MIEnd; ++MI) 96 MI->getValue()->print(OS, Indent + 2); 97 98 indent(OS, Indent); 99 OS << "}\n"; 100 } 101 102 void ModuleMap::Module::dump() const { 103 print(llvm::errs()); 104 } 105 106 //----------------------------------------------------------------------------// 107 // Module map 108 //----------------------------------------------------------------------------// 109 110 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) { 111 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs); 112 Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>( 113 new DiagnosticsEngine(DiagIDs)); 114 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true); 115 SourceMgr = new SourceManager(*Diags, FileMgr); 116 } 117 118 ModuleMap::~ModuleMap() { 119 for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 120 IEnd = Modules.end(); 121 I != IEnd; ++I) { 122 delete I->getValue(); 123 } 124 125 delete SourceMgr; 126 } 127 128 ModuleMap::Module *ModuleMap::findModuleForHeader(const FileEntry *File) { 129 llvm::DenseMap<const FileEntry *, Module *>::iterator Known 130 = Headers.find(File); 131 if (Known != Headers.end()) 132 return Known->second; 133 134 const DirectoryEntry *Dir = File->getDir(); 135 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir 136 = UmbrellaDirs.find(Dir); 137 if (KnownDir != UmbrellaDirs.end()) 138 return KnownDir->second; 139 140 // Walk up the directory hierarchy looking for umbrella headers. 141 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs; 142 StringRef DirName = Dir->getName(); 143 do { 144 // Retrieve our parent path. 145 DirName = llvm::sys::path::parent_path(DirName); 146 if (DirName.empty()) 147 break; 148 149 // Resolve the parent path to a directory entry. 150 Dir = SourceMgr->getFileManager().getDirectory(DirName); 151 if (!Dir) 152 break; 153 154 KnownDir = UmbrellaDirs.find(Dir); 155 if (KnownDir != UmbrellaDirs.end()) { 156 Module *Result = KnownDir->second; 157 158 // Record each of the directories we stepped through as being part of 159 // the module we found, since the umbrella header covers them all. 160 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I) 161 UmbrellaDirs[SkippedDirs[I]] = Result; 162 163 return Result; 164 } 165 166 SkippedDirs.push_back(Dir); 167 } while (true); 168 169 return 0; 170 } 171 172 ModuleMap::Module *ModuleMap::findModule(StringRef Name) { 173 llvm::StringMap<Module *>::iterator Known = Modules.find(Name); 174 if (Known != Modules.end()) 175 return Known->getValue(); 176 177 return 0; 178 } 179 180 ModuleMap::Module * 181 ModuleMap::inferFrameworkModule(StringRef ModuleName, 182 const DirectoryEntry *FrameworkDir) { 183 // Check whether we've already found this module. 184 if (Module *Module = findModule(ModuleName)) 185 return Module; 186 187 // Look for an umbrella header. 188 llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName()); 189 llvm::sys::path::append(UmbrellaName, "Headers"); 190 llvm::sys::path::append(UmbrellaName, ModuleName + ".h"); 191 const FileEntry *UmbrellaHeader 192 = SourceMgr->getFileManager().getFile(UmbrellaName); 193 194 // FIXME: If there's no umbrella header, we could probably scan the 195 // framework to load *everything*. But, it's not clear that this is a good 196 // idea. 197 if (!UmbrellaHeader) 198 return 0; 199 200 Module *Result = new Module(ModuleName, SourceLocation(), 201 /*IsFramework=*/true); 202 Result->UmbrellaHeader = UmbrellaHeader; 203 Headers[UmbrellaHeader] = Result; 204 UmbrellaDirs[FrameworkDir] = Result; 205 Modules[ModuleName] = Result; 206 return Result; 207 } 208 209 void ModuleMap::dump() { 210 llvm::errs() << "Modules:"; 211 for (llvm::StringMap<Module *>::iterator M = Modules.begin(), 212 MEnd = Modules.end(); 213 M != MEnd; ++M) 214 M->getValue()->print(llvm::errs(), 2); 215 216 llvm::errs() << "Headers:"; 217 for (llvm::DenseMap<const FileEntry *, Module *>::iterator 218 H = Headers.begin(), 219 HEnd = Headers.end(); 220 H != HEnd; ++H) { 221 llvm::errs() << " \"" << H->first->getName() << "\" -> " 222 << H->second->getFullModuleName() << "\n"; 223 } 224 } 225 226 //----------------------------------------------------------------------------// 227 // Module map file parser 228 //----------------------------------------------------------------------------// 229 230 namespace clang { 231 /// \brief A token in a module map file. 232 struct MMToken { 233 enum TokenKind { 234 EndOfFile, 235 HeaderKeyword, 236 Identifier, 237 ExplicitKeyword, 238 FrameworkKeyword, 239 ModuleKeyword, 240 UmbrellaKeyword, 241 StringLiteral, 242 LBrace, 243 RBrace 244 } Kind; 245 246 unsigned Location; 247 unsigned StringLength; 248 const char *StringData; 249 250 void clear() { 251 Kind = EndOfFile; 252 Location = 0; 253 StringLength = 0; 254 StringData = 0; 255 } 256 257 bool is(TokenKind K) const { return Kind == K; } 258 259 SourceLocation getLocation() const { 260 return SourceLocation::getFromRawEncoding(Location); 261 } 262 263 StringRef getString() const { 264 return StringRef(StringData, StringLength); 265 } 266 }; 267 268 class ModuleMapParser { 269 Lexer &L; 270 SourceManager &SourceMgr; 271 DiagnosticsEngine &Diags; 272 ModuleMap ⤅ 273 274 /// \brief The directory that this module map resides in. 275 const DirectoryEntry *Directory; 276 277 /// \brief Whether an error occurred. 278 bool HadError; 279 280 /// \brief Default target information, used only for string literal 281 /// parsing. 282 TargetInfo *Target; 283 284 /// \brief Stores string data for the various string literals referenced 285 /// during parsing. 286 llvm::BumpPtrAllocator StringData; 287 288 /// \brief The current token. 289 MMToken Tok; 290 291 /// \brief The active module. 292 ModuleMap::Module *ActiveModule; 293 294 /// \brief Consume the current token and return its location. 295 SourceLocation consumeToken(); 296 297 /// \brief Skip tokens until we reach the a token with the given kind 298 /// (or the end of the file). 299 void skipUntil(MMToken::TokenKind K); 300 301 void parseModuleDecl(); 302 void parseUmbrellaDecl(); 303 void parseHeaderDecl(); 304 305 public: 306 typedef ModuleMap::Module Module; 307 308 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 309 DiagnosticsEngine &Diags, 310 ModuleMap &Map, 311 const DirectoryEntry *Directory) 312 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 313 Directory(Directory), HadError(false), ActiveModule(0) 314 { 315 TargetOptions TargetOpts; 316 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 317 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 318 319 Tok.clear(); 320 consumeToken(); 321 } 322 323 bool parseModuleMapFile(); 324 }; 325 } 326 327 SourceLocation ModuleMapParser::consumeToken() { 328 retry: 329 SourceLocation Result = Tok.getLocation(); 330 Tok.clear(); 331 332 Token LToken; 333 L.LexFromRawLexer(LToken); 334 Tok.Location = LToken.getLocation().getRawEncoding(); 335 switch (LToken.getKind()) { 336 case tok::raw_identifier: 337 Tok.StringData = LToken.getRawIdentifierData(); 338 Tok.StringLength = LToken.getLength(); 339 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 340 .Case("header", MMToken::HeaderKeyword) 341 .Case("explicit", MMToken::ExplicitKeyword) 342 .Case("framework", MMToken::FrameworkKeyword) 343 .Case("module", MMToken::ModuleKeyword) 344 .Case("umbrella", MMToken::UmbrellaKeyword) 345 .Default(MMToken::Identifier); 346 break; 347 348 case tok::eof: 349 Tok.Kind = MMToken::EndOfFile; 350 break; 351 352 case tok::l_brace: 353 Tok.Kind = MMToken::LBrace; 354 break; 355 356 case tok::r_brace: 357 Tok.Kind = MMToken::RBrace; 358 break; 359 360 case tok::string_literal: { 361 // Parse the string literal. 362 LangOptions LangOpts; 363 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 364 if (StringLiteral.hadError) 365 goto retry; 366 367 // Copy the string literal into our string data allocator. 368 unsigned Length = StringLiteral.GetStringLength(); 369 char *Saved = StringData.Allocate<char>(Length + 1); 370 memcpy(Saved, StringLiteral.GetString().data(), Length); 371 Saved[Length] = 0; 372 373 // Form the token. 374 Tok.Kind = MMToken::StringLiteral; 375 Tok.StringData = Saved; 376 Tok.StringLength = Length; 377 break; 378 } 379 380 case tok::comment: 381 goto retry; 382 383 default: 384 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 385 HadError = true; 386 goto retry; 387 } 388 389 return Result; 390 } 391 392 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 393 unsigned braceDepth = 0; 394 do { 395 switch (Tok.Kind) { 396 case MMToken::EndOfFile: 397 return; 398 399 case MMToken::LBrace: 400 if (Tok.is(K) && braceDepth == 0) 401 return; 402 403 ++braceDepth; 404 break; 405 406 case MMToken::RBrace: 407 if (braceDepth > 0) 408 --braceDepth; 409 else if (Tok.is(K)) 410 return; 411 break; 412 413 default: 414 if (braceDepth == 0 && Tok.is(K)) 415 return; 416 break; 417 } 418 419 consumeToken(); 420 } while (true); 421 } 422 423 /// \brief Parse a module declaration. 424 /// 425 /// module-declaration: 426 /// 'framework'[opt] 'module' identifier { module-member* } 427 /// 428 /// module-member: 429 /// umbrella-declaration 430 /// header-declaration 431 /// 'explicit'[opt] module-declaration 432 void ModuleMapParser::parseModuleDecl() { 433 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 434 Tok.is(MMToken::FrameworkKeyword)); 435 436 // Parse 'framework' or 'explicit' keyword, if present. 437 bool Framework = false; 438 bool Explicit = false; 439 440 if (Tok.is(MMToken::FrameworkKeyword)) { 441 consumeToken(); 442 Framework = true; 443 } 444 // Parse 'explicit' keyword, if present. 445 else if (Tok.is(MMToken::ExplicitKeyword)) { 446 consumeToken(); 447 Explicit = true; 448 } 449 450 // Parse 'module' keyword. 451 if (!Tok.is(MMToken::ModuleKeyword)) { 452 Diags.Report(Tok.getLocation(), 453 diag::err_mmap_expected_module_after_explicit); 454 consumeToken(); 455 HadError = true; 456 return; 457 } 458 consumeToken(); // 'module' keyword 459 460 // Parse the module name. 461 if (!Tok.is(MMToken::Identifier)) { 462 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 463 HadError = true; 464 return; 465 } 466 StringRef ModuleName = Tok.getString(); 467 SourceLocation ModuleNameLoc = consumeToken(); 468 469 // Parse the opening brace. 470 if (!Tok.is(MMToken::LBrace)) { 471 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 472 << ModuleName; 473 HadError = true; 474 return; 475 } 476 SourceLocation LBraceLoc = consumeToken(); 477 478 // Determine whether this (sub)module has already been defined. 479 llvm::StringMap<Module *> &ModuleSpace 480 = ActiveModule? ActiveModule->SubModules : Map.Modules; 481 llvm::StringMap<Module *>::iterator ExistingModule 482 = ModuleSpace.find(ModuleName); 483 if (ExistingModule != ModuleSpace.end()) { 484 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 485 << ModuleName; 486 Diags.Report(ExistingModule->getValue()->DefinitionLoc, 487 diag::note_mmap_prev_definition); 488 489 // Skip the module definition. 490 skipUntil(MMToken::RBrace); 491 if (Tok.is(MMToken::RBrace)) 492 consumeToken(); 493 494 HadError = true; 495 return; 496 } 497 498 // Start defining this module. 499 ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 500 Explicit); 501 ModuleSpace[ModuleName] = ActiveModule; 502 503 bool Done = false; 504 do { 505 switch (Tok.Kind) { 506 case MMToken::EndOfFile: 507 case MMToken::RBrace: 508 Done = true; 509 break; 510 511 case MMToken::ExplicitKeyword: 512 case MMToken::ModuleKeyword: 513 parseModuleDecl(); 514 break; 515 516 case MMToken::HeaderKeyword: 517 parseHeaderDecl(); 518 break; 519 520 case MMToken::UmbrellaKeyword: 521 parseUmbrellaDecl(); 522 break; 523 524 default: 525 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 526 consumeToken(); 527 break; 528 } 529 } while (!Done); 530 531 if (Tok.is(MMToken::RBrace)) 532 consumeToken(); 533 else { 534 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 535 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 536 HadError = true; 537 } 538 539 // We're done parsing this module. Pop back to our parent scope. 540 ActiveModule = ActiveModule->Parent; 541 } 542 543 /// \brief Parse an umbrella header declaration. 544 /// 545 /// umbrella-declaration: 546 /// 'umbrella' string-literal 547 void ModuleMapParser::parseUmbrellaDecl() { 548 assert(Tok.is(MMToken::UmbrellaKeyword)); 549 SourceLocation UmbrellaLoc = consumeToken(); 550 551 // Parse the header name. 552 if (!Tok.is(MMToken::StringLiteral)) { 553 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 554 << "umbrella"; 555 HadError = true; 556 return; 557 } 558 StringRef FileName = Tok.getString(); 559 SourceLocation FileNameLoc = consumeToken(); 560 561 // Check whether we already have an umbrella header. 562 if (ActiveModule->UmbrellaHeader) { 563 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict) 564 << ActiveModule->getFullModuleName() 565 << ActiveModule->UmbrellaHeader->getName(); 566 HadError = true; 567 return; 568 } 569 570 // Only top-level modules can have umbrella headers. 571 if (ActiveModule->Parent) { 572 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule) 573 << ActiveModule->getFullModuleName(); 574 HadError = true; 575 return; 576 } 577 578 // Look for this file. 579 llvm::SmallString<128> PathName; 580 PathName += Directory->getName(); 581 unsigned PathLength = PathName.size(); 582 const FileEntry *File = 0; 583 if (ActiveModule->isPartOfFramework()) { 584 // Check whether this file is in the public headers. 585 llvm::sys::path::append(PathName, "Headers"); 586 llvm::sys::path::append(PathName, FileName); 587 File = SourceMgr.getFileManager().getFile(PathName); 588 589 if (!File) { 590 // Check whether this file is in the private headers. 591 PathName.resize(PathLength); 592 llvm::sys::path::append(PathName, "PrivateHeaders"); 593 llvm::sys::path::append(PathName, FileName); 594 File = SourceMgr.getFileManager().getFile(PathName); 595 } 596 597 // FIXME: Deal with subframeworks. 598 } else { 599 // Lookup for normal headers. 600 llvm::sys::path::append(PathName, FileName); 601 File = SourceMgr.getFileManager().getFile(PathName); 602 } 603 604 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 605 // Come up with a lazy way to do this. 606 if (File) { 607 if (const Module *OwningModule = Map.Headers[File]) { 608 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 609 << FileName << OwningModule->getFullModuleName(); 610 HadError = true; 611 } else if ((OwningModule = Map.UmbrellaDirs[Directory])) { 612 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 613 << OwningModule->getFullModuleName(); 614 HadError = true; 615 } else { 616 // Record this umbrella header. 617 ActiveModule->UmbrellaHeader = File; 618 Map.Headers[File] = ActiveModule; 619 Map.UmbrellaDirs[Directory] = ActiveModule; 620 } 621 } else { 622 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 623 << true << FileName; 624 HadError = true; 625 } 626 } 627 628 /// \brief Parse a header declaration. 629 /// 630 /// header-declaration: 631 /// 'header' string-literal 632 void ModuleMapParser::parseHeaderDecl() { 633 assert(Tok.is(MMToken::HeaderKeyword)); 634 consumeToken(); 635 636 // Parse the header name. 637 if (!Tok.is(MMToken::StringLiteral)) { 638 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 639 << "header"; 640 HadError = true; 641 return; 642 } 643 StringRef FileName = Tok.getString(); 644 SourceLocation FileNameLoc = consumeToken(); 645 646 // Look for this file. 647 llvm::SmallString<128> PathName; 648 PathName += Directory->getName(); 649 650 if (ActiveModule->isPartOfFramework()) 651 llvm::sys::path::append(PathName, "Headers"); 652 653 llvm::sys::path::append(PathName, FileName); 654 655 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 656 // Come up with a lazy way to do this. 657 if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) { 658 if (const Module *OwningModule = Map.Headers[File]) { 659 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 660 << FileName << OwningModule->getFullModuleName(); 661 HadError = true; 662 } else { 663 // Record this file. 664 ActiveModule->Headers.push_back(File); 665 Map.Headers[File] = ActiveModule; 666 } 667 } else { 668 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 669 << false << FileName; 670 HadError = true; 671 } 672 } 673 674 /// \brief Parse a module map file. 675 /// 676 /// module-map-file: 677 /// module-declaration* 678 bool ModuleMapParser::parseModuleMapFile() { 679 do { 680 switch (Tok.Kind) { 681 case MMToken::EndOfFile: 682 return HadError; 683 684 case MMToken::ModuleKeyword: 685 case MMToken::FrameworkKeyword: 686 parseModuleDecl(); 687 break; 688 689 case MMToken::ExplicitKeyword: 690 case MMToken::HeaderKeyword: 691 case MMToken::Identifier: 692 case MMToken::LBrace: 693 case MMToken::RBrace: 694 case MMToken::StringLiteral: 695 case MMToken::UmbrellaKeyword: 696 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 697 HadError = true; 698 consumeToken(); 699 break; 700 } 701 } while (true); 702 703 return HadError; 704 } 705 706 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 707 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 708 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 709 if (!Buffer) 710 return true; 711 712 // Parse this module map file. 713 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 714 Diags->getClient()->BeginSourceFile(LangOpts); 715 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 716 bool Result = Parser.parseModuleMapFile(); 717 Diags->getClient()->EndSourceFile(); 718 719 return Result; 720 } 721