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