mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[serialization] Lazily load top-level decls, extensions, and operators.
This switches from simple lists of decls to name-based on-disk hash tables, which allows decls to be loaded lazily when doing simple lookup (but not code completion, at least not yet). The on-disk hash table implementation is borrowed from Clang; eventually it will be pushed down to LLVM's Support library. (Fortunately the implementation is header-only.) This breaks a few tests that rely on magic protocols like IntegerLiteralConvertible, because the type checker won't have seen the types that conform to those protocols yet. This will be fixed by doing an additional "hey, modules, got any of these?" lookup. Swift SVN r7259
This commit is contained in:
@@ -33,6 +33,12 @@ namespace llvm {
|
||||
class MemoryBuffer;
|
||||
}
|
||||
|
||||
// This template should eventually move to llvm/Support.
|
||||
namespace clang {
|
||||
template <typename Info>
|
||||
class OnDiskChainedHashTable;
|
||||
}
|
||||
|
||||
namespace swift {
|
||||
class Pattern;
|
||||
class ProtocolConformance;
|
||||
@@ -163,22 +169,13 @@ private:
|
||||
/// Identifiers referenced by this module.
|
||||
std::vector<SerializedIdentifier> Identifiers;
|
||||
|
||||
/// All top-level decls in this module.
|
||||
llvm::DenseMap<Identifier, TinyPtrVector<ValueDecl *>> TopLevelDecls;
|
||||
private:
|
||||
class DeclTableInfo;
|
||||
using SerializedDeclTable = clang::OnDiskChainedHashTable<DeclTableInfo>;
|
||||
|
||||
/// An array of the top-level decl IDs.
|
||||
// FIXME: We don't really want to deserialize all of these at once.
|
||||
std::vector<serialization::DeclID> RawTopLevelIDs;
|
||||
|
||||
using OperatorKey = std::pair<Identifier, serialization::OperatorKind>;
|
||||
friend struct llvm::DenseMapInfo<OperatorKey>;
|
||||
|
||||
/// All the operators in the module.
|
||||
llvm::DenseMap<OperatorKey, OperatorDecl *> Operators;
|
||||
|
||||
/// An array of the top-level decl IDs.
|
||||
// FIXME: We don't really want to deserialize all of these at once.
|
||||
std::vector<serialization::DeclID> RawOperatorIDs;
|
||||
public:
|
||||
std::unique_ptr<SerializedDeclTable> TopLevelDecls;
|
||||
std::unique_ptr<SerializedDeclTable> OperatorDecls;
|
||||
|
||||
/// Whether this module file can be used.
|
||||
ModuleStatus Status;
|
||||
@@ -186,6 +183,9 @@ private:
|
||||
/// Constructs an new module and validates it.
|
||||
ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input);
|
||||
|
||||
// Out of line to avoid instantiation OnDiskChainedHashTable here.
|
||||
~ModuleFile();
|
||||
|
||||
/// Convenience function for module loading.
|
||||
void error(ModuleStatus issue = ModuleStatus::Malformed) {
|
||||
assert(issue != ModuleStatus::Valid &&
|
||||
@@ -277,7 +277,7 @@ public:
|
||||
/// \returns Whether the module was successfully loaded, or what went wrong
|
||||
/// if it was not.
|
||||
static ModuleStatus load(llvm::OwningPtr<llvm::MemoryBuffer> &&input,
|
||||
llvm::OwningPtr<ModuleFile> &module) {
|
||||
std::unique_ptr<ModuleFile> &module) {
|
||||
module.reset(new ModuleFile(std::move(input)));
|
||||
return module->getStatus();
|
||||
}
|
||||
@@ -317,6 +317,11 @@ public:
|
||||
void lookupVisibleDecls(Module::AccessPathTy accessPath,
|
||||
VisibleDeclConsumer &consumer,
|
||||
NLKind lookupKind);
|
||||
|
||||
/// Loads extensions for the given decl.
|
||||
///
|
||||
/// Note that this may cause other extensions to load as well.
|
||||
void loadExtensions(NominalTypeDecl *nominal);
|
||||
};
|
||||
|
||||
class SerializedModule : public LoadedModule {
|
||||
@@ -337,25 +342,4 @@ public:
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
namespace llvm {
|
||||
template<> struct DenseMapInfo<swift::ModuleFile::OperatorKey> {
|
||||
using OperatorKey = swift::ModuleFile::OperatorKey;
|
||||
using Identifier = swift::Identifier;
|
||||
|
||||
static OperatorKey getEmptyKey() {
|
||||
return OperatorKey(Identifier(), swift::serialization::Prefix);
|
||||
}
|
||||
static OperatorKey getTombstoneKey() {
|
||||
return OperatorKey(Identifier(), swift::serialization::Postfix);
|
||||
}
|
||||
static unsigned getHashValue(OperatorKey Val) {
|
||||
using RawPair = std::pair<Identifier, unsigned>;
|
||||
return DenseMapInfo<RawPair>::getHashValue(RawPair(Val));
|
||||
}
|
||||
static bool isEqual(OperatorKey LHS, OperatorKey RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user