Coverage Report

Created: 2023-05-31 04:38

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