1 //===--- GlobalModuleIndex.cpp - Global Module Index ------------*- 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 implements the GlobalModuleIndex class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ASTReaderInternals.h" 15 #include "clang/Basic/FileManager.h" 16 #include "clang/Basic/OnDiskHashTable.h" 17 #include "clang/Lex/HeaderSearch.h" 18 #include "clang/Serialization/ASTBitCodes.h" 19 #include "clang/Serialization/GlobalModuleIndex.h" 20 #include "clang/Serialization/Module.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/MapVector.h" 23 #include "llvm/ADT/SmallString.h" 24 #include "llvm/ADT/StringExtras.h" 25 #include "llvm/Bitcode/BitstreamReader.h" 26 #include "llvm/Bitcode/BitstreamWriter.h" 27 #include "llvm/Support/FileSystem.h" 28 #include "llvm/Support/LockFileManager.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/Path.h" 31 #include <cstdio> 32 using namespace clang; 33 using namespace serialization; 34 35 //----------------------------------------------------------------------------// 36 // Shared constants 37 //----------------------------------------------------------------------------// 38 namespace { 39 enum { 40 /// \brief The block containing the index. 41 GLOBAL_INDEX_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID 42 }; 43 44 /// \brief Describes the record types in the index. 45 enum IndexRecordTypes { 46 /// \brief Contains version information and potentially other metadata, 47 /// used to determine if we can read this global index file. 48 INDEX_METADATA, 49 /// \brief Describes a module, including its file name and dependencies. 50 MODULE, 51 /// \brief The index for identifiers. 52 IDENTIFIER_INDEX 53 }; 54 } 55 56 /// \brief The name of the global index file. 57 static const char * const IndexFileName = "modules.idx"; 58 59 /// \brief The global index file version. 60 static const unsigned CurrentVersion = 1; 61 62 //----------------------------------------------------------------------------// 63 // Global module index reader. 64 //----------------------------------------------------------------------------// 65 66 namespace { 67 68 /// \brief Trait used to read the identifier index from the on-disk hash 69 /// table. 70 class IdentifierIndexReaderTrait { 71 public: 72 typedef StringRef external_key_type; 73 typedef StringRef internal_key_type; 74 typedef SmallVector<unsigned, 2> data_type; 75 76 static bool EqualKey(const internal_key_type& a, const internal_key_type& b) { 77 return a == b; 78 } 79 80 static unsigned ComputeHash(const internal_key_type& a) { 81 return llvm::HashString(a); 82 } 83 84 static std::pair<unsigned, unsigned> 85 ReadKeyDataLength(const unsigned char*& d) { 86 using namespace llvm::support; 87 unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d); 88 unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d); 89 return std::make_pair(KeyLen, DataLen); 90 } 91 92 static const internal_key_type& 93 GetInternalKey(const external_key_type& x) { return x; } 94 95 static const external_key_type& 96 GetExternalKey(const internal_key_type& x) { return x; } 97 98 static internal_key_type ReadKey(const unsigned char* d, unsigned n) { 99 return StringRef((const char *)d, n); 100 } 101 102 static data_type ReadData(const internal_key_type& k, 103 const unsigned char* d, 104 unsigned DataLen) { 105 using namespace llvm::support; 106 107 data_type Result; 108 while (DataLen > 0) { 109 unsigned ID = endian::readNext<uint32_t, little, unaligned>(d); 110 Result.push_back(ID); 111 DataLen -= 4; 112 } 113 114 return Result; 115 } 116 }; 117 118 typedef OnDiskIterableChainedHashTable<IdentifierIndexReaderTrait> 119 IdentifierIndexTable; 120 121 } 122 123 GlobalModuleIndex::GlobalModuleIndex(llvm::MemoryBuffer *Buffer, 124 llvm::BitstreamCursor Cursor) 125 : Buffer(Buffer), IdentifierIndex(), 126 NumIdentifierLookups(), NumIdentifierLookupHits() 127 { 128 // Read the global index. 129 bool InGlobalIndexBlock = false; 130 bool Done = false; 131 while (!Done) { 132 llvm::BitstreamEntry Entry = Cursor.advance(); 133 134 switch (Entry.Kind) { 135 case llvm::BitstreamEntry::Error: 136 return; 137 138 case llvm::BitstreamEntry::EndBlock: 139 if (InGlobalIndexBlock) { 140 InGlobalIndexBlock = false; 141 Done = true; 142 continue; 143 } 144 return; 145 146 147 case llvm::BitstreamEntry::Record: 148 // Entries in the global index block are handled below. 149 if (InGlobalIndexBlock) 150 break; 151 152 return; 153 154 case llvm::BitstreamEntry::SubBlock: 155 if (!InGlobalIndexBlock && Entry.ID == GLOBAL_INDEX_BLOCK_ID) { 156 if (Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID)) 157 return; 158 159 InGlobalIndexBlock = true; 160 } else if (Cursor.SkipBlock()) { 161 return; 162 } 163 continue; 164 } 165 166 SmallVector<uint64_t, 64> Record; 167 StringRef Blob; 168 switch ((IndexRecordTypes)Cursor.readRecord(Entry.ID, Record, &Blob)) { 169 case INDEX_METADATA: 170 // Make sure that the version matches. 171 if (Record.size() < 1 || Record[0] != CurrentVersion) 172 return; 173 break; 174 175 case MODULE: { 176 unsigned Idx = 0; 177 unsigned ID = Record[Idx++]; 178 179 // Make room for this module's information. 180 if (ID == Modules.size()) 181 Modules.push_back(ModuleInfo()); 182 else 183 Modules.resize(ID + 1); 184 185 // Size/modification time for this module file at the time the 186 // global index was built. 187 Modules[ID].Size = Record[Idx++]; 188 Modules[ID].ModTime = Record[Idx++]; 189 190 // File name. 191 unsigned NameLen = Record[Idx++]; 192 Modules[ID].FileName.assign(Record.begin() + Idx, 193 Record.begin() + Idx + NameLen); 194 Idx += NameLen; 195 196 // Dependencies 197 unsigned NumDeps = Record[Idx++]; 198 Modules[ID].Dependencies.insert(Modules[ID].Dependencies.end(), 199 Record.begin() + Idx, 200 Record.begin() + Idx + NumDeps); 201 Idx += NumDeps; 202 203 // Make sure we're at the end of the record. 204 assert(Idx == Record.size() && "More module info?"); 205 206 // Record this module as an unresolved module. 207 // FIXME: this doesn't work correctly for module names containing path 208 // separators. 209 StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName); 210 // Remove the -<hash of ModuleMapPath> 211 ModuleName = ModuleName.rsplit('-').first; 212 UnresolvedModules[ModuleName] = ID; 213 break; 214 } 215 216 case IDENTIFIER_INDEX: 217 // Wire up the identifier index. 218 if (Record[0]) { 219 IdentifierIndex = IdentifierIndexTable::Create( 220 (const unsigned char *)Blob.data() + Record[0], 221 (const unsigned char *)Blob.data() + sizeof(uint32_t), 222 (const unsigned char *)Blob.data(), IdentifierIndexReaderTrait()); 223 } 224 break; 225 } 226 } 227 } 228 229 GlobalModuleIndex::~GlobalModuleIndex() { } 230 231 std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> 232 GlobalModuleIndex::readIndex(StringRef Path) { 233 // Load the index file, if it's there. 234 llvm::SmallString<128> IndexPath; 235 IndexPath += Path; 236 llvm::sys::path::append(IndexPath, IndexFileName); 237 238 std::unique_ptr<llvm::MemoryBuffer> Buffer; 239 if (llvm::MemoryBuffer::getFile(IndexPath.c_str(), Buffer) != 240 llvm::errc::success) 241 return std::make_pair((GlobalModuleIndex *)0, EC_NotFound); 242 243 /// \brief The bitstream reader from which we'll read the AST file. 244 llvm::BitstreamReader Reader((const unsigned char *)Buffer->getBufferStart(), 245 (const unsigned char *)Buffer->getBufferEnd()); 246 247 /// \brief The main bitstream cursor for the main block. 248 llvm::BitstreamCursor Cursor(Reader); 249 250 // Sniff for the signature. 251 if (Cursor.Read(8) != 'B' || 252 Cursor.Read(8) != 'C' || 253 Cursor.Read(8) != 'G' || 254 Cursor.Read(8) != 'I') { 255 return std::make_pair((GlobalModuleIndex *)0, EC_IOError); 256 } 257 258 return std::make_pair(new GlobalModuleIndex(Buffer.release(), Cursor), 259 EC_None); 260 } 261 262 void 263 GlobalModuleIndex::getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles) { 264 ModuleFiles.clear(); 265 for (unsigned I = 0, N = Modules.size(); I != N; ++I) { 266 if (ModuleFile *MF = Modules[I].File) 267 ModuleFiles.push_back(MF); 268 } 269 } 270 271 void GlobalModuleIndex::getModuleDependencies( 272 ModuleFile *File, 273 SmallVectorImpl<ModuleFile *> &Dependencies) { 274 // Look for information about this module file. 275 llvm::DenseMap<ModuleFile *, unsigned>::iterator Known 276 = ModulesByFile.find(File); 277 if (Known == ModulesByFile.end()) 278 return; 279 280 // Record dependencies. 281 Dependencies.clear(); 282 ArrayRef<unsigned> StoredDependencies = Modules[Known->second].Dependencies; 283 for (unsigned I = 0, N = StoredDependencies.size(); I != N; ++I) { 284 if (ModuleFile *MF = Modules[I].File) 285 Dependencies.push_back(MF); 286 } 287 } 288 289 bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) { 290 Hits.clear(); 291 292 // If there's no identifier index, there is nothing we can do. 293 if (!IdentifierIndex) 294 return false; 295 296 // Look into the identifier index. 297 ++NumIdentifierLookups; 298 IdentifierIndexTable &Table 299 = *static_cast<IdentifierIndexTable *>(IdentifierIndex); 300 IdentifierIndexTable::iterator Known = Table.find(Name); 301 if (Known == Table.end()) { 302 return true; 303 } 304 305 SmallVector<unsigned, 2> ModuleIDs = *Known; 306 for (unsigned I = 0, N = ModuleIDs.size(); I != N; ++I) { 307 if (ModuleFile *MF = Modules[ModuleIDs[I]].File) 308 Hits.insert(MF); 309 } 310 311 ++NumIdentifierLookupHits; 312 return true; 313 } 314 315 bool GlobalModuleIndex::loadedModuleFile(ModuleFile *File) { 316 // Look for the module in the global module index based on the module name. 317 StringRef Name = File->ModuleName; 318 llvm::StringMap<unsigned>::iterator Known = UnresolvedModules.find(Name); 319 if (Known == UnresolvedModules.end()) { 320 return true; 321 } 322 323 // Rectify this module with the global module index. 324 ModuleInfo &Info = Modules[Known->second]; 325 326 // If the size and modification time match what we expected, record this 327 // module file. 328 bool Failed = true; 329 if (File->File->getSize() == Info.Size && 330 File->File->getModificationTime() == Info.ModTime) { 331 Info.File = File; 332 ModulesByFile[File] = Known->second; 333 334 Failed = false; 335 } 336 337 // One way or another, we have resolved this module file. 338 UnresolvedModules.erase(Known); 339 return Failed; 340 } 341 342 void GlobalModuleIndex::printStats() { 343 std::fprintf(stderr, "*** Global Module Index Statistics:\n"); 344 if (NumIdentifierLookups) { 345 fprintf(stderr, " %u / %u identifier lookups succeeded (%f%%)\n", 346 NumIdentifierLookupHits, NumIdentifierLookups, 347 (double)NumIdentifierLookupHits*100.0/NumIdentifierLookups); 348 } 349 std::fprintf(stderr, "\n"); 350 } 351 352 //----------------------------------------------------------------------------// 353 // Global module index writer. 354 //----------------------------------------------------------------------------// 355 356 namespace { 357 /// \brief Provides information about a specific module file. 358 struct ModuleFileInfo { 359 /// \brief The numberic ID for this module file. 360 unsigned ID; 361 362 /// \brief The set of modules on which this module depends. Each entry is 363 /// a module ID. 364 SmallVector<unsigned, 4> Dependencies; 365 }; 366 367 /// \brief Builder that generates the global module index file. 368 class GlobalModuleIndexBuilder { 369 FileManager &FileMgr; 370 371 /// \brief Mapping from files to module file information. 372 typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap; 373 374 /// \brief Information about each of the known module files. 375 ModuleFilesMap ModuleFiles; 376 377 /// \brief Mapping from identifiers to the list of module file IDs that 378 /// consider this identifier to be interesting. 379 typedef llvm::StringMap<SmallVector<unsigned, 2> > InterestingIdentifierMap; 380 381 /// \brief A mapping from all interesting identifiers to the set of module 382 /// files in which those identifiers are considered interesting. 383 InterestingIdentifierMap InterestingIdentifiers; 384 385 /// \brief Write the block-info block for the global module index file. 386 void emitBlockInfoBlock(llvm::BitstreamWriter &Stream); 387 388 /// \brief Retrieve the module file information for the given file. 389 ModuleFileInfo &getModuleFileInfo(const FileEntry *File) { 390 llvm::MapVector<const FileEntry *, ModuleFileInfo>::iterator Known 391 = ModuleFiles.find(File); 392 if (Known != ModuleFiles.end()) 393 return Known->second; 394 395 unsigned NewID = ModuleFiles.size(); 396 ModuleFileInfo &Info = ModuleFiles[File]; 397 Info.ID = NewID; 398 return Info; 399 } 400 401 public: 402 explicit GlobalModuleIndexBuilder(FileManager &FileMgr) : FileMgr(FileMgr){} 403 404 /// \brief Load the contents of the given module file into the builder. 405 /// 406 /// \returns true if an error occurred, false otherwise. 407 bool loadModuleFile(const FileEntry *File); 408 409 /// \brief Write the index to the given bitstream. 410 void writeIndex(llvm::BitstreamWriter &Stream); 411 }; 412 } 413 414 static void emitBlockID(unsigned ID, const char *Name, 415 llvm::BitstreamWriter &Stream, 416 SmallVectorImpl<uint64_t> &Record) { 417 Record.clear(); 418 Record.push_back(ID); 419 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); 420 421 // Emit the block name if present. 422 if (Name == 0 || Name[0] == 0) return; 423 Record.clear(); 424 while (*Name) 425 Record.push_back(*Name++); 426 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record); 427 } 428 429 static void emitRecordID(unsigned ID, const char *Name, 430 llvm::BitstreamWriter &Stream, 431 SmallVectorImpl<uint64_t> &Record) { 432 Record.clear(); 433 Record.push_back(ID); 434 while (*Name) 435 Record.push_back(*Name++); 436 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record); 437 } 438 439 void 440 GlobalModuleIndexBuilder::emitBlockInfoBlock(llvm::BitstreamWriter &Stream) { 441 SmallVector<uint64_t, 64> Record; 442 Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3); 443 444 #define BLOCK(X) emitBlockID(X ## _ID, #X, Stream, Record) 445 #define RECORD(X) emitRecordID(X, #X, Stream, Record) 446 BLOCK(GLOBAL_INDEX_BLOCK); 447 RECORD(INDEX_METADATA); 448 RECORD(MODULE); 449 RECORD(IDENTIFIER_INDEX); 450 #undef RECORD 451 #undef BLOCK 452 453 Stream.ExitBlock(); 454 } 455 456 namespace { 457 class InterestingASTIdentifierLookupTrait 458 : public serialization::reader::ASTIdentifierLookupTraitBase { 459 460 public: 461 /// \brief The identifier and whether it is "interesting". 462 typedef std::pair<StringRef, bool> data_type; 463 464 data_type ReadData(const internal_key_type& k, 465 const unsigned char* d, 466 unsigned DataLen) { 467 // The first bit indicates whether this identifier is interesting. 468 // That's all we care about. 469 using namespace llvm::support; 470 unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d); 471 bool IsInteresting = RawID & 0x01; 472 return std::make_pair(k, IsInteresting); 473 } 474 }; 475 } 476 477 bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { 478 // Open the module file. 479 std::unique_ptr<llvm::MemoryBuffer> Buffer; 480 std::string ErrorStr; 481 Buffer.reset(FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)); 482 if (!Buffer) { 483 return true; 484 } 485 486 // Initialize the input stream 487 llvm::BitstreamReader InStreamFile; 488 llvm::BitstreamCursor InStream; 489 InStreamFile.init((const unsigned char *)Buffer->getBufferStart(), 490 (const unsigned char *)Buffer->getBufferEnd()); 491 InStream.init(InStreamFile); 492 493 // Sniff for the signature. 494 if (InStream.Read(8) != 'C' || 495 InStream.Read(8) != 'P' || 496 InStream.Read(8) != 'C' || 497 InStream.Read(8) != 'H') { 498 return true; 499 } 500 501 // Record this module file and assign it a unique ID (if it doesn't have 502 // one already). 503 unsigned ID = getModuleFileInfo(File).ID; 504 505 // Search for the blocks and records we care about. 506 enum { Other, ControlBlock, ASTBlock } State = Other; 507 bool Done = false; 508 while (!Done) { 509 llvm::BitstreamEntry Entry = InStream.advance(); 510 switch (Entry.Kind) { 511 case llvm::BitstreamEntry::Error: 512 Done = true; 513 continue; 514 515 case llvm::BitstreamEntry::Record: 516 // In the 'other' state, just skip the record. We don't care. 517 if (State == Other) { 518 InStream.skipRecord(Entry.ID); 519 continue; 520 } 521 522 // Handle potentially-interesting records below. 523 break; 524 525 case llvm::BitstreamEntry::SubBlock: 526 if (Entry.ID == CONTROL_BLOCK_ID) { 527 if (InStream.EnterSubBlock(CONTROL_BLOCK_ID)) 528 return true; 529 530 // Found the control block. 531 State = ControlBlock; 532 continue; 533 } 534 535 if (Entry.ID == AST_BLOCK_ID) { 536 if (InStream.EnterSubBlock(AST_BLOCK_ID)) 537 return true; 538 539 // Found the AST block. 540 State = ASTBlock; 541 continue; 542 } 543 544 if (InStream.SkipBlock()) 545 return true; 546 547 continue; 548 549 case llvm::BitstreamEntry::EndBlock: 550 State = Other; 551 continue; 552 } 553 554 // Read the given record. 555 SmallVector<uint64_t, 64> Record; 556 StringRef Blob; 557 unsigned Code = InStream.readRecord(Entry.ID, Record, &Blob); 558 559 // Handle module dependencies. 560 if (State == ControlBlock && Code == IMPORTS) { 561 // Load each of the imported PCH files. 562 unsigned Idx = 0, N = Record.size(); 563 while (Idx < N) { 564 // Read information about the AST file. 565 566 // Skip the imported kind 567 ++Idx; 568 569 // Skip the import location 570 ++Idx; 571 572 // Load stored size/modification time. 573 off_t StoredSize = (off_t)Record[Idx++]; 574 time_t StoredModTime = (time_t)Record[Idx++]; 575 576 // Retrieve the imported file name. 577 unsigned Length = Record[Idx++]; 578 SmallString<128> ImportedFile(Record.begin() + Idx, 579 Record.begin() + Idx + Length); 580 Idx += Length; 581 582 // Find the imported module file. 583 const FileEntry *DependsOnFile 584 = FileMgr.getFile(ImportedFile, /*openFile=*/false, 585 /*cacheFailure=*/false); 586 if (!DependsOnFile || 587 (StoredSize != DependsOnFile->getSize()) || 588 (StoredModTime != DependsOnFile->getModificationTime())) 589 return true; 590 591 // Record the dependency. 592 unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID; 593 getModuleFileInfo(File).Dependencies.push_back(DependsOnID); 594 } 595 596 continue; 597 } 598 599 // Handle the identifier table 600 if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) { 601 typedef 602 OnDiskIterableChainedHashTable<InterestingASTIdentifierLookupTrait> 603 InterestingIdentifierTable; 604 std::unique_ptr<InterestingIdentifierTable> Table( 605 InterestingIdentifierTable::Create( 606 (const unsigned char *)Blob.data() + Record[0], 607 (const unsigned char *)Blob.data() + sizeof(uint32_t), 608 (const unsigned char *)Blob.data())); 609 for (InterestingIdentifierTable::data_iterator D = Table->data_begin(), 610 DEnd = Table->data_end(); 611 D != DEnd; ++D) { 612 std::pair<StringRef, bool> Ident = *D; 613 if (Ident.second) 614 InterestingIdentifiers[Ident.first].push_back(ID); 615 else 616 (void)InterestingIdentifiers[Ident.first]; 617 } 618 } 619 620 // We don't care about this record. 621 } 622 623 return false; 624 } 625 626 namespace { 627 628 /// \brief Trait used to generate the identifier index as an on-disk hash 629 /// table. 630 class IdentifierIndexWriterTrait { 631 public: 632 typedef StringRef key_type; 633 typedef StringRef key_type_ref; 634 typedef SmallVector<unsigned, 2> data_type; 635 typedef const SmallVector<unsigned, 2> &data_type_ref; 636 637 static unsigned ComputeHash(key_type_ref Key) { 638 return llvm::HashString(Key); 639 } 640 641 std::pair<unsigned,unsigned> 642 EmitKeyDataLength(raw_ostream& Out, key_type_ref Key, data_type_ref Data) { 643 using namespace llvm::support; 644 endian::Writer<little> LE(Out); 645 unsigned KeyLen = Key.size(); 646 unsigned DataLen = Data.size() * 4; 647 LE.write<uint16_t>(KeyLen); 648 LE.write<uint16_t>(DataLen); 649 return std::make_pair(KeyLen, DataLen); 650 } 651 652 void EmitKey(raw_ostream& Out, key_type_ref Key, unsigned KeyLen) { 653 Out.write(Key.data(), KeyLen); 654 } 655 656 void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data, 657 unsigned DataLen) { 658 using namespace llvm::support; 659 for (unsigned I = 0, N = Data.size(); I != N; ++I) 660 endian::Writer<little>(Out).write<uint32_t>(Data[I]); 661 } 662 }; 663 664 } 665 666 void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) { 667 using namespace llvm; 668 669 // Emit the file header. 670 Stream.Emit((unsigned)'B', 8); 671 Stream.Emit((unsigned)'C', 8); 672 Stream.Emit((unsigned)'G', 8); 673 Stream.Emit((unsigned)'I', 8); 674 675 // Write the block-info block, which describes the records in this bitcode 676 // file. 677 emitBlockInfoBlock(Stream); 678 679 Stream.EnterSubblock(GLOBAL_INDEX_BLOCK_ID, 3); 680 681 // Write the metadata. 682 SmallVector<uint64_t, 2> Record; 683 Record.push_back(CurrentVersion); 684 Stream.EmitRecord(INDEX_METADATA, Record); 685 686 // Write the set of known module files. 687 for (ModuleFilesMap::iterator M = ModuleFiles.begin(), 688 MEnd = ModuleFiles.end(); 689 M != MEnd; ++M) { 690 Record.clear(); 691 Record.push_back(M->second.ID); 692 Record.push_back(M->first->getSize()); 693 Record.push_back(M->first->getModificationTime()); 694 695 // File name 696 StringRef Name(M->first->getName()); 697 Record.push_back(Name.size()); 698 Record.append(Name.begin(), Name.end()); 699 700 // Dependencies 701 Record.push_back(M->second.Dependencies.size()); 702 Record.append(M->second.Dependencies.begin(), M->second.Dependencies.end()); 703 Stream.EmitRecord(MODULE, Record); 704 } 705 706 // Write the identifier -> module file mapping. 707 { 708 OnDiskChainedHashTableGenerator<IdentifierIndexWriterTrait> Generator; 709 IdentifierIndexWriterTrait Trait; 710 711 // Populate the hash table. 712 for (InterestingIdentifierMap::iterator I = InterestingIdentifiers.begin(), 713 IEnd = InterestingIdentifiers.end(); 714 I != IEnd; ++I) { 715 Generator.insert(I->first(), I->second, Trait); 716 } 717 718 // Create the on-disk hash table in a buffer. 719 SmallString<4096> IdentifierTable; 720 uint32_t BucketOffset; 721 { 722 using namespace llvm::support; 723 llvm::raw_svector_ostream Out(IdentifierTable); 724 // Make sure that no bucket is at offset 0 725 endian::Writer<little>(Out).write<uint32_t>(0); 726 BucketOffset = Generator.Emit(Out, Trait); 727 } 728 729 // Create a blob abbreviation 730 BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); 731 Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_INDEX)); 732 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); 733 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 734 unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev); 735 736 // Write the identifier table 737 Record.clear(); 738 Record.push_back(IDENTIFIER_INDEX); 739 Record.push_back(BucketOffset); 740 Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str()); 741 } 742 743 Stream.ExitBlock(); 744 } 745 746 GlobalModuleIndex::ErrorCode 747 GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) { 748 llvm::SmallString<128> IndexPath; 749 IndexPath += Path; 750 llvm::sys::path::append(IndexPath, IndexFileName); 751 752 // Coordinate building the global index file with other processes that might 753 // try to do the same. 754 llvm::LockFileManager Locked(IndexPath); 755 switch (Locked) { 756 case llvm::LockFileManager::LFS_Error: 757 return EC_IOError; 758 759 case llvm::LockFileManager::LFS_Owned: 760 // We're responsible for building the index ourselves. Do so below. 761 break; 762 763 case llvm::LockFileManager::LFS_Shared: 764 // Someone else is responsible for building the index. We don't care 765 // when they finish, so we're done. 766 return EC_Building; 767 } 768 769 // The module index builder. 770 GlobalModuleIndexBuilder Builder(FileMgr); 771 772 // Load each of the module files. 773 llvm::error_code EC; 774 for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd; 775 D != DEnd && !EC; 776 D.increment(EC)) { 777 // If this isn't a module file, we don't care. 778 if (llvm::sys::path::extension(D->path()) != ".pcm") { 779 // ... unless it's a .pcm.lock file, which indicates that someone is 780 // in the process of rebuilding a module. They'll rebuild the index 781 // at the end of that translation unit, so we don't have to. 782 if (llvm::sys::path::extension(D->path()) == ".pcm.lock") 783 return EC_Building; 784 785 continue; 786 } 787 788 // If we can't find the module file, skip it. 789 const FileEntry *ModuleFile = FileMgr.getFile(D->path()); 790 if (!ModuleFile) 791 continue; 792 793 // Load this module file. 794 if (Builder.loadModuleFile(ModuleFile)) 795 return EC_IOError; 796 } 797 798 // The output buffer, into which the global index will be written. 799 SmallVector<char, 16> OutputBuffer; 800 { 801 llvm::BitstreamWriter OutputStream(OutputBuffer); 802 Builder.writeIndex(OutputStream); 803 } 804 805 // Write the global index file to a temporary file. 806 llvm::SmallString<128> IndexTmpPath; 807 int TmpFD; 808 if (llvm::sys::fs::createUniqueFile(IndexPath + "-%%%%%%%%", TmpFD, 809 IndexTmpPath)) 810 return EC_IOError; 811 812 // Open the temporary global index file for output. 813 llvm::raw_fd_ostream Out(TmpFD, true); 814 if (Out.has_error()) 815 return EC_IOError; 816 817 // Write the index. 818 Out.write(OutputBuffer.data(), OutputBuffer.size()); 819 Out.close(); 820 if (Out.has_error()) 821 return EC_IOError; 822 823 // Remove the old index file. It isn't relevant any more. 824 llvm::sys::fs::remove(IndexPath.str()); 825 826 // Rename the newly-written index file to the proper name. 827 if (llvm::sys::fs::rename(IndexTmpPath.str(), IndexPath.str())) { 828 // Rename failed; just remove the 829 llvm::sys::fs::remove(IndexTmpPath.str()); 830 return EC_IOError; 831 } 832 833 // We're done. 834 return EC_None; 835 } 836 837 namespace { 838 class GlobalIndexIdentifierIterator : public IdentifierIterator { 839 /// \brief The current position within the identifier lookup table. 840 IdentifierIndexTable::key_iterator Current; 841 842 /// \brief The end position within the identifier lookup table. 843 IdentifierIndexTable::key_iterator End; 844 845 public: 846 explicit GlobalIndexIdentifierIterator(IdentifierIndexTable &Idx) { 847 Current = Idx.key_begin(); 848 End = Idx.key_end(); 849 } 850 851 StringRef Next() override { 852 if (Current == End) 853 return StringRef(); 854 855 StringRef Result = *Current; 856 ++Current; 857 return Result; 858 } 859 }; 860 } 861 862 IdentifierIterator *GlobalModuleIndex::createIdentifierIterator() const { 863 IdentifierIndexTable &Table = 864 *static_cast<IdentifierIndexTable *>(IdentifierIndex); 865 return new GlobalIndexIdentifierIterator(Table); 866 } 867