diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReaderInternals.h')
| -rw-r--r-- | clang/lib/Serialization/ASTReaderInternals.h | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReaderInternals.h b/clang/lib/Serialization/ASTReaderInternals.h new file mode 100644 index 000000000000..265a77fdb215 --- /dev/null +++ b/clang/lib/Serialization/ASTReaderInternals.h @@ -0,0 +1,292 @@ +//===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides internal definitions used in the AST reader. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H +#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H + +#include "MultiOnDiskHashTable.h" +#include "clang/AST/DeclarationName.h" +#include "clang/Basic/LLVM.h" +#include "clang/Serialization/ASTBitCodes.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/OnDiskHashTable.h" +#include <ctime> +#include <utility> + +namespace clang { + +class ASTReader; +class FileEntry; +struct HeaderFileInfo; +class HeaderSearch; +class IdentifierTable; +class ObjCMethodDecl; + +namespace serialization { + +class ModuleFile; + +namespace reader { + +/// Class that performs name lookup into a DeclContext stored +/// in an AST file. +class ASTDeclContextNameLookupTrait { + ASTReader &Reader; + ModuleFile &F; + +public: + // Maximum number of lookup tables we allow before condensing the tables. + static const int MaxTables = 4; + + /// The lookup result is a list of global declaration IDs. + using data_type = SmallVector<DeclID, 4>; + + struct data_type_builder { + data_type &Data; + llvm::DenseSet<DeclID> Found; + + data_type_builder(data_type &D) : Data(D) {} + + void insert(DeclID ID) { + // Just use a linear scan unless we have more than a few IDs. + if (Found.empty() && !Data.empty()) { + if (Data.size() <= 4) { + for (auto I : Found) + if (I == ID) + return; + Data.push_back(ID); + return; + } + + // Switch to tracking found IDs in the set. + Found.insert(Data.begin(), Data.end()); + } + + if (Found.insert(ID).second) + Data.push_back(ID); + } + }; + using hash_value_type = unsigned; + using offset_type = unsigned; + using file_type = ModuleFile *; + + using external_key_type = DeclarationName; + using internal_key_type = DeclarationNameKey; + + explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F) + : Reader(Reader), F(F) {} + + static bool EqualKey(const internal_key_type &a, const internal_key_type &b) { + return a == b; + } + + static hash_value_type ComputeHash(const internal_key_type &Key) { + return Key.getHash(); + } + + static internal_key_type GetInternalKey(const external_key_type &Name) { + return Name; + } + + static std::pair<unsigned, unsigned> + ReadKeyDataLength(const unsigned char *&d); + + internal_key_type ReadKey(const unsigned char *d, unsigned); + + void ReadDataInto(internal_key_type, const unsigned char *d, + unsigned DataLen, data_type_builder &Val); + + static void MergeDataInto(const data_type &From, data_type_builder &To) { + To.Data.reserve(To.Data.size() + From.size()); + for (DeclID ID : From) + To.insert(ID); + } + + file_type ReadFileRef(const unsigned char *&d); +}; + +struct DeclContextLookupTable { + MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table; +}; + +/// Base class for the trait describing the on-disk hash table for the +/// identifiers in an AST file. +/// +/// This class is not useful by itself; rather, it provides common +/// functionality for accessing the on-disk hash table of identifiers +/// in an AST file. Different subclasses customize that functionality +/// based on what information they are interested in. Those subclasses +/// must provide the \c data_type type and the ReadData operation, only. +class ASTIdentifierLookupTraitBase { +public: + using external_key_type = StringRef; + using internal_key_type = StringRef; + using hash_value_type = unsigned; + using offset_type = unsigned; + + static bool EqualKey(const internal_key_type& a, const internal_key_type& b) { + return a == b; + } + + static hash_value_type ComputeHash(const internal_key_type& a); + + static std::pair<unsigned, unsigned> + ReadKeyDataLength(const unsigned char*& d); + + // This hopefully will just get inlined and removed by the optimizer. + static const internal_key_type& + GetInternalKey(const external_key_type& x) { return x; } + + // This hopefully will just get inlined and removed by the optimizer. + static const external_key_type& + GetExternalKey(const internal_key_type& x) { return x; } + + static internal_key_type ReadKey(const unsigned char* d, unsigned n); +}; + +/// Class that performs lookup for an identifier stored in an AST file. +class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase { + ASTReader &Reader; + ModuleFile &F; + + // If we know the IdentifierInfo in advance, it is here and we will + // not build a new one. Used when deserializing information about an + // identifier that was constructed before the AST file was read. + IdentifierInfo *KnownII; + +public: + using data_type = IdentifierInfo *; + + ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F, + IdentifierInfo *II = nullptr) + : Reader(Reader), F(F), KnownII(II) {} + + data_type ReadData(const internal_key_type& k, + const unsigned char* d, + unsigned DataLen); + + IdentID ReadIdentifierID(const unsigned char *d); + + ASTReader &getReader() const { return Reader; } +}; + +/// The on-disk hash table used to contain information about +/// all of the identifiers in the program. +using ASTIdentifierLookupTable = + llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>; + +/// Class that performs lookup for a selector's entries in the global +/// method pool stored in an AST file. +class ASTSelectorLookupTrait { + ASTReader &Reader; + ModuleFile &F; + +public: + struct data_type { + SelectorID ID; + unsigned InstanceBits; + unsigned FactoryBits; + bool InstanceHasMoreThanOneDecl; + bool FactoryHasMoreThanOneDecl; + SmallVector<ObjCMethodDecl *, 2> Instance; + SmallVector<ObjCMethodDecl *, 2> Factory; + }; + + using external_key_type = Selector; + using internal_key_type = external_key_type; + using hash_value_type = unsigned; + using offset_type = unsigned; + + ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F) + : Reader(Reader), F(F) {} + + static bool EqualKey(const internal_key_type& a, + const internal_key_type& b) { + return a == b; + } + + static hash_value_type ComputeHash(Selector Sel); + + static const internal_key_type& + GetInternalKey(const external_key_type& x) { return x; } + + static std::pair<unsigned, unsigned> + ReadKeyDataLength(const unsigned char*& d); + + internal_key_type ReadKey(const unsigned char* d, unsigned); + data_type ReadData(Selector, const unsigned char* d, unsigned DataLen); +}; + +/// The on-disk hash table used for the global method pool. +using ASTSelectorLookupTable = + llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>; + +/// Trait class used to search the on-disk hash table containing all of +/// the header search information. +/// +/// The on-disk hash table contains a mapping from each header path to +/// information about that header (how many times it has been included, its +/// controlling macro, etc.). Note that we actually hash based on the size +/// and mtime, and support "deep" comparisons of file names based on current +/// inode numbers, so that the search can cope with non-normalized path names +/// and symlinks. +class HeaderFileInfoTrait { + ASTReader &Reader; + ModuleFile &M; + HeaderSearch *HS; + const char *FrameworkStrings; + +public: + using external_key_type = const FileEntry *; + + struct internal_key_type { + off_t Size; + time_t ModTime; + StringRef Filename; + bool Imported; + }; + + using internal_key_ref = const internal_key_type &; + + using data_type = HeaderFileInfo; + using hash_value_type = unsigned; + using offset_type = unsigned; + + HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS, + const char *FrameworkStrings) + : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {} + + static hash_value_type ComputeHash(internal_key_ref ikey); + internal_key_type GetInternalKey(const FileEntry *FE); + bool EqualKey(internal_key_ref a, internal_key_ref b); + + static std::pair<unsigned, unsigned> + ReadKeyDataLength(const unsigned char*& d); + + static internal_key_type ReadKey(const unsigned char *d, unsigned); + + data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen); +}; + +/// The on-disk hash table used for known header files. +using HeaderFileInfoLookupTable = + llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>; + +} // namespace reader + +} // namespace serialization + +} // namespace clang + +#endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H |
