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