ASTReaderInternals.h 8.8 KB

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