1*67e74705SXin Li //===--- ASTReaderInternals.h - AST Reader Internals ------------*- C++ -*-===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // This file provides internal definitions used in the AST reader. 11*67e74705SXin Li // 12*67e74705SXin Li //===----------------------------------------------------------------------===// 13*67e74705SXin Li #ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H 14*67e74705SXin Li #define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H 15*67e74705SXin Li 16*67e74705SXin Li #include "clang/AST/DeclarationName.h" 17*67e74705SXin Li #include "clang/Serialization/ASTBitCodes.h" 18*67e74705SXin Li #include "llvm/ADT/DenseSet.h" 19*67e74705SXin Li #include "llvm/ADT/PointerUnion.h" 20*67e74705SXin Li #include "llvm/ADT/TinyPtrVector.h" 21*67e74705SXin Li #include "llvm/Support/Endian.h" 22*67e74705SXin Li #include "llvm/Support/OnDiskHashTable.h" 23*67e74705SXin Li #include "MultiOnDiskHashTable.h" 24*67e74705SXin Li #include <utility> 25*67e74705SXin Li 26*67e74705SXin Li namespace clang { 27*67e74705SXin Li 28*67e74705SXin Li class ASTReader; 29*67e74705SXin Li class HeaderSearch; 30*67e74705SXin Li struct HeaderFileInfo; 31*67e74705SXin Li class FileEntry; 32*67e74705SXin Li 33*67e74705SXin Li namespace serialization { 34*67e74705SXin Li 35*67e74705SXin Li class ModuleFile; 36*67e74705SXin Li 37*67e74705SXin Li namespace reader { 38*67e74705SXin Li 39*67e74705SXin Li /// \brief Class that performs name lookup into a DeclContext stored 40*67e74705SXin Li /// in an AST file. 41*67e74705SXin Li class ASTDeclContextNameLookupTrait { 42*67e74705SXin Li ASTReader &Reader; 43*67e74705SXin Li ModuleFile &F; 44*67e74705SXin Li 45*67e74705SXin Li public: 46*67e74705SXin Li // Maximum number of lookup tables we allow before condensing the tables. 47*67e74705SXin Li static const int MaxTables = 4; 48*67e74705SXin Li 49*67e74705SXin Li /// The lookup result is a list of global declaration IDs. 50*67e74705SXin Li typedef llvm::SmallVector<DeclID, 4> data_type; 51*67e74705SXin Li struct data_type_builder { 52*67e74705SXin Li data_type &Data; 53*67e74705SXin Li llvm::DenseSet<DeclID> Found; 54*67e74705SXin Li data_type_builderdata_type_builder55*67e74705SXin Li data_type_builder(data_type &D) : Data(D) {} insertdata_type_builder56*67e74705SXin Li void insert(DeclID ID) { 57*67e74705SXin Li // Just use a linear scan unless we have more than a few IDs. 58*67e74705SXin Li if (Found.empty() && !Data.empty()) { 59*67e74705SXin Li if (Data.size() <= 4) { 60*67e74705SXin Li for (auto I : Found) 61*67e74705SXin Li if (I == ID) 62*67e74705SXin Li return; 63*67e74705SXin Li Data.push_back(ID); 64*67e74705SXin Li return; 65*67e74705SXin Li } 66*67e74705SXin Li 67*67e74705SXin Li // Switch to tracking found IDs in the set. 68*67e74705SXin Li Found.insert(Data.begin(), Data.end()); 69*67e74705SXin Li } 70*67e74705SXin Li 71*67e74705SXin Li if (Found.insert(ID).second) 72*67e74705SXin Li Data.push_back(ID); 73*67e74705SXin Li } 74*67e74705SXin Li }; 75*67e74705SXin Li typedef unsigned hash_value_type; 76*67e74705SXin Li typedef unsigned offset_type; 77*67e74705SXin Li typedef ModuleFile *file_type; 78*67e74705SXin Li 79*67e74705SXin Li typedef DeclarationName external_key_type; 80*67e74705SXin Li typedef DeclarationNameKey internal_key_type; 81*67e74705SXin Li ASTDeclContextNameLookupTrait(ASTReader & Reader,ModuleFile & F)82*67e74705SXin Li explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F) 83*67e74705SXin Li : Reader(Reader), F(F) { } 84*67e74705SXin Li EqualKey(const internal_key_type & a,const internal_key_type & b)85*67e74705SXin Li static bool EqualKey(const internal_key_type &a, const internal_key_type &b) { 86*67e74705SXin Li return a == b; 87*67e74705SXin Li } 88*67e74705SXin Li ComputeHash(const internal_key_type & Key)89*67e74705SXin Li static hash_value_type ComputeHash(const internal_key_type &Key) { 90*67e74705SXin Li return Key.getHash(); 91*67e74705SXin Li } GetInternalKey(const external_key_type & Name)92*67e74705SXin Li static internal_key_type GetInternalKey(const external_key_type &Name) { 93*67e74705SXin Li return Name; 94*67e74705SXin Li } 95*67e74705SXin Li 96*67e74705SXin Li static std::pair<unsigned, unsigned> 97*67e74705SXin Li ReadKeyDataLength(const unsigned char *&d); 98*67e74705SXin Li 99*67e74705SXin Li internal_key_type ReadKey(const unsigned char *d, unsigned); 100*67e74705SXin Li 101*67e74705SXin Li void ReadDataInto(internal_key_type, const unsigned char *d, 102*67e74705SXin Li unsigned DataLen, data_type_builder &Val); 103*67e74705SXin Li MergeDataInto(const data_type & From,data_type_builder & To)104*67e74705SXin Li static void MergeDataInto(const data_type &From, data_type_builder &To) { 105*67e74705SXin Li To.Data.reserve(To.Data.size() + From.size()); 106*67e74705SXin Li for (DeclID ID : From) 107*67e74705SXin Li To.insert(ID); 108*67e74705SXin Li } 109*67e74705SXin Li 110*67e74705SXin Li file_type ReadFileRef(const unsigned char *&d); 111*67e74705SXin Li }; 112*67e74705SXin Li 113*67e74705SXin Li struct DeclContextLookupTable { 114*67e74705SXin Li MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table; 115*67e74705SXin Li 116*67e74705SXin Li // These look redundant, but don't remove them -- they work around MSVC 2013's 117*67e74705SXin Li // inability to synthesize move operations. Without them, the 118*67e74705SXin Li // MultiOnDiskHashTable will be copied (despite being move-only!). DeclContextLookupTableDeclContextLookupTable119*67e74705SXin Li DeclContextLookupTable() : Table() {} DeclContextLookupTableDeclContextLookupTable120*67e74705SXin Li DeclContextLookupTable(DeclContextLookupTable &&O) 121*67e74705SXin Li : Table(std::move(O.Table)) {} 122*67e74705SXin Li DeclContextLookupTable &operator=(DeclContextLookupTable &&O) { 123*67e74705SXin Li Table = std::move(O.Table); 124*67e74705SXin Li return *this; 125*67e74705SXin Li } 126*67e74705SXin Li }; 127*67e74705SXin Li 128*67e74705SXin Li /// \brief Base class for the trait describing the on-disk hash table for the 129*67e74705SXin Li /// identifiers in an AST file. 130*67e74705SXin Li /// 131*67e74705SXin Li /// This class is not useful by itself; rather, it provides common 132*67e74705SXin Li /// functionality for accessing the on-disk hash table of identifiers 133*67e74705SXin Li /// in an AST file. Different subclasses customize that functionality 134*67e74705SXin Li /// based on what information they are interested in. Those subclasses 135*67e74705SXin Li /// must provide the \c data_type typedef and the ReadData operation, 136*67e74705SXin Li /// only. 137*67e74705SXin Li class ASTIdentifierLookupTraitBase { 138*67e74705SXin Li public: 139*67e74705SXin Li typedef StringRef external_key_type; 140*67e74705SXin Li typedef StringRef internal_key_type; 141*67e74705SXin Li typedef unsigned hash_value_type; 142*67e74705SXin Li typedef unsigned offset_type; 143*67e74705SXin Li EqualKey(const internal_key_type & a,const internal_key_type & b)144*67e74705SXin Li static bool EqualKey(const internal_key_type& a, const internal_key_type& b) { 145*67e74705SXin Li return a == b; 146*67e74705SXin Li } 147*67e74705SXin Li 148*67e74705SXin Li static hash_value_type ComputeHash(const internal_key_type& a); 149*67e74705SXin Li 150*67e74705SXin Li static std::pair<unsigned, unsigned> 151*67e74705SXin Li ReadKeyDataLength(const unsigned char*& d); 152*67e74705SXin Li 153*67e74705SXin Li // This hopefully will just get inlined and removed by the optimizer. 154*67e74705SXin Li static const internal_key_type& GetInternalKey(const external_key_type & x)155*67e74705SXin Li GetInternalKey(const external_key_type& x) { return x; } 156*67e74705SXin Li 157*67e74705SXin Li // This hopefully will just get inlined and removed by the optimizer. 158*67e74705SXin Li static const external_key_type& GetExternalKey(const internal_key_type & x)159*67e74705SXin Li GetExternalKey(const internal_key_type& x) { return x; } 160*67e74705SXin Li 161*67e74705SXin Li static internal_key_type ReadKey(const unsigned char* d, unsigned n); 162*67e74705SXin Li }; 163*67e74705SXin Li 164*67e74705SXin Li /// \brief Class that performs lookup for an identifier stored in an AST file. 165*67e74705SXin Li class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase { 166*67e74705SXin Li ASTReader &Reader; 167*67e74705SXin Li ModuleFile &F; 168*67e74705SXin Li 169*67e74705SXin Li // If we know the IdentifierInfo in advance, it is here and we will 170*67e74705SXin Li // not build a new one. Used when deserializing information about an 171*67e74705SXin Li // identifier that was constructed before the AST file was read. 172*67e74705SXin Li IdentifierInfo *KnownII; 173*67e74705SXin Li 174*67e74705SXin Li public: 175*67e74705SXin Li typedef IdentifierInfo * data_type; 176*67e74705SXin Li 177*67e74705SXin Li ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F, 178*67e74705SXin Li IdentifierInfo *II = nullptr) Reader(Reader)179*67e74705SXin Li : Reader(Reader), F(F), KnownII(II) { } 180*67e74705SXin Li 181*67e74705SXin Li data_type ReadData(const internal_key_type& k, 182*67e74705SXin Li const unsigned char* d, 183*67e74705SXin Li unsigned DataLen); 184*67e74705SXin Li 185*67e74705SXin Li IdentID ReadIdentifierID(const unsigned char *d); 186*67e74705SXin Li getReader()187*67e74705SXin Li ASTReader &getReader() const { return Reader; } 188*67e74705SXin Li }; 189*67e74705SXin Li 190*67e74705SXin Li /// \brief The on-disk hash table used to contain information about 191*67e74705SXin Li /// all of the identifiers in the program. 192*67e74705SXin Li typedef llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait> 193*67e74705SXin Li ASTIdentifierLookupTable; 194*67e74705SXin Li 195*67e74705SXin Li /// \brief Class that performs lookup for a selector's entries in the global 196*67e74705SXin Li /// method pool stored in an AST file. 197*67e74705SXin Li class ASTSelectorLookupTrait { 198*67e74705SXin Li ASTReader &Reader; 199*67e74705SXin Li ModuleFile &F; 200*67e74705SXin Li 201*67e74705SXin Li public: 202*67e74705SXin Li struct data_type { 203*67e74705SXin Li SelectorID ID; 204*67e74705SXin Li unsigned InstanceBits; 205*67e74705SXin Li unsigned FactoryBits; 206*67e74705SXin Li bool InstanceHasMoreThanOneDecl; 207*67e74705SXin Li bool FactoryHasMoreThanOneDecl; 208*67e74705SXin Li SmallVector<ObjCMethodDecl *, 2> Instance; 209*67e74705SXin Li SmallVector<ObjCMethodDecl *, 2> Factory; 210*67e74705SXin Li }; 211*67e74705SXin Li 212*67e74705SXin Li typedef Selector external_key_type; 213*67e74705SXin Li typedef external_key_type internal_key_type; 214*67e74705SXin Li typedef unsigned hash_value_type; 215*67e74705SXin Li typedef unsigned offset_type; 216*67e74705SXin Li ASTSelectorLookupTrait(ASTReader & Reader,ModuleFile & F)217*67e74705SXin Li ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F) 218*67e74705SXin Li : Reader(Reader), F(F) { } 219*67e74705SXin Li EqualKey(const internal_key_type & a,const internal_key_type & b)220*67e74705SXin Li static bool EqualKey(const internal_key_type& a, 221*67e74705SXin Li const internal_key_type& b) { 222*67e74705SXin Li return a == b; 223*67e74705SXin Li } 224*67e74705SXin Li 225*67e74705SXin Li static hash_value_type ComputeHash(Selector Sel); 226*67e74705SXin Li 227*67e74705SXin Li static const internal_key_type& GetInternalKey(const external_key_type & x)228*67e74705SXin Li GetInternalKey(const external_key_type& x) { return x; } 229*67e74705SXin Li 230*67e74705SXin Li static std::pair<unsigned, unsigned> 231*67e74705SXin Li ReadKeyDataLength(const unsigned char*& d); 232*67e74705SXin Li 233*67e74705SXin Li internal_key_type ReadKey(const unsigned char* d, unsigned); 234*67e74705SXin Li data_type ReadData(Selector, const unsigned char* d, unsigned DataLen); 235*67e74705SXin Li }; 236*67e74705SXin Li 237*67e74705SXin Li /// \brief The on-disk hash table used for the global method pool. 238*67e74705SXin Li typedef llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait> 239*67e74705SXin Li ASTSelectorLookupTable; 240*67e74705SXin Li 241*67e74705SXin Li /// \brief Trait class used to search the on-disk hash table containing all of 242*67e74705SXin Li /// the header search information. 243*67e74705SXin Li /// 244*67e74705SXin Li /// The on-disk hash table contains a mapping from each header path to 245*67e74705SXin Li /// information about that header (how many times it has been included, its 246*67e74705SXin Li /// controlling macro, etc.). Note that we actually hash based on the size 247*67e74705SXin Li /// and mtime, and support "deep" comparisons of file names based on current 248*67e74705SXin Li /// inode numbers, so that the search can cope with non-normalized path names 249*67e74705SXin Li /// and symlinks. 250*67e74705SXin Li class HeaderFileInfoTrait { 251*67e74705SXin Li ASTReader &Reader; 252*67e74705SXin Li ModuleFile &M; 253*67e74705SXin Li HeaderSearch *HS; 254*67e74705SXin Li const char *FrameworkStrings; 255*67e74705SXin Li 256*67e74705SXin Li public: 257*67e74705SXin Li typedef const FileEntry *external_key_type; 258*67e74705SXin Li 259*67e74705SXin Li struct internal_key_type { 260*67e74705SXin Li off_t Size; 261*67e74705SXin Li time_t ModTime; 262*67e74705SXin Li const char *Filename; 263*67e74705SXin Li bool Imported; 264*67e74705SXin Li }; 265*67e74705SXin Li typedef const internal_key_type &internal_key_ref; 266*67e74705SXin Li 267*67e74705SXin Li typedef HeaderFileInfo data_type; 268*67e74705SXin Li typedef unsigned hash_value_type; 269*67e74705SXin Li typedef unsigned offset_type; 270*67e74705SXin Li HeaderFileInfoTrait(ASTReader & Reader,ModuleFile & M,HeaderSearch * HS,const char * FrameworkStrings)271*67e74705SXin Li HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS, 272*67e74705SXin Li const char *FrameworkStrings) 273*67e74705SXin Li : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) { } 274*67e74705SXin Li 275*67e74705SXin Li static hash_value_type ComputeHash(internal_key_ref ikey); 276*67e74705SXin Li internal_key_type GetInternalKey(const FileEntry *FE); 277*67e74705SXin Li bool EqualKey(internal_key_ref a, internal_key_ref b); 278*67e74705SXin Li 279*67e74705SXin Li static std::pair<unsigned, unsigned> 280*67e74705SXin Li ReadKeyDataLength(const unsigned char*& d); 281*67e74705SXin Li 282*67e74705SXin Li static internal_key_type ReadKey(const unsigned char *d, unsigned); 283*67e74705SXin Li 284*67e74705SXin Li data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen); 285*67e74705SXin Li }; 286*67e74705SXin Li 287*67e74705SXin Li /// \brief The on-disk hash table used for known header files. 288*67e74705SXin Li typedef llvm::OnDiskChainedHashTable<HeaderFileInfoTrait> 289*67e74705SXin Li HeaderFileInfoLookupTable; 290*67e74705SXin Li 291*67e74705SXin Li } // end namespace clang::serialization::reader 292*67e74705SXin Li } // end namespace clang::serialization 293*67e74705SXin Li } // end namespace clang 294*67e74705SXin Li 295*67e74705SXin Li 296*67e74705SXin Li #endif 297