summaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTReaderInternals.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReaderInternals.h')
-rw-r--r--clang/lib/Serialization/ASTReaderInternals.h292
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