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