1 //===--- ASTReaderInternals.h - AST Reader Internals ------------*- 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 provides internal definitions used in the AST reader. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H 14 #define LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H 15 16 #include "clang/Basic/OnDiskHashTable.h" 17 #include "clang/AST/DeclarationName.h" 18 #include <utility> 19 #include <sys/stat.h> 20 21 namespace clang { 22 23 class ASTReader; 24 class HeaderSearch; 25 struct HeaderFileInfo; 26 27 namespace serialization { 28 29 class Module; 30 31 namespace reader { 32 33 /// \brief Class that performs name lookup into a DeclContext stored 34 /// in an AST file. 35 class ASTDeclContextNameLookupTrait { 36 ASTReader &Reader; 37 Module &F; 38 39 public: 40 /// \brief Pair of begin/end iterators for DeclIDs. 41 /// 42 /// Note that these declaration IDs are local to the module that contains this 43 /// particular lookup t 44 typedef std::pair<DeclID *, DeclID *> data_type; 45 46 /// \brief Special internal key for declaration names. 47 /// The hash table creates keys for comparison; we do not create 48 /// a DeclarationName for the internal key to avoid deserializing types. 49 struct DeclNameKey { 50 DeclarationName::NameKind Kind; 51 uint64_t Data; 52 DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { } 53 }; 54 55 typedef DeclarationName external_key_type; 56 typedef DeclNameKey internal_key_type; 57 58 explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, 59 Module &F) 60 : Reader(Reader), F(F) { } 61 62 static bool EqualKey(const internal_key_type& a, 63 const internal_key_type& b) { 64 return a.Kind == b.Kind && a.Data == b.Data; 65 } 66 67 unsigned ComputeHash(const DeclNameKey &Key) const; 68 internal_key_type GetInternalKey(const external_key_type& Name) const; 69 external_key_type GetExternalKey(const internal_key_type& Key) const; 70 71 static std::pair<unsigned, unsigned> 72 ReadKeyDataLength(const unsigned char*& d); 73 74 internal_key_type ReadKey(const unsigned char* d, unsigned); 75 76 data_type ReadData(internal_key_type, const unsigned char* d, 77 unsigned DataLen); 78 }; 79 80 /// \brief The on-disk hash table used for the DeclContext's Name lookup table. 81 typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait> 82 ASTDeclContextNameLookupTable; 83 84 /// \brief Class that performs lookup for an identifier stored in an AST file. 85 class ASTIdentifierLookupTrait { 86 ASTReader &Reader; 87 Module &F; 88 89 // If we know the IdentifierInfo in advance, it is here and we will 90 // not build a new one. Used when deserializing information about an 91 // identifier that was constructed before the AST file was read. 92 IdentifierInfo *KnownII; 93 94 public: 95 typedef IdentifierInfo * data_type; 96 97 typedef const std::pair<const char*, unsigned> external_key_type; 98 99 typedef external_key_type internal_key_type; 100 101 ASTIdentifierLookupTrait(ASTReader &Reader, Module &F, 102 IdentifierInfo *II = 0) 103 : Reader(Reader), F(F), KnownII(II) { } 104 105 static bool EqualKey(const internal_key_type& a, 106 const internal_key_type& b) { 107 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0 108 : false; 109 } 110 111 static unsigned ComputeHash(const internal_key_type& a); 112 113 // This hopefully will just get inlined and removed by the optimizer. 114 static const internal_key_type& 115 GetInternalKey(const external_key_type& x) { return x; } 116 117 // This hopefully will just get inlined and removed by the optimizer. 118 static const external_key_type& 119 GetExternalKey(const internal_key_type& x) { return x; } 120 121 static std::pair<unsigned, unsigned> 122 ReadKeyDataLength(const unsigned char*& d); 123 124 static std::pair<const char*, unsigned> 125 ReadKey(const unsigned char* d, unsigned n); 126 127 IdentifierInfo *ReadData(const internal_key_type& k, 128 const unsigned char* d, 129 unsigned DataLen); 130 }; 131 132 /// \brief The on-disk hash table used to contain information about 133 /// all of the identifiers in the program. 134 typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait> 135 ASTIdentifierLookupTable; 136 137 /// \brief Class that performs lookup for a selector's entries in the global 138 /// method pool stored in an AST file. 139 class ASTSelectorLookupTrait { 140 ASTReader &Reader; 141 Module &F; 142 143 public: 144 struct data_type { 145 SelectorID ID; 146 llvm::SmallVector<ObjCMethodDecl *, 2> Instance; 147 llvm::SmallVector<ObjCMethodDecl *, 2> Factory; 148 }; 149 150 typedef Selector external_key_type; 151 typedef external_key_type internal_key_type; 152 153 ASTSelectorLookupTrait(ASTReader &Reader, Module &F) 154 : Reader(Reader), F(F) { } 155 156 static bool EqualKey(const internal_key_type& a, 157 const internal_key_type& b) { 158 return a == b; 159 } 160 161 static unsigned ComputeHash(Selector Sel); 162 163 static const internal_key_type& 164 GetInternalKey(const external_key_type& x) { return x; } 165 166 static std::pair<unsigned, unsigned> 167 ReadKeyDataLength(const unsigned char*& d); 168 169 internal_key_type ReadKey(const unsigned char* d, unsigned); 170 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen); 171 }; 172 173 /// \brief The on-disk hash table used for the global method pool. 174 typedef OnDiskChainedHashTable<ASTSelectorLookupTrait> 175 ASTSelectorLookupTable; 176 177 /// \brief Trait class used to search the on-disk hash table containing all of 178 /// the header search information. 179 /// 180 /// The on-disk hash table contains a mapping from each header path to 181 /// information about that header (how many times it has been included, its 182 /// controlling macro, etc.). Note that we actually hash based on the 183 /// filename, and support "deep" comparisons of file names based on current 184 /// inode numbers, so that the search can cope with non-normalized path names 185 /// and symlinks. 186 class HeaderFileInfoTrait { 187 ASTReader &Reader; 188 Module &M; 189 HeaderSearch *HS; 190 const char *FrameworkStrings; 191 const char *SearchPath; 192 struct stat SearchPathStatBuf; 193 llvm::Optional<int> SearchPathStatResult; 194 195 int StatSimpleCache(const char *Path, struct stat *StatBuf) { 196 if (Path == SearchPath) { 197 if (!SearchPathStatResult) 198 SearchPathStatResult = stat(Path, &SearchPathStatBuf); 199 200 *StatBuf = SearchPathStatBuf; 201 return *SearchPathStatResult; 202 } 203 204 return stat(Path, StatBuf); 205 } 206 207 public: 208 typedef const char *external_key_type; 209 typedef const char *internal_key_type; 210 211 typedef HeaderFileInfo data_type; 212 213 HeaderFileInfoTrait(ASTReader &Reader, Module &M, HeaderSearch *HS, 214 const char *FrameworkStrings, 215 const char *SearchPath = 0) 216 : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings), 217 SearchPath(SearchPath) { } 218 219 static unsigned ComputeHash(const char *path); 220 static internal_key_type GetInternalKey(const char *path); 221 bool EqualKey(internal_key_type a, internal_key_type b); 222 223 static std::pair<unsigned, unsigned> 224 ReadKeyDataLength(const unsigned char*& d); 225 226 static internal_key_type ReadKey(const unsigned char *d, unsigned) { 227 return (const char *)d; 228 } 229 230 data_type ReadData(const internal_key_type, const unsigned char *d, 231 unsigned DataLen); 232 }; 233 234 /// \brief The on-disk hash table used for known header files. 235 typedef OnDiskChainedHashTable<HeaderFileInfoTrait> 236 HeaderFileInfoLookupTable; 237 238 } // end namespace clang::serialization::reader 239 } // end namespace clang::serialization 240 } // end namespace clang 241 242 243 #endif 244