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