GlobalModuleIndex.cpp revision 677e15ffee2ecc9c1c8f46fd77cab4b5afb59640
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>
30using namespace clang;
31using namespace serialization;
32
33//----------------------------------------------------------------------------//
34// Shared constants
35//----------------------------------------------------------------------------//
36namespace {
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.
55static const char * const IndexFileName = "modules.idx";
56
57/// \brief The global index file version.
58static const unsigned CurrentVersion = 1;
59
60ModuleFileNameResolver::~ModuleFileNameResolver() { }
61
62//----------------------------------------------------------------------------//
63// Global module index reader.
64//----------------------------------------------------------------------------//
65
66namespace {
67
68/// \brief Trait used to read the identifier index from the on-disk hash
69/// table.
70class IdentifierIndexReaderTrait {
71public:
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
118typedef OnDiskChainedHashTable<IdentifierIndexReaderTrait> IdentifierIndexTable;
119
120}
121
122GlobalModuleIndex::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
228GlobalModuleIndex::~GlobalModuleIndex() { }
229
230std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode>
231GlobalModuleIndex::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
259void
260GlobalModuleIndex::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
268void 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
293bool 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
319ModuleFile *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
367void 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
381namespace {
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
439static 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
454static 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
464void
465GlobalModuleIndexBuilder::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
481namespace {
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
502bool 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
649namespace {
650
651/// \brief Trait used to generate the identifier index as an on-disk hash
652/// table.
653class IdentifierIndexWriterTrait {
654public:
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
686void 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
765GlobalModuleIndex::ErrorCode
766GlobalModuleIndex::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