AST: Clean up some more duplication using the new GenericContext

This commit is contained in:
Slava Pestov
2017-02-19 20:26:25 -08:00
parent fe16cf869d
commit b319a3aa32
6 changed files with 39 additions and 123 deletions

View File

@@ -58,13 +58,13 @@ namespace swift {
class ExtensionDecl;
class ForeignRepresentationInfo;
class FuncDecl;
class GenericContext;
class InFlightDiagnostic;
class IterableDeclContext;
class LazyAbstractFunctionData;
class LazyGenericTypeData;
class LazyContextData;
class LazyMemberLoader;
class LazyGenericContextData;
class LazyIterableDeclContextData;
class LazyMemberLoader;
class LazyResolver;
class PatternBindingDecl;
class PatternBindingInitializer;
@@ -722,25 +722,16 @@ public:
/// \param lazyLoader If non-null, the lazy loader to use when creating the
/// lazy data. The pointer must either be null or be consistent
/// across all calls for the same \p func.
LazyContextData *getOrCreateLazyContextData(const Decl *decl,
LazyContextData *getOrCreateLazyContextData(const DeclContext *decl,
LazyMemberLoader *lazyLoader);
/// Get the lazy function data for the given generic type.
///
/// \param lazyLoader If non-null, the lazy loader to use when creating the
/// generic type data. The pointer must either be null or be consistent
/// across all calls for the same \p type.
LazyGenericTypeData *getOrCreateLazyGenericTypeData(
const GenericTypeDecl *type,
LazyMemberLoader *lazyLoader);
/// Get the lazy function data for the given abstract function.
/// Get the lazy function data for the given generic context.
///
/// \param lazyLoader If non-null, the lazy loader to use when creating the
/// function data. The pointer must either be null or be consistent
/// across all calls for the same \p func.
LazyAbstractFunctionData *getOrCreateLazyFunctionContextData(
const AbstractFunctionDecl *func,
LazyGenericContextData *getOrCreateLazyGenericContextData(
const GenericContext *dc,
LazyMemberLoader *lazyLoader);
/// Get the lazy iterable context for the given iterable declaration context.

View File

@@ -191,22 +191,15 @@ public:
LazyMemberLoader *loader;
};
/// Context data for abstract function declarations.
class LazyAbstractFunctionData : public LazyContextData {
public:
/// The context data used for loading the generic environment.
uint64_t genericEnvData = 0;
};
/// Context data for generic type declarations.
class LazyGenericTypeData : public LazyContextData {
/// Context data for generic contexts.
class LazyGenericContextData : public LazyContextData {
public:
/// The context data used for loading the generic environment.
uint64_t genericEnvData = 0;
};
/// Context data for iterable decl contexts.
class LazyIterableDeclContextData : public LazyGenericTypeData {
class LazyIterableDeclContextData : public LazyGenericContextData {
public:
/// The context data used for loading all of the members of the iterable
/// context.
@@ -254,7 +247,7 @@ public:
}
/// Returns the generic environment.
virtual GenericEnvironment *loadGenericEnvironment(const Decl *decl,
virtual GenericEnvironment *loadGenericEnvironment(const DeclContext *decl,
uint64_t contextData) {
llvm_unreachable("unimplemented");
}

View File

@@ -507,8 +507,7 @@ private:
/// Set up a (potentially lazy) generic environment for the given type,
/// function or extension.
void configureGenericEnvironment(
llvm::PointerUnion3<GenericTypeDecl *, ExtensionDecl *,
AbstractFunctionDecl *> genericDecl,
GenericContext *genericDecl,
serialization::GenericEnvironmentID envID);
/// Populates the vector with members of a DeclContext from \c DeclTypeCursor.
@@ -711,7 +710,7 @@ public:
virtual void finishNormalConformance(NormalProtocolConformance *conformance,
uint64_t contextData) override;
GenericEnvironment *loadGenericEnvironment(const Decl *decl,
GenericEnvironment *loadGenericEnvironment(const DeclContext *decl,
uint64_t contextData) override;
Optional<StringRef> getGroupNameById(unsigned Id) const;

View File

@@ -206,7 +206,7 @@ struct ASTContext::Implementation {
DelayedConformanceDiags;
/// Stores information about lazy deserialization of various declarations.
llvm::DenseMap<const Decl *, LazyContextData *> LazyContexts;
llvm::DenseMap<const DeclContext *, LazyContextData *> LazyContexts;
/// Stored generic signature builders for canonical generic signatures.
llvm::DenseMap<std::pair<GenericSignature *, ModuleDecl *>,
@@ -1477,9 +1477,9 @@ ASTContext::getInheritedConformance(Type type, ProtocolConformance *inherited) {
}
LazyContextData *ASTContext::getOrCreateLazyContextData(
const Decl *decl,
const DeclContext *dc,
LazyMemberLoader *lazyLoader) {
auto known = Impl.LazyContexts.find(decl);
auto known = Impl.LazyContexts.find(dc);
if (known != Impl.LazyContexts.end()) {
// Make sure we didn't provide an incompatible lazy loader.
assert(!lazyLoader || lazyLoader == known->second->loader);
@@ -1488,32 +1488,20 @@ LazyContextData *ASTContext::getOrCreateLazyContextData(
// Create new lazy iterable context data with the given loader.
assert(lazyLoader && "Queried lazy data for non-lazy iterable context");
if (isa<NominalTypeDecl>(decl) || isa<ExtensionDecl>(decl)) {
if (isa<NominalTypeDecl>(dc) || isa<ExtensionDecl>(dc)) {
auto *contextData = Allocate<LazyIterableDeclContextData>();
contextData->loader = lazyLoader;
Impl.LazyContexts[decl] = contextData;
Impl.LazyContexts[dc] = contextData;
return contextData;
}
// Create new lazy generic type data with the given loader.
if (isa<GenericTypeDecl>(decl)) {
auto *contextData = Allocate<LazyGenericTypeData>();
// Create new lazy generic context data with the given loader.
auto *contextData = Allocate<LazyGenericContextData>();
contextData->loader = lazyLoader;
Impl.LazyContexts[decl] = contextData;
Impl.LazyContexts[dc] = contextData;
return contextData;
}
// Create new lazy function context data with the given loader.
if (isa<AbstractFunctionDecl>(decl)) {
auto *contextData = Allocate<LazyAbstractFunctionData>();
contextData->loader = lazyLoader;
Impl.LazyContexts[decl] = contextData;
return contextData;
}
llvm_unreachable("unhandled lazy context");
}
LazyIterableDeclContextData *ASTContext::getOrCreateLazyIterableContextData(
const IterableDeclContext *idc,
LazyMemberLoader *lazyLoader) {
@@ -1527,18 +1515,13 @@ LazyIterableDeclContextData *ASTContext::getOrCreateLazyIterableContextData(
lazyLoader);
}
LazyAbstractFunctionData *ASTContext::getOrCreateLazyFunctionContextData(
const AbstractFunctionDecl *func,
LazyGenericContextData *ASTContext::getOrCreateLazyGenericContextData(
const GenericContext *dc,
LazyMemberLoader *lazyLoader) {
return (LazyAbstractFunctionData *)getOrCreateLazyContextData(func,
return (LazyGenericContextData *)getOrCreateLazyContextData(dc,
lazyLoader);
}
LazyGenericTypeData *ASTContext::getOrCreateLazyGenericTypeData(
const GenericTypeDecl *type,
LazyMemberLoader *lazyLoader) {
return (LazyGenericTypeData *)getOrCreateLazyContextData(type, lazyLoader);
}
void ASTContext::addDelayedConformanceDiag(
NormalProtocolConformance *conformance,
DelayedConformanceDiag fn) {

View File

@@ -592,26 +592,10 @@ GenericContext::getLazyGenericEnvironmentSlow() const {
assert(GenericSigOrEnv.is<GenericSignature *>() &&
"not a lazily deserialized generic environment");
GenericEnvironment *genericEnv;
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(this)) {
auto contextData = getASTContext().getOrCreateLazyIterableContextData(
extensionDecl, nullptr);
genericEnv = contextData->loader->loadGenericEnvironment(
extensionDecl, contextData->genericEnvData);
} else if (auto *typeDecl = dyn_cast<GenericTypeDecl>(this)) {
auto contextData = getASTContext().getOrCreateLazyGenericTypeData(
typeDecl, nullptr);
genericEnv = contextData->loader->loadGenericEnvironment(
typeDecl, contextData->genericEnvData);
} else if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(this)) {
auto contextData = getASTContext().getOrCreateLazyFunctionContextData(
funcDecl, nullptr);
genericEnv = contextData->loader->loadGenericEnvironment(
funcDecl, contextData->genericEnvData);
} else {
llvm_unreachable("Bad GenericContext kind");
}
auto contextData = getASTContext().getOrCreateLazyGenericContextData(
this, nullptr);
auto *genericEnv = contextData->loader->loadGenericEnvironment(
this, contextData->genericEnvData);
const_cast<GenericContext *>(this)->setGenericEnvironment(genericEnv);
++NumLazyGenericEnvironmentsLoaded;
@@ -624,24 +608,9 @@ void GenericContext::setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
assert(GenericSigOrEnv.isNull() && "already have a generic signature");
GenericSigOrEnv = genericSig;
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(this)) {
auto contextData =
getASTContext().getOrCreateLazyIterableContextData(
extensionDecl, lazyLoader);
getASTContext().getOrCreateLazyGenericContextData(this, lazyLoader);
contextData->genericEnvData = genericEnvData;
} else if (auto *typeDecl = dyn_cast<GenericTypeDecl>(this)) {
auto contextData =
getASTContext().getOrCreateLazyGenericTypeData(
typeDecl, lazyLoader);
contextData->genericEnvData = genericEnvData;
} else if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(this)) {
auto contextData =
getASTContext().getOrCreateLazyFunctionContextData(
funcDecl, lazyLoader);
contextData->genericEnvData = genericEnvData;
} else {
llvm_unreachable("Bad GenericContext kind");
}
++NumLazyGenericEnvironments;
}

View File

@@ -992,8 +992,7 @@ void ModuleFile::readGenericRequirements(
}
void ModuleFile::configureGenericEnvironment(
llvm::PointerUnion3<GenericTypeDecl *, ExtensionDecl *,
AbstractFunctionDecl *> genericDecl,
GenericContext *genericDecl,
serialization::GenericEnvironmentID envID) {
if (envID == 0) return;
@@ -1002,33 +1001,15 @@ void ModuleFile::configureGenericEnvironment(
// If we just have a generic signature, set up lazy generic environment
// creation.
if (auto genericSig = sigOrEnv.dyn_cast<GenericSignature *>()) {
if (auto type = genericDecl.dyn_cast<GenericTypeDecl *>()) {
type->setLazyGenericEnvironment(this, genericSig, envID);
DelayedGenericEnvironments.push_back(type);
} else if (auto func = genericDecl.dyn_cast<AbstractFunctionDecl *>()) {
func->setLazyGenericEnvironment(this, genericSig, envID);
DelayedGenericEnvironments.push_back(func);
} else {
auto ext = genericDecl.get<ExtensionDecl *>();
ext->setLazyGenericEnvironment(this, genericSig, envID);
DelayedGenericEnvironments.push_back(ext);
}
genericDecl->setLazyGenericEnvironment(this, genericSig, envID);
DelayedGenericEnvironments.push_back(genericDecl);
return;
}
// If we have a full generic environment, it's because it happened to be
// deserialized already. Record it directly.
if (auto genericEnv = sigOrEnv.dyn_cast<GenericEnvironment *>()) {
if (auto type = genericDecl.dyn_cast<GenericTypeDecl *>()) {
type->setGenericEnvironment(genericEnv);
} else if (auto func = genericDecl.dyn_cast<AbstractFunctionDecl *>()) {
func->setGenericEnvironment(genericEnv);
} else {
auto ext = genericDecl.get<ExtensionDecl *>();
ext->setGenericEnvironment(genericEnv);
}
genericDecl->setGenericEnvironment(genericEnv);
return;
}
}
@@ -4441,7 +4422,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
}
}
GenericEnvironment *ModuleFile::loadGenericEnvironment(const Decl *decl,
GenericEnvironment *ModuleFile::loadGenericEnvironment(const DeclContext *decl,
uint64_t contextData) {
return getGenericEnvironment(contextData);
}