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 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 253 DiagnosticsEngine &Diags, 254 ModuleMap &Map, 255 const DirectoryEntry *Directory) 256 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map), 257 Directory(Directory), HadError(false), ActiveModule(0) 258 { 259 TargetOptions TargetOpts; 260 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple(); 261 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 262 263 Tok.clear(); 264 consumeToken(); 265 } 266 267 bool parseModuleMapFile(); 268 }; 269 } 270 271 SourceLocation ModuleMapParser::consumeToken() { 272 retry: 273 SourceLocation Result = Tok.getLocation(); 274 Tok.clear(); 275 276 Token LToken; 277 L.LexFromRawLexer(LToken); 278 Tok.Location = LToken.getLocation().getRawEncoding(); 279 switch (LToken.getKind()) { 280 case tok::raw_identifier: 281 Tok.StringData = LToken.getRawIdentifierData(); 282 Tok.StringLength = LToken.getLength(); 283 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString()) 284 .Case("header", MMToken::HeaderKeyword) 285 .Case("explicit", MMToken::ExplicitKeyword) 286 .Case("framework", MMToken::FrameworkKeyword) 287 .Case("module", MMToken::ModuleKeyword) 288 .Case("umbrella", MMToken::UmbrellaKeyword) 289 .Default(MMToken::Identifier); 290 break; 291 292 case tok::eof: 293 Tok.Kind = MMToken::EndOfFile; 294 break; 295 296 case tok::l_brace: 297 Tok.Kind = MMToken::LBrace; 298 break; 299 300 case tok::r_brace: 301 Tok.Kind = MMToken::RBrace; 302 break; 303 304 case tok::string_literal: { 305 // Parse the string literal. 306 LangOptions LangOpts; 307 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target); 308 if (StringLiteral.hadError) 309 goto retry; 310 311 // Copy the string literal into our string data allocator. 312 unsigned Length = StringLiteral.GetStringLength(); 313 char *Saved = StringData.Allocate<char>(Length + 1); 314 memcpy(Saved, StringLiteral.GetString().data(), Length); 315 Saved[Length] = 0; 316 317 // Form the token. 318 Tok.Kind = MMToken::StringLiteral; 319 Tok.StringData = Saved; 320 Tok.StringLength = Length; 321 break; 322 } 323 324 case tok::comment: 325 goto retry; 326 327 default: 328 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); 329 HadError = true; 330 goto retry; 331 } 332 333 return Result; 334 } 335 336 void ModuleMapParser::skipUntil(MMToken::TokenKind K) { 337 unsigned braceDepth = 0; 338 do { 339 switch (Tok.Kind) { 340 case MMToken::EndOfFile: 341 return; 342 343 case MMToken::LBrace: 344 if (Tok.is(K) && braceDepth == 0) 345 return; 346 347 ++braceDepth; 348 break; 349 350 case MMToken::RBrace: 351 if (braceDepth > 0) 352 --braceDepth; 353 else if (Tok.is(K)) 354 return; 355 break; 356 357 default: 358 if (braceDepth == 0 && Tok.is(K)) 359 return; 360 break; 361 } 362 363 consumeToken(); 364 } while (true); 365 } 366 367 /// \brief Parse a module declaration. 368 /// 369 /// module-declaration: 370 /// 'framework'[opt] 'module' identifier { module-member* } 371 /// 372 /// module-member: 373 /// umbrella-declaration 374 /// header-declaration 375 /// 'explicit'[opt] module-declaration 376 void ModuleMapParser::parseModuleDecl() { 377 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) || 378 Tok.is(MMToken::FrameworkKeyword)); 379 380 // Parse 'framework' or 'explicit' keyword, if present. 381 bool Framework = false; 382 bool Explicit = false; 383 384 if (Tok.is(MMToken::FrameworkKeyword)) { 385 consumeToken(); 386 Framework = true; 387 } 388 // Parse 'explicit' keyword, if present. 389 else if (Tok.is(MMToken::ExplicitKeyword)) { 390 consumeToken(); 391 Explicit = true; 392 } 393 394 // Parse 'module' keyword. 395 if (!Tok.is(MMToken::ModuleKeyword)) { 396 Diags.Report(Tok.getLocation(), 397 diag::err_mmap_expected_module_after_explicit); 398 consumeToken(); 399 HadError = true; 400 return; 401 } 402 consumeToken(); // 'module' keyword 403 404 // Parse the module name. 405 if (!Tok.is(MMToken::Identifier)) { 406 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name); 407 HadError = true; 408 return; 409 } 410 StringRef ModuleName = Tok.getString(); 411 SourceLocation ModuleNameLoc = consumeToken(); 412 413 // Parse the opening brace. 414 if (!Tok.is(MMToken::LBrace)) { 415 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) 416 << ModuleName; 417 HadError = true; 418 return; 419 } 420 SourceLocation LBraceLoc = consumeToken(); 421 422 // Determine whether this (sub)module has already been defined. 423 llvm::StringMap<Module *> &ModuleSpace 424 = ActiveModule? ActiveModule->SubModules : Map.Modules; 425 llvm::StringMap<Module *>::iterator ExistingModule 426 = ModuleSpace.find(ModuleName); 427 if (ExistingModule != ModuleSpace.end()) { 428 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) 429 << ModuleName; 430 Diags.Report(ExistingModule->getValue()->DefinitionLoc, 431 diag::note_mmap_prev_definition); 432 433 // Skip the module definition. 434 skipUntil(MMToken::RBrace); 435 if (Tok.is(MMToken::RBrace)) 436 consumeToken(); 437 438 HadError = true; 439 return; 440 } 441 442 // Start defining this module. 443 ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework, 444 Explicit); 445 ModuleSpace[ModuleName] = ActiveModule; 446 447 bool Done = false; 448 do { 449 switch (Tok.Kind) { 450 case MMToken::EndOfFile: 451 case MMToken::RBrace: 452 Done = true; 453 break; 454 455 case MMToken::ExplicitKeyword: 456 case MMToken::ModuleKeyword: 457 parseModuleDecl(); 458 break; 459 460 case MMToken::HeaderKeyword: 461 parseHeaderDecl(); 462 break; 463 464 case MMToken::UmbrellaKeyword: 465 parseUmbrellaDecl(); 466 break; 467 468 default: 469 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member); 470 consumeToken(); 471 break; 472 } 473 } while (!Done); 474 475 if (Tok.is(MMToken::RBrace)) 476 consumeToken(); 477 else { 478 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); 479 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); 480 HadError = true; 481 } 482 483 // We're done parsing this module. Pop back to our parent scope. 484 ActiveModule = ActiveModule->Parent; 485 } 486 487 /// \brief Parse an umbrella header declaration. 488 /// 489 /// umbrella-declaration: 490 /// 'umbrella' string-literal 491 void ModuleMapParser::parseUmbrellaDecl() { 492 assert(Tok.is(MMToken::UmbrellaKeyword)); 493 SourceLocation UmbrellaLoc = consumeToken(); 494 495 // Parse the header name. 496 if (!Tok.is(MMToken::StringLiteral)) { 497 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 498 << "umbrella"; 499 HadError = true; 500 return; 501 } 502 StringRef FileName = Tok.getString(); 503 SourceLocation FileNameLoc = consumeToken(); 504 505 // Check whether we already have an umbrella header. 506 if (ActiveModule->UmbrellaHeader) { 507 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict) 508 << ActiveModule->getFullModuleName() 509 << ActiveModule->UmbrellaHeader->getName(); 510 HadError = true; 511 return; 512 } 513 514 // Only top-level modules can have umbrella headers. 515 if (ActiveModule->Parent) { 516 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule) 517 << ActiveModule->getFullModuleName(); 518 HadError = true; 519 return; 520 } 521 522 // Look for this file. 523 llvm::SmallString<128> PathName; 524 const FileEntry *File = 0; 525 526 if (llvm::sys::path::is_absolute(FileName)) { 527 PathName = FileName; 528 File = SourceMgr.getFileManager().getFile(PathName); 529 } else { 530 // Search for the header file within the search directory. 531 PathName += Directory->getName(); 532 unsigned PathLength = PathName.size(); 533 if (ActiveModule->isPartOfFramework()) { 534 // Check whether this file is in the public headers. 535 llvm::sys::path::append(PathName, "Headers"); 536 llvm::sys::path::append(PathName, FileName); 537 File = SourceMgr.getFileManager().getFile(PathName); 538 539 if (!File) { 540 // Check whether this file is in the private headers. 541 PathName.resize(PathLength); 542 llvm::sys::path::append(PathName, "PrivateHeaders"); 543 llvm::sys::path::append(PathName, FileName); 544 File = SourceMgr.getFileManager().getFile(PathName); 545 } 546 547 // FIXME: Deal with subframeworks. 548 } else { 549 // Lookup for normal headers. 550 llvm::sys::path::append(PathName, FileName); 551 File = SourceMgr.getFileManager().getFile(PathName); 552 } 553 } 554 555 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 556 // Come up with a lazy way to do this. 557 if (File) { 558 if (const Module *OwningModule = Map.Headers[File]) { 559 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 560 << FileName << OwningModule->getFullModuleName(); 561 HadError = true; 562 } else if ((OwningModule = Map.UmbrellaDirs[Directory])) { 563 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash) 564 << OwningModule->getFullModuleName(); 565 HadError = true; 566 } else { 567 // Record this umbrella header. 568 ActiveModule->UmbrellaHeader = File; 569 Map.Headers[File] = ActiveModule; 570 Map.UmbrellaDirs[Directory] = ActiveModule; 571 } 572 } else { 573 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 574 << true << FileName; 575 HadError = true; 576 } 577 } 578 579 /// \brief Parse a header declaration. 580 /// 581 /// header-declaration: 582 /// 'header' string-literal 583 void ModuleMapParser::parseHeaderDecl() { 584 assert(Tok.is(MMToken::HeaderKeyword)); 585 consumeToken(); 586 587 // Parse the header name. 588 if (!Tok.is(MMToken::StringLiteral)) { 589 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) 590 << "header"; 591 HadError = true; 592 return; 593 } 594 StringRef FileName = Tok.getString(); 595 SourceLocation FileNameLoc = consumeToken(); 596 597 // Look for this file. 598 llvm::SmallString<128> PathName; 599 if (llvm::sys::path::is_relative(FileName)) { 600 // FIXME: Change this search to also look for private headers! 601 PathName += Directory->getName(); 602 603 if (ActiveModule->isPartOfFramework()) 604 llvm::sys::path::append(PathName, "Headers"); 605 } 606 607 llvm::sys::path::append(PathName, FileName); 608 609 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. 610 // Come up with a lazy way to do this. 611 if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) { 612 if (const Module *OwningModule = Map.Headers[File]) { 613 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict) 614 << FileName << OwningModule->getFullModuleName(); 615 HadError = true; 616 } else { 617 // Record this file. 618 ActiveModule->Headers.push_back(File); 619 Map.Headers[File] = ActiveModule; 620 } 621 } else { 622 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) 623 << false << FileName; 624 HadError = true; 625 } 626 } 627 628 /// \brief Parse a module map file. 629 /// 630 /// module-map-file: 631 /// module-declaration* 632 bool ModuleMapParser::parseModuleMapFile() { 633 do { 634 switch (Tok.Kind) { 635 case MMToken::EndOfFile: 636 return HadError; 637 638 case MMToken::ModuleKeyword: 639 case MMToken::FrameworkKeyword: 640 parseModuleDecl(); 641 break; 642 643 case MMToken::ExplicitKeyword: 644 case MMToken::HeaderKeyword: 645 case MMToken::Identifier: 646 case MMToken::LBrace: 647 case MMToken::RBrace: 648 case MMToken::StringLiteral: 649 case MMToken::UmbrellaKeyword: 650 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); 651 HadError = true; 652 consumeToken(); 653 break; 654 } 655 } while (true); 656 657 return HadError; 658 } 659 660 bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 661 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); 662 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); 663 if (!Buffer) 664 return true; 665 666 // Parse this module map file. 667 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts); 668 Diags->getClient()->BeginSourceFile(LangOpts); 669 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir()); 670 bool Result = Parser.parseModuleMapFile(); 671 Diags->getClient()->EndSourceFile(); 672 673 return Result; 674 } 675