ASTReaderInternals.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //===- ASTReaderInternals.h - AST Reader Internals --------------*- 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 provides internal definitions used in the AST reader.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
  13. #define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
  14. #include "MultiOnDiskHashTable.h"
  15. #include "clang/AST/DeclarationName.h"
  16. #include "clang/Basic/LLVM.h"
  17. #include "clang/Serialization/ASTBitCodes.h"
  18. #include "llvm/ADT/DenseSet.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Support/OnDiskHashTable.h"
  22. #include <ctime>
  23. #include <utility>
  24. namespace clang {
  25. class ASTReader;
  26. class FileEntry;
  27. struct HeaderFileInfo;
  28. class HeaderSearch;
  29. class IdentifierTable;
  30. class ObjCMethodDecl;
  31. namespace serialization {
  32. class ModuleFile;
  33. namespace reader {
  34. /// Class that performs name lookup into a DeclContext stored
  35. /// in an AST file.
  36. class ASTDeclContextNameLookupTrait {
  37. ASTReader &Reader;
  38. ModuleFile &F;
  39. public:
  40. // Maximum number of lookup tables we allow before condensing the tables.
  41. static const int MaxTables = 4;
  42. /// The lookup result is a list of global declaration IDs.
  43. using data_type = SmallVector<DeclID, 4>;
  44. struct data_type_builder {
  45. data_type &Data;
  46. llvm::DenseSet<DeclID> Found;
  47. data_type_builder(data_type &D) : Data(D) {}
  48. void insert(DeclID ID) {
  49. // Just use a linear scan unless we have more than a few IDs.
  50. if (Found.empty() && !Data.empty()) {
  51. if (Data.size() <= 4) {
  52. for (auto I : Found)
  53. if (I == ID)
  54. return;
  55. Data.push_back(ID);
  56. return;
  57. }
  58. // Switch to tracking found IDs in the set.
  59. Found.insert(Data.begin(), Data.end());
  60. }
  61. if (Found.insert(ID).second)
  62. Data.push_back(ID);
  63. }
  64. };
  65. using hash_value_type = unsigned;
  66. using offset_type = unsigned;
  67. using file_type = ModuleFile *;
  68. using external_key_type = DeclarationName;
  69. using internal_key_type = DeclarationNameKey;
  70. explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
  71. : Reader(Reader), F(F) {}
  72. static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
  73. return a == b;
  74. }
  75. static hash_value_type ComputeHash(const internal_key_type &Key) {
  76. return Key.getHash();
  77. }
  78. static internal_key_type GetInternalKey(const external_key_type &Name) {
  79. return Name;
  80. }
  81. static std::pair<unsigned, unsigned>
  82. ReadKeyDataLength(const unsigned char *&d);
  83. internal_key_type ReadKey(const unsigned char *d, unsigned);
  84. void ReadDataInto(internal_key_type, const unsigned char *d,
  85. unsigned DataLen, data_type_builder &Val);
  86. static void MergeDataInto(const data_type &From, data_type_builder &To) {
  87. To.Data.reserve(To.Data.size() + From.size());
  88. for (DeclID ID : From)
  89. To.insert(ID);
  90. }
  91. file_type ReadFileRef(const unsigned char *&d);
  92. };
  93. struct DeclContextLookupTable {
  94. MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
  95. };
  96. /// Base class for the trait describing the on-disk hash table for the
  97. /// identifiers in an AST file.
  98. ///
  99. /// This class is not useful by itself; rather, it provides common
  100. /// functionality for accessing the on-disk hash table of identifiers
  101. /// in an AST file. Different subclasses customize that functionality
  102. /// based on what information they are interested in. Those subclasses
  103. /// must provide the \c data_type type and the ReadData operation, only.
  104. class ASTIdentifierLookupTraitBase {
  105. public:
  106. using external_key_type = StringRef;
  107. using internal_key_type = StringRef;
  108. using hash_value_type = unsigned;
  109. using offset_type = unsigned;
  110. static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
  111. return a == b;
  112. }
  113. static hash_value_type ComputeHash(const internal_key_type& a);
  114. static std::pair<unsigned, unsigned>
  115. ReadKeyDataLength(const unsigned char*& d);
  116. // This hopefully will just get inlined and removed by the optimizer.
  117. static const internal_key_type&
  118. GetInternalKey(const external_key_type& x) { return x; }
  119. // This hopefully will just get inlined and removed by the optimizer.
  120. static const external_key_type&
  121. GetExternalKey(const internal_key_type& x) { return x; }
  122. static internal_key_type ReadKey(const unsigned char* d, unsigned n);
  123. };
  124. /// Class that performs lookup for an identifier stored in an AST file.
  125. class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
  126. ASTReader &Reader;
  127. ModuleFile &F;
  128. // If we know the IdentifierInfo in advance, it is here and we will
  129. // not build a new one. Used when deserializing information about an
  130. // identifier that was constructed before the AST file was read.
  131. IdentifierInfo *KnownII;
  132. public:
  133. using data_type = IdentifierInfo *;
  134. ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
  135. IdentifierInfo *II = nullptr)
  136. : Reader(Reader), F(F), KnownII(II) {}
  137. data_type ReadData(const internal_key_type& k,
  138. const unsigned char* d,
  139. unsigned DataLen);
  140. IdentID ReadIdentifierID(const unsigned char *d);
  141. ASTReader &getReader() const { return Reader; }
  142. };
  143. /// The on-disk hash table used to contain information about
  144. /// all of the identifiers in the program.
  145. using ASTIdentifierLookupTable =
  146. llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
  147. /// Class that performs lookup for a selector's entries in the global
  148. /// method pool stored in an AST file.
  149. class ASTSelectorLookupTrait {
  150. ASTReader &Reader;
  151. ModuleFile &F;
  152. public:
  153. struct data_type {
  154. SelectorID ID;
  155. unsigned InstanceBits;
  156. unsigned FactoryBits;
  157. bool InstanceHasMoreThanOneDecl;
  158. bool FactoryHasMoreThanOneDecl;
  159. SmallVector<ObjCMethodDecl *, 2> Instance;
  160. SmallVector<ObjCMethodDecl *, 2> Factory;
  161. };
  162. using external_key_type = Selector;
  163. using internal_key_type = external_key_type;
  164. using hash_value_type = unsigned;
  165. using offset_type = unsigned;
  166. ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
  167. : Reader(Reader), F(F) {}
  168. static bool EqualKey(const internal_key_type& a,
  169. const internal_key_type& b) {
  170. return a == b;
  171. }
  172. static hash_value_type ComputeHash(Selector Sel);
  173. static const internal_key_type&
  174. GetInternalKey(const external_key_type& x) { return x; }
  175. static std::pair<unsigned, unsigned>
  176. ReadKeyDataLength(const unsigned char*& d);
  177. internal_key_type ReadKey(const unsigned char* d, unsigned);
  178. data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
  179. };
  180. /// The on-disk hash table used for the global method pool.
  181. using ASTSelectorLookupTable =
  182. llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
  183. /// Trait class used to search the on-disk hash table containing all of
  184. /// the header search information.
  185. ///
  186. /// The on-disk hash table contains a mapping from each header path to
  187. /// information about that header (how many times it has been included, its
  188. /// controlling macro, etc.). Note that we actually hash based on the size
  189. /// and mtime, and support "deep" comparisons of file names based on current
  190. /// inode numbers, so that the search can cope with non-normalized path names
  191. /// and symlinks.
  192. class HeaderFileInfoTrait {
  193. ASTReader &Reader;
  194. ModuleFile &M;
  195. HeaderSearch *HS;
  196. const char *FrameworkStrings;
  197. public:
  198. using external_key_type = const FileEntry *;
  199. struct internal_key_type {
  200. off_t Size;
  201. time_t ModTime;
  202. StringRef Filename;
  203. bool Imported;
  204. };
  205. using internal_key_ref = const internal_key_type &;
  206. using data_type = HeaderFileInfo;
  207. using hash_value_type = unsigned;
  208. using offset_type = unsigned;
  209. HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
  210. const char *FrameworkStrings)
  211. : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
  212. static hash_value_type ComputeHash(internal_key_ref ikey);
  213. internal_key_type GetInternalKey(const FileEntry *FE);
  214. bool EqualKey(internal_key_ref a, internal_key_ref b);
  215. static std::pair<unsigned, unsigned>
  216. ReadKeyDataLength(const unsigned char*& d);
  217. static internal_key_type ReadKey(const unsigned char *d, unsigned);
  218. data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
  219. };
  220. /// The on-disk hash table used for known header files.
  221. using HeaderFileInfoLookupTable =
  222. llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
  223. } // namespace reader
  224. } // namespace serialization
  225. } // namespace clang
  226. #endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H