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