GlobalModuleIndex.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  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/Basic/OnDiskHashTable.h"
  16. #include "clang/Serialization/ASTBitCodes.h"
  17. #include "clang/Serialization/GlobalModuleIndex.h"
  18. #include "llvm/ADT/DenseMap.h"
  19. #include "llvm/ADT/MapVector.h"
  20. #include "llvm/ADT/SmallString.h"
  21. #include "llvm/ADT/StringExtras.h"
  22. #include "llvm/Bitcode/BitstreamReader.h"
  23. #include "llvm/Bitcode/BitstreamWriter.h"
  24. #include "llvm/Support/Filesystem.h"
  25. #include "llvm/Support/LockFileManager.h"
  26. #include "llvm/Support/MemoryBuffer.h"
  27. #include "llvm/Support/PathV2.h"
  28. using namespace clang;
  29. using namespace serialization;
  30. //----------------------------------------------------------------------------//
  31. // Shared constants
  32. //----------------------------------------------------------------------------//
  33. namespace {
  34. enum {
  35. /// \brief The block containing the index.
  36. GLOBAL_INDEX_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID
  37. };
  38. /// \brief Describes the record types in the index.
  39. enum IndexRecordTypes {
  40. /// \brief Contains version information and potentially other metadata,
  41. /// used to determine if we can read this global index file.
  42. METADATA,
  43. /// \brief Describes a module, including its file name and dependencies.
  44. MODULE,
  45. /// \brief The index for identifiers.
  46. IDENTIFIER_INDEX
  47. };
  48. }
  49. /// \brief The name of the global index file.
  50. static const char * const IndexFileName = "modules.idx";
  51. /// \brief The global index file version.
  52. static const unsigned CurrentVersion = 1;
  53. //----------------------------------------------------------------------------//
  54. // Global module index writer.
  55. //----------------------------------------------------------------------------//
  56. namespace {
  57. /// \brief Provides information about a specific module file.
  58. struct ModuleFileInfo {
  59. /// \brief The numberic ID for this module file.
  60. unsigned ID;
  61. /// \brief The set of modules on which this module depends. Each entry is
  62. /// a module ID.
  63. SmallVector<unsigned, 4> Dependencies;
  64. };
  65. /// \brief Builder that generates the global module index file.
  66. class GlobalModuleIndexBuilder {
  67. FileManager &FileMgr;
  68. /// \brief Mapping from files to module file information.
  69. typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
  70. /// \brief Information about each of the known module files.
  71. ModuleFilesMap ModuleFiles;
  72. /// \brief Mapping from identifiers to the list of module file IDs that
  73. /// consider this identifier to be interesting.
  74. typedef llvm::StringMap<SmallVector<unsigned, 2> > InterestingIdentifierMap;
  75. /// \brief A mapping from all interesting identifiers to the set of module
  76. /// files in which those identifiers are considered interesting.
  77. InterestingIdentifierMap InterestingIdentifiers;
  78. /// \brief Write the block-info block for the global module index file.
  79. void emitBlockInfoBlock(llvm::BitstreamWriter &Stream);
  80. /// \brief Retrieve the module file information for the given file.
  81. ModuleFileInfo &getModuleFileInfo(const FileEntry *File) {
  82. llvm::MapVector<const FileEntry *, ModuleFileInfo>::iterator Known
  83. = ModuleFiles.find(File);
  84. if (Known != ModuleFiles.end())
  85. return Known->second;
  86. unsigned NewID = ModuleFiles.size();
  87. ModuleFileInfo &Info = ModuleFiles[File];
  88. Info.ID = NewID;
  89. return Info;
  90. }
  91. public:
  92. explicit GlobalModuleIndexBuilder(FileManager &FileMgr) : FileMgr(FileMgr){}
  93. /// \brief Load the contents of the given module file into the builder.
  94. ///
  95. /// \returns true if an error occurred, false otherwise.
  96. bool loadModuleFile(const FileEntry *File);
  97. /// \brief Write the index to the given bitstream.
  98. void writeIndex(llvm::BitstreamWriter &Stream);
  99. };
  100. }
  101. static void emitBlockID(unsigned ID, const char *Name,
  102. llvm::BitstreamWriter &Stream,
  103. SmallVectorImpl<uint64_t> &Record) {
  104. Record.clear();
  105. Record.push_back(ID);
  106. Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
  107. // Emit the block name if present.
  108. if (Name == 0 || Name[0] == 0) return;
  109. Record.clear();
  110. while (*Name)
  111. Record.push_back(*Name++);
  112. Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
  113. }
  114. static void emitRecordID(unsigned ID, const char *Name,
  115. llvm::BitstreamWriter &Stream,
  116. SmallVectorImpl<uint64_t> &Record) {
  117. Record.clear();
  118. Record.push_back(ID);
  119. while (*Name)
  120. Record.push_back(*Name++);
  121. Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
  122. }
  123. void
  124. GlobalModuleIndexBuilder::emitBlockInfoBlock(llvm::BitstreamWriter &Stream) {
  125. SmallVector<uint64_t, 64> Record;
  126. Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3);
  127. #define BLOCK(X) emitBlockID(X ## _ID, #X, Stream, Record)
  128. #define RECORD(X) emitRecordID(X, #X, Stream, Record)
  129. BLOCK(GLOBAL_INDEX_BLOCK);
  130. RECORD(METADATA);
  131. RECORD(MODULE);
  132. RECORD(IDENTIFIER_INDEX);
  133. #undef RECORD
  134. #undef BLOCK
  135. Stream.ExitBlock();
  136. }
  137. namespace clang {
  138. class InterestingASTIdentifierLookupTrait
  139. : public serialization::reader::ASTIdentifierLookupTraitBase {
  140. public:
  141. /// \brief The identifier and whether it is "interesting".
  142. typedef std::pair<StringRef, bool> data_type;
  143. data_type ReadData(const internal_key_type& k,
  144. const unsigned char* d,
  145. unsigned DataLen) {
  146. // The first bit indicates whether this identifier is interesting.
  147. // That's all we care about.
  148. using namespace clang::io;
  149. unsigned RawID = ReadUnalignedLE32(d);
  150. bool IsInteresting = RawID & 0x01;
  151. return std::make_pair(k, IsInteresting);
  152. }
  153. };
  154. }
  155. bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
  156. // Open the module file.
  157. OwningPtr<llvm::MemoryBuffer> Buffer;
  158. Buffer.reset(FileMgr.getBufferForFile(File));
  159. if (!Buffer) {
  160. return true;
  161. }
  162. // Initialize the input stream
  163. llvm::BitstreamReader InStreamFile;
  164. llvm::BitstreamCursor InStream;
  165. InStreamFile.init((const unsigned char *)Buffer->getBufferStart(),
  166. (const unsigned char *)Buffer->getBufferEnd());
  167. InStream.init(InStreamFile);
  168. // Sniff for the signature.
  169. if (InStream.Read(8) != 'C' ||
  170. InStream.Read(8) != 'P' ||
  171. InStream.Read(8) != 'C' ||
  172. InStream.Read(8) != 'H') {
  173. return true;
  174. }
  175. // Record this module file and assign it a unique ID (if it doesn't have
  176. // one already).
  177. unsigned ID = getModuleFileInfo(File).ID;
  178. // Search for the blocks and records we care about.
  179. enum { Outer, ControlBlock, ASTBlock } State = Outer;
  180. bool Done = false;
  181. while (!Done) {
  182. const unsigned Flags = llvm::BitstreamCursor::AF_DontPopBlockAtEnd;
  183. llvm::BitstreamEntry Entry = InStream.advance(Flags);
  184. switch (Entry.Kind) {
  185. case llvm::BitstreamEntry::Error:
  186. return true;
  187. case llvm::BitstreamEntry::Record:
  188. // In the outer state, just skip the record. We don't care.
  189. if (State == Outer) {
  190. InStream.skipRecord(Entry.ID);
  191. continue;
  192. }
  193. // Handle potentially-interesting records below.
  194. break;
  195. case llvm::BitstreamEntry::SubBlock:
  196. if (State == Outer && Entry.ID == CONTROL_BLOCK_ID) {
  197. if (InStream.EnterSubBlock(CONTROL_BLOCK_ID))
  198. return true;
  199. // Found the control block.
  200. State = ControlBlock;
  201. continue;
  202. }
  203. if (State == Outer && Entry.ID == AST_BLOCK_ID) {
  204. if (InStream.EnterSubBlock(AST_BLOCK_ID))
  205. return true;
  206. // Found the AST block.
  207. State = ASTBlock;
  208. continue;
  209. }
  210. if (InStream.SkipBlock())
  211. return true;
  212. continue;
  213. case llvm::BitstreamEntry::EndBlock:
  214. if (State == Outer) {
  215. Done = true;
  216. }
  217. State = Outer;
  218. continue;
  219. }
  220. // Read the given record.
  221. SmallVector<uint64_t, 64> Record;
  222. StringRef Blob;
  223. unsigned Code = InStream.readRecord(Entry.ID, Record, &Blob);
  224. // Handle module dependencies.
  225. if (State == ControlBlock && Code == IMPORTS) {
  226. // Load each of the imported PCH files.
  227. unsigned Idx = 0, N = Record.size();
  228. while (Idx < N) {
  229. // Read information about the AST file.
  230. // Skip the imported kind
  231. ++Idx;
  232. // Skip the import location
  233. ++Idx;
  234. // Retrieve the imported file name.
  235. unsigned Length = Record[Idx++];
  236. SmallString<128> ImportedFile(Record.begin() + Idx,
  237. Record.begin() + Idx + Length);
  238. Idx += Length;
  239. // Find the imported module file.
  240. const FileEntry *DependsOnFile = FileMgr.getFile(ImportedFile);
  241. if (!DependsOnFile)
  242. return true;
  243. // Record the dependency.
  244. unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID;
  245. getModuleFileInfo(File).Dependencies.push_back(DependsOnID);
  246. }
  247. continue;
  248. }
  249. // Handle the identifier table
  250. if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) {
  251. typedef OnDiskChainedHashTable<InterestingASTIdentifierLookupTrait>
  252. InterestingIdentifierTable;
  253. llvm::OwningPtr<InterestingIdentifierTable>
  254. Table(InterestingIdentifierTable::Create(
  255. (const unsigned char *)Blob.data() + Record[0],
  256. (const unsigned char *)Blob.data()));
  257. for (InterestingIdentifierTable::data_iterator D = Table->data_begin(),
  258. DEnd = Table->data_end();
  259. D != DEnd; ++D) {
  260. std::pair<StringRef, bool> Ident = *D;
  261. if (Ident.second)
  262. InterestingIdentifiers[Ident.first].push_back(ID);
  263. }
  264. }
  265. // FIXME: Handle the selector table.
  266. // We don't care about this record.
  267. }
  268. return false;
  269. }
  270. namespace {
  271. /// \brief Trait used to generate the identifier index as an on-disk hash
  272. /// table.
  273. class IdentifierIndexWriterTrait {
  274. public:
  275. typedef StringRef key_type;
  276. typedef StringRef key_type_ref;
  277. typedef SmallVector<unsigned, 2> data_type;
  278. typedef const SmallVector<unsigned, 2> &data_type_ref;
  279. static unsigned ComputeHash(key_type_ref Key) {
  280. return llvm::HashString(Key);
  281. }
  282. std::pair<unsigned,unsigned>
  283. EmitKeyDataLength(raw_ostream& Out, key_type_ref Key, data_type_ref Data) {
  284. unsigned KeyLen = Key.size();
  285. unsigned DataLen = Data.size() * 4;
  286. clang::io::Emit16(Out, KeyLen);
  287. clang::io::Emit16(Out, DataLen);
  288. return std::make_pair(KeyLen, DataLen);
  289. }
  290. void EmitKey(raw_ostream& Out, key_type_ref Key, unsigned KeyLen) {
  291. Out.write(Key.data(), KeyLen);
  292. }
  293. void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data,
  294. unsigned DataLen) {
  295. for (unsigned I = 0, N = Data.size(); I != N; ++I)
  296. clang::io::Emit32(Out, Data[I]);
  297. }
  298. };
  299. }
  300. void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
  301. using namespace llvm;
  302. // Emit the file header.
  303. Stream.Emit((unsigned)'B', 8);
  304. Stream.Emit((unsigned)'C', 8);
  305. Stream.Emit((unsigned)'G', 8);
  306. Stream.Emit((unsigned)'I', 8);
  307. // Write the block-info block, which describes the records in this bitcode
  308. // file.
  309. emitBlockInfoBlock(Stream);
  310. Stream.EnterSubblock(GLOBAL_INDEX_BLOCK_ID, 3);
  311. // Write the metadata.
  312. SmallVector<uint64_t, 2> Record;
  313. Record.push_back(CurrentVersion);
  314. Stream.EmitRecord(METADATA, Record);
  315. // Write the set of known module files.
  316. for (ModuleFilesMap::iterator M = ModuleFiles.begin(),
  317. MEnd = ModuleFiles.end();
  318. M != MEnd; ++M) {
  319. Record.clear();
  320. Record.push_back(M->second.ID);
  321. Record.push_back(M->first->getSize());
  322. Record.push_back(M->first->getModificationTime());
  323. // File name
  324. StringRef Name(M->first->getName());
  325. Record.push_back(Name.size());
  326. Record.append(Name.begin(), Name.end());
  327. // Dependencies
  328. Record.push_back(M->second.Dependencies.size());
  329. Record.append(M->second.Dependencies.begin(), M->second.Dependencies.end());
  330. Stream.EmitRecord(MODULE, Record);
  331. }
  332. // Write the identifier -> module file mapping.
  333. {
  334. OnDiskChainedHashTableGenerator<IdentifierIndexWriterTrait> Generator;
  335. IdentifierIndexWriterTrait Trait;
  336. // Populate the hash table.
  337. for (InterestingIdentifierMap::iterator I = InterestingIdentifiers.begin(),
  338. IEnd = InterestingIdentifiers.end();
  339. I != IEnd; ++I) {
  340. Generator.insert(I->first(), I->second, Trait);
  341. }
  342. // Create the on-disk hash table in a buffer.
  343. SmallString<4096> IdentifierTable;
  344. uint32_t BucketOffset;
  345. {
  346. llvm::raw_svector_ostream Out(IdentifierTable);
  347. // Make sure that no bucket is at offset 0
  348. clang::io::Emit32(Out, 0);
  349. BucketOffset = Generator.Emit(Out, Trait);
  350. }
  351. // Create a blob abbreviation
  352. BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
  353. Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_INDEX));
  354. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
  355. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
  356. unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev);
  357. // Write the identifier table
  358. Record.clear();
  359. Record.push_back(IDENTIFIER_INDEX);
  360. Record.push_back(BucketOffset);
  361. Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str());
  362. }
  363. // FIXME: Selectors.
  364. Stream.ExitBlock();
  365. }
  366. GlobalModuleIndex::ErrorCode
  367. GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) {
  368. llvm::SmallString<128> IndexPath;
  369. IndexPath += Path;
  370. llvm::sys::path::append(IndexPath, IndexFileName);
  371. // Coordinate building the global index file with other processes that might
  372. // try to do the same.
  373. llvm::LockFileManager Locked(IndexPath);
  374. switch (Locked) {
  375. case llvm::LockFileManager::LFS_Error:
  376. return EC_IOError;
  377. case llvm::LockFileManager::LFS_Owned:
  378. // We're responsible for building the index ourselves. Do so below.
  379. break;
  380. case llvm::LockFileManager::LFS_Shared:
  381. // Someone else is responsible for building the index. We don't care
  382. // when they finish, so we're done.
  383. return EC_Building;
  384. }
  385. // The module index builder.
  386. GlobalModuleIndexBuilder Builder(FileMgr);
  387. // Load each of the module files.
  388. llvm::error_code EC;
  389. for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
  390. D != DEnd && !EC;
  391. D.increment(EC)) {
  392. // If this isn't a module file, we don't care.
  393. if (llvm::sys::path::extension(D->path()) != ".pcm") {
  394. // ... unless it's a .pcm.lock file, which indicates that someone is
  395. // in the process of rebuilding a module. They'll rebuild the index
  396. // at the end of that translation unit, so we don't have to.
  397. if (llvm::sys::path::extension(D->path()) == ".pcm.lock")
  398. return EC_Building;
  399. continue;
  400. }
  401. // If we can't find the module file, skip it.
  402. const FileEntry *ModuleFile = FileMgr.getFile(D->path());
  403. if (!ModuleFile)
  404. continue;
  405. // Load this module file.
  406. if (Builder.loadModuleFile(ModuleFile))
  407. return EC_IOError;
  408. }
  409. // The output buffer, into which the global index will be written.
  410. SmallVector<char, 16> OutputBuffer;
  411. {
  412. llvm::BitstreamWriter OutputStream(OutputBuffer);
  413. Builder.writeIndex(OutputStream);
  414. }
  415. // Write the global index file to a temporary file.
  416. llvm::SmallString<128> IndexTmpPath;
  417. int TmpFD;
  418. if (llvm::sys::fs::unique_file(IndexPath + "-%%%%%%%%", TmpFD, IndexTmpPath))
  419. return EC_IOError;
  420. // Open the temporary global index file for output.
  421. std::string ErrorInfo;
  422. llvm::raw_fd_ostream Out(IndexTmpPath.c_str(), ErrorInfo,
  423. llvm::raw_fd_ostream::F_Binary);
  424. if (Out.has_error())
  425. return EC_IOError;
  426. // Write the index.
  427. Out.write(OutputBuffer.data(), OutputBuffer.size());
  428. Out.close();
  429. if (Out.has_error())
  430. return EC_IOError;
  431. // Remove the old index file. It isn't relevant any more.
  432. bool OldIndexExisted;
  433. llvm::sys::fs::remove(IndexPath.str(), OldIndexExisted);
  434. // Rename the newly-written index file to the proper name.
  435. if (llvm::sys::fs::rename(IndexTmpPath.str(), IndexPath.str())) {
  436. // Rename failed; just remove the
  437. llvm::sys::fs::remove(IndexTmpPath.str(), OldIndexExisted);
  438. return EC_IOError;
  439. }
  440. // We're done.
  441. return EC_None;
  442. }