GlobalModuleIndex.cpp 27 KB

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