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