1226586Sdim//===--- ASTReaderInternals.h - AST Reader Internals ------------*- C++ -*-===//
2226586Sdim//
3226586Sdim//                     The LLVM Compiler Infrastructure
4226586Sdim//
5226586Sdim// This file is distributed under the University of Illinois Open Source
6226586Sdim// License. See LICENSE.TXT for details.
7226586Sdim//
8226586Sdim//===----------------------------------------------------------------------===//
9226586Sdim//
10226586Sdim//  This file provides internal definitions used in the AST reader.
11226586Sdim//
12226586Sdim//===----------------------------------------------------------------------===//
13226586Sdim#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
14226586Sdim#define LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
15226586Sdim
16249423Sdim#include "clang/AST/DeclarationName.h"
17226586Sdim#include "clang/Basic/OnDiskHashTable.h"
18249423Sdim#include "clang/Serialization/ASTBitCodes.h"
19234353Sdim#include "llvm/Support/Endian.h"
20249423Sdim#include <sys/stat.h>
21226586Sdim#include <utility>
22226586Sdim
23226586Sdimnamespace clang {
24226586Sdim
25226586Sdimclass ASTReader;
26226586Sdimclass HeaderSearch;
27226586Sdimstruct HeaderFileInfo;
28249423Sdimclass FileEntry;
29226586Sdim
30226586Sdimnamespace serialization {
31226586Sdim
32234353Sdimclass ModuleFile;
33226586Sdim
34226586Sdimnamespace reader {
35226586Sdim
36226586Sdim/// \brief Class that performs name lookup into a DeclContext stored
37226586Sdim/// in an AST file.
38226586Sdimclass ASTDeclContextNameLookupTrait {
39226586Sdim  ASTReader &Reader;
40234353Sdim  ModuleFile &F;
41226586Sdim
42226586Sdimpublic:
43226586Sdim  /// \brief Pair of begin/end iterators for DeclIDs.
44226586Sdim  ///
45226586Sdim  /// Note that these declaration IDs are local to the module that contains this
46226586Sdim  /// particular lookup t
47234353Sdim  typedef llvm::support::ulittle32_t LE32DeclID;
48234353Sdim  typedef std::pair<LE32DeclID *, LE32DeclID *> data_type;
49226586Sdim
50226586Sdim  /// \brief Special internal key for declaration names.
51226586Sdim  /// The hash table creates keys for comparison; we do not create
52226586Sdim  /// a DeclarationName for the internal key to avoid deserializing types.
53226586Sdim  struct DeclNameKey {
54226586Sdim    DeclarationName::NameKind Kind;
55226586Sdim    uint64_t Data;
56226586Sdim    DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
57226586Sdim  };
58226586Sdim
59226586Sdim  typedef DeclarationName external_key_type;
60226586Sdim  typedef DeclNameKey internal_key_type;
61226586Sdim
62234982Sdim  explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
63226586Sdim    : Reader(Reader), F(F) { }
64226586Sdim
65226586Sdim  static bool EqualKey(const internal_key_type& a,
66226586Sdim                       const internal_key_type& b) {
67226586Sdim    return a.Kind == b.Kind && a.Data == b.Data;
68226586Sdim  }
69226586Sdim
70226586Sdim  unsigned ComputeHash(const DeclNameKey &Key) const;
71226586Sdim  internal_key_type GetInternalKey(const external_key_type& Name) const;
72226586Sdim
73234982Sdim  static std::pair<unsigned, unsigned>
74226586Sdim  ReadKeyDataLength(const unsigned char*& d);
75226586Sdim
76226586Sdim  internal_key_type ReadKey(const unsigned char* d, unsigned);
77226586Sdim
78226586Sdim  data_type ReadData(internal_key_type, const unsigned char* d,
79226586Sdim                     unsigned DataLen);
80226586Sdim};
81226586Sdim
82249423Sdim/// \brief Base class for the trait describing the on-disk hash table for the
83249423Sdim/// identifiers in an AST file.
84249423Sdim///
85249423Sdim/// This class is not useful by itself; rather, it provides common
86249423Sdim/// functionality for accessing the on-disk hash table of identifiers
87249423Sdim/// in an AST file. Different subclasses customize that functionality
88249423Sdim/// based on what information they are interested in. Those subclasses
89249423Sdim/// must provide the \c data_type typedef and the ReadData operation,
90249423Sdim/// only.
91249423Sdimclass ASTIdentifierLookupTraitBase {
92249423Sdimpublic:
93249423Sdim  typedef StringRef external_key_type;
94249423Sdim  typedef StringRef internal_key_type;
95249423Sdim
96249423Sdim
97249423Sdim  static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
98249423Sdim    return a == b;
99249423Sdim  }
100249423Sdim
101249423Sdim  static unsigned ComputeHash(const internal_key_type& a);
102249423Sdim
103249423Sdim  static std::pair<unsigned, unsigned>
104249423Sdim  ReadKeyDataLength(const unsigned char*& d);
105249423Sdim
106249423Sdim  // This hopefully will just get inlined and removed by the optimizer.
107249423Sdim  static const internal_key_type&
108249423Sdim  GetInternalKey(const external_key_type& x) { return x; }
109249423Sdim
110249423Sdim  // This hopefully will just get inlined and removed by the optimizer.
111249423Sdim  static const external_key_type&
112249423Sdim  GetExternalKey(const internal_key_type& x) { return x; }
113249423Sdim
114249423Sdim  static internal_key_type ReadKey(const unsigned char* d, unsigned n);
115249423Sdim};
116249423Sdim
117226586Sdim/// \brief Class that performs lookup for an identifier stored in an AST file.
118249423Sdimclass ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
119226586Sdim  ASTReader &Reader;
120234353Sdim  ModuleFile &F;
121226586Sdim
122226586Sdim  // If we know the IdentifierInfo in advance, it is here and we will
123226586Sdim  // not build a new one. Used when deserializing information about an
124226586Sdim  // identifier that was constructed before the AST file was read.
125226586Sdim  IdentifierInfo *KnownII;
126226586Sdim
127226586Sdimpublic:
128226586Sdim  typedef IdentifierInfo * data_type;
129226586Sdim
130234353Sdim  ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
131226586Sdim                           IdentifierInfo *II = 0)
132226586Sdim    : Reader(Reader), F(F), KnownII(II) { }
133249423Sdim
134249423Sdim  data_type ReadData(const internal_key_type& k,
135249423Sdim                     const unsigned char* d,
136249423Sdim                     unsigned DataLen);
137226586Sdim
138234353Sdim  ASTReader &getReader() const { return Reader; }
139226586Sdim};
140226586Sdim
141226586Sdim/// \brief The on-disk hash table used to contain information about
142226586Sdim/// all of the identifiers in the program.
143226586Sdimtypedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
144226586Sdim  ASTIdentifierLookupTable;
145226586Sdim
146226586Sdim/// \brief Class that performs lookup for a selector's entries in the global
147226586Sdim/// method pool stored in an AST file.
148226586Sdimclass ASTSelectorLookupTrait {
149226586Sdim  ASTReader &Reader;
150234353Sdim  ModuleFile &F;
151226586Sdim
152226586Sdimpublic:
153226586Sdim  struct data_type {
154226586Sdim    SelectorID ID;
155251662Sdim    unsigned InstanceBits;
156251662Sdim    unsigned FactoryBits;
157249423Sdim    SmallVector<ObjCMethodDecl *, 2> Instance;
158249423Sdim    SmallVector<ObjCMethodDecl *, 2> Factory;
159226586Sdim  };
160226586Sdim
161226586Sdim  typedef Selector external_key_type;
162226586Sdim  typedef external_key_type internal_key_type;
163226586Sdim
164234353Sdim  ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
165226586Sdim    : Reader(Reader), F(F) { }
166226586Sdim
167226586Sdim  static bool EqualKey(const internal_key_type& a,
168226586Sdim                       const internal_key_type& b) {
169226586Sdim    return a == b;
170226586Sdim  }
171226586Sdim
172226586Sdim  static unsigned ComputeHash(Selector Sel);
173226586Sdim
174226586Sdim  static const internal_key_type&
175226586Sdim  GetInternalKey(const external_key_type& x) { return x; }
176226586Sdim
177226586Sdim  static std::pair<unsigned, unsigned>
178226586Sdim  ReadKeyDataLength(const unsigned char*& d);
179226586Sdim
180226586Sdim  internal_key_type ReadKey(const unsigned char* d, unsigned);
181226586Sdim  data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
182226586Sdim};
183226586Sdim
184226586Sdim/// \brief The on-disk hash table used for the global method pool.
185226586Sdimtypedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
186226586Sdim  ASTSelectorLookupTable;
187226586Sdim
188226586Sdim/// \brief Trait class used to search the on-disk hash table containing all of
189226586Sdim/// the header search information.
190226586Sdim///
191226586Sdim/// The on-disk hash table contains a mapping from each header path to
192226586Sdim/// information about that header (how many times it has been included, its
193226586Sdim/// controlling macro, etc.). Note that we actually hash based on the
194226586Sdim/// filename, and support "deep" comparisons of file names based on current
195226586Sdim/// inode numbers, so that the search can cope with non-normalized path names
196226586Sdim/// and symlinks.
197226586Sdimclass HeaderFileInfoTrait {
198226586Sdim  ASTReader &Reader;
199234353Sdim  ModuleFile &M;
200226586Sdim  HeaderSearch *HS;
201226586Sdim  const char *FrameworkStrings;
202249423Sdim
203226586Sdimpublic:
204249423Sdim  typedef const FileEntry *external_key_type;
205249423Sdim
206249423Sdim  struct internal_key_type {
207249423Sdim    off_t Size;
208249423Sdim    time_t ModTime;
209249423Sdim    const char *Filename;
210249423Sdim  };
211249423Sdim  typedef const internal_key_type &internal_key_ref;
212226586Sdim
213226586Sdim  typedef HeaderFileInfo data_type;
214226586Sdim
215234353Sdim  HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
216249423Sdim                      const char *FrameworkStrings)
217249423Sdim  : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) { }
218226586Sdim
219249423Sdim  static unsigned ComputeHash(internal_key_ref ikey);
220249423Sdim  static internal_key_type GetInternalKey(const FileEntry *FE);
221249423Sdim  bool EqualKey(internal_key_ref a, internal_key_ref b);
222226586Sdim
223226586Sdim  static std::pair<unsigned, unsigned>
224226586Sdim  ReadKeyDataLength(const unsigned char*& d);
225226586Sdim
226249423Sdim  static internal_key_type ReadKey(const unsigned char *d, unsigned);
227226586Sdim
228249423Sdim  data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
229226586Sdim};
230226586Sdim
231226586Sdim/// \brief The on-disk hash table used for known header files.
232226586Sdimtypedef OnDiskChainedHashTable<HeaderFileInfoTrait>
233226586Sdim  HeaderFileInfoLookupTable;
234226586Sdim
235226586Sdim} // end namespace clang::serialization::reader
236226586Sdim} // end namespace clang::serialization
237226586Sdim} // end namespace clang
238226586Sdim
239226586Sdim
240226586Sdim#endif
241