AST: Introduce new GenericContext base class

This is in preparation for generic subscripts, which will also
expose methods like getGenericSignature(), and so on.

ExtensionDecl, GenericTypeDecl and AbstractFunctionDecl all share
code. Instead of copy and pasting it yet again into SubscriptDecl,
factor it out into a common base class.

There are more yaks to shave here, but this is a step in the right
direction.
This commit is contained in:
Slava Pestov
2017-02-17 22:49:09 -08:00
parent b925ee9acb
commit ad78604e32
2 changed files with 185 additions and 356 deletions

View File

@@ -1374,6 +1374,82 @@ public:
} }
}; };
class GenericContext : public DeclContext {
private:
GenericParamList *GenericParams = nullptr;
/// The trailing where clause.
///
/// Note that this is not currently serialized, because semantic analysis
/// moves the trailing where clause into the generic parameter list.
TrailingWhereClause *TrailingWhere = nullptr;
/// The generic signature or environment of this declaration.
///
/// When this declaration stores only a signature, the generic
/// environment will be lazily loaded.
mutable llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
GenericSigOrEnv;
/// Lazily populate the generic environment.
GenericEnvironment *getLazyGenericEnvironmentSlow() const;
protected:
GenericContext(DeclContextKind Kind, DeclContext *Parent)
: DeclContext(Kind, Parent) { }
public:
/// \brief Retrieve the set of parameters to a generic subscript, or null if
/// this subscript is not generic.
GenericParamList *getGenericParams() const { return GenericParams; }
void setGenericParams(GenericParamList *GenericParams);
/// \brief Determine whether this subscript has generic parameters
/// of its own.
bool isGeneric() const { return GenericParams != nullptr; }
/// Retrieve the trailing where clause for this extension, if any.
TrailingWhereClause *getTrailingWhereClause() const {
return TrailingWhere;
}
/// Set the trailing where clause for this extension.
void setTrailingWhereClause(TrailingWhereClause *trailingWhereClause) {
TrailingWhere = trailingWhereClause;
}
/// Retrieve the generic signature for this subscript.
GenericSignature *getGenericSignature() const;
/// Retrieve the generic context for this subscript.
GenericEnvironment *getGenericEnvironment() const;
/// Retrieve the innermost generic parameter types.
ArrayRef<GenericTypeParamType *> getInnermostGenericParamTypes() const {
if (auto sig = getGenericSignature())
return sig->getInnermostGenericParams();
else
return { };
}
/// Retrieve the generic requirements.
ArrayRef<Requirement> getGenericRequirements() const {
if (auto sig = getGenericSignature())
return sig->getRequirements();
else
return { };
}
/// Set a lazy generic environment.
void setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData);
/// Set the generic context of this subscript.
void setGenericEnvironment(GenericEnvironment *genericEnv);
};
/// Describes what kind of name is being imported. /// Describes what kind of name is being imported.
/// ///
/// If the enumerators here are changed, make sure to update all diagnostics /// If the enumerators here are changed, make sure to update all diagnostics
@@ -1483,7 +1559,7 @@ public:
/// ExtensionDecl - This represents a type extension containing methods /// ExtensionDecl - This represents a type extension containing methods
/// associated with the type. This is not a ValueDecl and has no Type because /// associated with the type. This is not a ValueDecl and has no Type because
/// there are no runtime values of the Extension's type. /// there are no runtime values of the Extension's type.
class ExtensionDecl final : public Decl, public DeclContext, class ExtensionDecl final : public Decl, public GenericContext,
public IterableDeclContext { public IterableDeclContext {
SourceLoc ExtensionLoc; // Location of 'extension' keyword. SourceLoc ExtensionLoc; // Location of 'extension' keyword.
SourceRange Braces; SourceRange Braces;
@@ -1491,24 +1567,8 @@ class ExtensionDecl final : public Decl, public DeclContext,
/// The type being extended. /// The type being extended.
TypeLoc ExtendedType; TypeLoc ExtendedType;
/// The generic parameters of the extension.
GenericParamList *GenericParams = nullptr;
/// The generic signature or environment of this extension.
///
/// When this extension stores only a signature, the generic environment
/// will be lazily loaded.
mutable llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
GenericSigOrEnv;
MutableArrayRef<TypeLoc> Inherited; MutableArrayRef<TypeLoc> Inherited;
/// The trailing where clause.
///
/// Note that this is not currently serialized, because semantic analysis
/// moves the trailing where clause into the generic parameter list.
TrailingWhereClause *TrailingWhere;
/// \brief The next extension in the linked list of extensions. /// \brief The next extension in the linked list of extensions.
/// ///
/// The bit indicates whether this extension has been resolved to refer to /// The bit indicates whether this extension has been resolved to refer to
@@ -1543,9 +1603,6 @@ class ExtensionDecl final : public Decl, public DeclContext,
/// Slow path for \c takeConformanceLoader(). /// Slow path for \c takeConformanceLoader().
std::pair<LazyMemberLoader *, uint64_t> takeConformanceLoaderSlow(); std::pair<LazyMemberLoader *, uint64_t> takeConformanceLoaderSlow();
/// Lazily populate the generic environment.
GenericEnvironment *getLazyGenericEnvironmentSlow() const;
public: public:
using Decl::getASTContext; using Decl::getASTContext;
@@ -1566,45 +1623,6 @@ public:
SourceRange getBraces() const { return Braces; } SourceRange getBraces() const { return Braces; }
void setBraces(SourceRange braces) { Braces = braces; } void setBraces(SourceRange braces) { Braces = braces; }
/// Retrieve the innermost generic parameter list.
GenericParamList *getGenericParams() const {
return GenericParams;
}
void setGenericParams(GenericParamList *params);
/// Retrieve the trailing where clause for this extension, if any.
TrailingWhereClause *getTrailingWhereClause() const {
return TrailingWhere;
}
/// Set the trailing where clause for this extension.
void setTrailingWhereClause(TrailingWhereClause *trailingWhereClause) {
TrailingWhere = trailingWhereClause;
}
/// Retrieve the generic requirements.
ArrayRef<Requirement> getGenericRequirements() const {
if (auto sig = getGenericSignature())
return sig->getRequirements();
else
return { };
}
/// Retrieve the generic signature for this type.
GenericSignature *getGenericSignature() const;
/// Retrieve the generic context for this type.
GenericEnvironment *getGenericEnvironment() const;
/// Set a lazy generic environment.
void setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData);
/// Set the generic context of this extension.
void setGenericEnvironment(GenericEnvironment *genericEnv);
/// Retrieve the type being extended. /// Retrieve the type being extended.
Type getExtendedType() const { return ExtendedType.getType(); } Type getExtendedType() const { return ExtendedType.getType(); }
@@ -2351,61 +2369,13 @@ public:
/// A type declaration that can have generic parameters attached to it. Because /// A type declaration that can have generic parameters attached to it. Because
/// it has these generic parameters, it is always a DeclContext. /// it has these generic parameters, it is always a DeclContext.
class GenericTypeDecl : public TypeDecl, public DeclContext { class GenericTypeDecl : public TypeDecl, public GenericContext {
GenericParamList *GenericParams = nullptr;
/// The generic signature or environment of this type.
///
/// When this function stores only a signature, the generic environment
/// will be lazily loaded.
mutable llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
GenericSigOrEnv;
/// Lazily populate the generic environment.
GenericEnvironment *getLazyGenericEnvironmentSlow() const;
public: public:
GenericTypeDecl(DeclKind K, DeclContext *DC, GenericTypeDecl(DeclKind K, DeclContext *DC,
Identifier name, SourceLoc nameLoc, Identifier name, SourceLoc nameLoc,
MutableArrayRef<TypeLoc> inherited, MutableArrayRef<TypeLoc> inherited,
GenericParamList *GenericParams); GenericParamList *GenericParams);
GenericParamList *getGenericParams() const { return GenericParams; }
/// Provide the set of parameters to a generic type, or null if
/// this function is not generic.
void setGenericParams(GenericParamList *params);
/// Retrieve the innermost generic parameter types.
ArrayRef<GenericTypeParamType *> getInnermostGenericParamTypes() const {
if (auto sig = getGenericSignature())
return sig->getInnermostGenericParams();
else
return { };
}
/// Retrieve the generic requirements.
ArrayRef<Requirement> getGenericRequirements() const {
if (auto sig = getGenericSignature())
return sig->getRequirements();
else
return { };
}
/// Retrieve the generic signature for this type.
GenericSignature *getGenericSignature() const;
/// Retrieve the generic context for this type.
GenericEnvironment *getGenericEnvironment() const;
/// Set a lazy generic environment.
void setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData);
/// Set the generic context of this function.
void setGenericEnvironment(GenericEnvironment *genericEnv);
// Resolve ambiguity due to multiple base classes. // Resolve ambiguity due to multiple base classes.
using TypeDecl::getASTContext; using TypeDecl::getASTContext;
using DeclContext::operator new; using DeclContext::operator new;
@@ -4639,7 +4609,7 @@ struct ImportAsMemberStatus {
}; };
/// \brief Base class for function-like declarations. /// \brief Base class for function-like declarations.
class AbstractFunctionDecl : public ValueDecl, public DeclContext { class AbstractFunctionDecl : public ValueDecl, public GenericContext {
public: public:
enum class BodyKind { enum class BodyKind {
/// The function did not have a body in the source code file. /// The function did not have a body in the source code file.
@@ -4690,15 +4660,6 @@ protected:
SourceRange BodyRange; SourceRange BodyRange;
}; };
GenericParamList *GenericParams;
/// The generic signature or environment of this function.
///
/// When this function stores only a signature, the generic environment
/// will be lazily loaded.
mutable llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
GenericSigOrEnv;
CaptureInfo Captures; CaptureInfo Captures;
/// Location of the 'throws' token. /// Location of the 'throws' token.
@@ -4711,8 +4672,8 @@ protected:
unsigned NumParameterLists, unsigned NumParameterLists,
GenericParamList *GenericParams) GenericParamList *GenericParams)
: ValueDecl(Kind, Parent, Name, NameLoc), : ValueDecl(Kind, Parent, Name, NameLoc),
DeclContext(DeclContextKind::AbstractFunctionDecl, Parent), GenericContext(DeclContextKind::AbstractFunctionDecl, Parent),
Body(nullptr), GenericParams(nullptr), ThrowsLoc(ThrowsLoc) { Body(nullptr), ThrowsLoc(ThrowsLoc) {
setBodyKind(BodyKind::None); setBodyKind(BodyKind::None);
setGenericParams(GenericParams); setGenericParams(GenericParams);
AbstractFunctionDeclBits.NumParameterLists = NumParameterLists; AbstractFunctionDeclBits.NumParameterLists = NumParameterLists;
@@ -4727,30 +4688,11 @@ protected:
AbstractFunctionDeclBits.BodyKind = unsigned(K); AbstractFunctionDeclBits.BodyKind = unsigned(K);
} }
void setGenericParams(GenericParamList *GenericParams);
/// Lazily populate the generic environment.
GenericEnvironment *getLazyGenericEnvironmentSlow() const;
public: public:
/// \brief Should this declaration be treated as if annotated with transparent /// \brief Should this declaration be treated as if annotated with transparent
/// attribute. /// attribute.
bool isTransparent() const; bool isTransparent() const;
/// Retrieve the generic signature for this function.
GenericSignature *getGenericSignature() const;
/// Retrieve the generic context for this function.
GenericEnvironment *getGenericEnvironment() const;
/// Set a lazy generic environment.
void setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData);
/// Set the generic context of this function.
void setGenericEnvironment(GenericEnvironment *genericEnv);
// Expose our import as member status // Expose our import as member status
bool isImportAsMember() const { return IAMStatus.isImportAsMember(); } bool isImportAsMember() const { return IAMStatus.isImportAsMember(); }
bool isImportAsInstanceMember() const { return IAMStatus.isInstance(); } bool isImportAsInstanceMember() const { return IAMStatus.isInstance(); }
@@ -4930,14 +4872,6 @@ public:
} }
ParamDecl *getImplicitSelfDecl(); ParamDecl *getImplicitSelfDecl();
/// \brief Retrieve the set of parameters to a generic function, or null if
/// this function is not generic.
GenericParamList *getGenericParams() const { return GenericParams; }
/// \brief Determine whether this is a generic function, which can only be
/// used when each of the archetypes is bound to a particular concrete type.
bool isGeneric() const { return GenericParams != nullptr; }
/// Retrieve the declaration that this method overrides, if any. /// Retrieve the declaration that this method overrides, if any.
AbstractFunctionDecl *getOverriddenDecl() const; AbstractFunctionDecl *getOverriddenDecl() const;

View File

@@ -546,6 +546,106 @@ TrailingWhereClause *TrailingWhereClause::create(
return new (mem) TrailingWhereClause(whereLoc, requirements); return new (mem) TrailingWhereClause(whereLoc, requirements);
} }
void GenericContext::setGenericParams(GenericParamList *params) {
GenericParams = params;
if (GenericParams) {
for (auto param : *GenericParams)
param->setDeclContext(this);
}
}
GenericSignature *GenericContext::getGenericSignature() const {
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv->getGenericSignature();
if (auto genericSig = GenericSigOrEnv.dyn_cast<GenericSignature *>())
return genericSig;
return nullptr;
}
GenericEnvironment *GenericContext::getGenericEnvironment() const {
// Fast case: we already have a generic environment.
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv;
// If we only have a generic signature, build the generic environment.
if (GenericSigOrEnv.dyn_cast<GenericSignature *>())
return getLazyGenericEnvironmentSlow();
return nullptr;
}
void GenericContext::setGenericEnvironment(GenericEnvironment *genericEnv) {
assert((GenericSigOrEnv.isNull() ||
getGenericSignature()->getCanonicalSignature() ==
genericEnv->getGenericSignature()->getCanonicalSignature()) &&
"set a generic environment with a different generic signature");
this->GenericSigOrEnv = genericEnv;
if (genericEnv)
genericEnv->setOwningDeclContext(this);
}
GenericEnvironment *
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");
}
const_cast<GenericContext *>(this)->setGenericEnvironment(genericEnv);
++NumLazyGenericEnvironmentsLoaded;
return genericEnv;
}
void GenericContext::setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData) {
assert(GenericSigOrEnv.isNull() && "already have a generic signature");
GenericSigOrEnv = genericSig;
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(this)) {
auto contextData =
getASTContext().getOrCreateLazyIterableContextData(
extensionDecl, 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;
}
ImportDecl *ImportDecl::create(ASTContext &Ctx, DeclContext *DC, ImportDecl *ImportDecl::create(ASTContext &Ctx, DeclContext *DC,
SourceLoc ImportLoc, ImportKind Kind, SourceLoc ImportLoc, ImportKind Kind,
SourceLoc KindLoc, SourceLoc KindLoc,
@@ -673,17 +773,17 @@ ExtensionDecl::ExtensionDecl(SourceLoc extensionLoc,
DeclContext *parent, DeclContext *parent,
TrailingWhereClause *trailingWhereClause) TrailingWhereClause *trailingWhereClause)
: Decl(DeclKind::Extension, parent), : Decl(DeclKind::Extension, parent),
DeclContext(DeclContextKind::ExtensionDecl, parent), GenericContext(DeclContextKind::ExtensionDecl, parent),
IterableDeclContext(IterableDeclContextKind::ExtensionDecl), IterableDeclContext(IterableDeclContextKind::ExtensionDecl),
ExtensionLoc(extensionLoc), ExtensionLoc(extensionLoc),
ExtendedType(extendedType), ExtendedType(extendedType),
Inherited(inherited), Inherited(inherited)
TrailingWhere(trailingWhereClause)
{ {
ExtensionDeclBits.Validated = false; ExtensionDeclBits.Validated = false;
ExtensionDeclBits.CheckedInheritanceClause = false; ExtensionDeclBits.CheckedInheritanceClause = false;
ExtensionDeclBits.DefaultAndMaxAccessLevel = 0; ExtensionDeclBits.DefaultAndMaxAccessLevel = 0;
ExtensionDeclBits.HasLazyConformances = false; ExtensionDeclBits.HasLazyConformances = false;
setTrailingWhereClause(trailingWhereClause);
} }
ExtensionDecl *ExtensionDecl::create(ASTContext &ctx, SourceLoc extensionLoc, ExtensionDecl *ExtensionDecl::create(ASTContext &ctx, SourceLoc extensionLoc,
@@ -707,72 +807,6 @@ ExtensionDecl *ExtensionDecl::create(ASTContext &ctx, SourceLoc extensionLoc,
return result; return result;
} }
void ExtensionDecl::setGenericParams(GenericParamList *params) {
GenericParams = params;
if (GenericParams) {
for (auto param : *GenericParams)
param->setDeclContext(this);
}
}
GenericSignature *ExtensionDecl::getGenericSignature() const {
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv->getGenericSignature();
if (auto genericSig = GenericSigOrEnv.dyn_cast<GenericSignature *>())
return genericSig;
return nullptr;
}
GenericEnvironment *ExtensionDecl::getGenericEnvironment() const {
// Fast case: we already have a generic environment.
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv;
// If we only have a generic signature, build the generic environment.
if (GenericSigOrEnv.dyn_cast<GenericSignature *>())
return getLazyGenericEnvironmentSlow();
return nullptr;
}
void ExtensionDecl::setGenericEnvironment(GenericEnvironment *genericEnv) {
assert((GenericSigOrEnv.isNull() ||
getGenericSignature()->getCanonicalSignature() ==
genericEnv->getGenericSignature()->getCanonicalSignature()) &&
"set a generic environment with a different generic signature");
this->GenericSigOrEnv = genericEnv;
if (genericEnv)
genericEnv->setOwningDeclContext(this);
}
GenericEnvironment *
ExtensionDecl::getLazyGenericEnvironmentSlow() const {
assert(GenericSigOrEnv.is<GenericSignature *>() &&
"not a lazily deserialized generic environment");
auto contextData = getASTContext().getOrCreateLazyIterableContextData(this,
nullptr);
auto genericEnv = contextData->loader->loadGenericEnvironment(
this, contextData->genericEnvData);
const_cast<ExtensionDecl *>(this)->setGenericEnvironment(genericEnv);
++NumLazyGenericEnvironmentsLoaded;
return genericEnv;
}
void ExtensionDecl::setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData) {
assert(GenericSigOrEnv.isNull() && "already have a generic signature");
GenericSigOrEnv = genericSig;
auto contextData =
getASTContext().getOrCreateLazyIterableContextData(this, lazyLoader);
contextData->genericEnvData = genericEnvData;
++NumLazyGenericEnvironments;
}
DeclRange ExtensionDecl::getMembers() const { DeclRange ExtensionDecl::getMembers() const {
loadAllMembers(); loadAllMembers();
return IterableDeclContext::getMembers(); return IterableDeclContext::getMembers();
@@ -2178,79 +2212,10 @@ GenericTypeDecl::GenericTypeDecl(DeclKind K, DeclContext *DC,
MutableArrayRef<TypeLoc> inherited, MutableArrayRef<TypeLoc> inherited,
GenericParamList *GenericParams) : GenericParamList *GenericParams) :
TypeDecl(K, DC, name, nameLoc, inherited), TypeDecl(K, DC, name, nameLoc, inherited),
DeclContext(DeclContextKind::GenericTypeDecl, DC) { GenericContext(DeclContextKind::GenericTypeDecl, DC) {
setGenericParams(GenericParams); setGenericParams(GenericParams);
} }
void GenericTypeDecl::setGenericParams(GenericParamList *params) {
// Set the specified generic parameters onto this type declaration, setting
// the parameters' context along the way.
GenericParams = params;
if (params)
for (auto Param : *params)
Param->setDeclContext(this);
}
GenericSignature *GenericTypeDecl::getGenericSignature() const {
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv->getGenericSignature();
if (auto genericSig = GenericSigOrEnv.dyn_cast<GenericSignature *>())
return genericSig;
return nullptr;
}
GenericEnvironment *GenericTypeDecl::getGenericEnvironment() const {
// Fast case: we already have a generic environment.
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv;
// If we only have a generic signature, build the generic environment.
if (GenericSigOrEnv.dyn_cast<GenericSignature *>())
return getLazyGenericEnvironmentSlow();
return nullptr;
}
/// Set the generic context of this function.
void GenericTypeDecl::setGenericEnvironment(GenericEnvironment *genericEnv) {
assert((GenericSigOrEnv.isNull() ||
getGenericSignature()->getCanonicalSignature() ==
genericEnv->getGenericSignature()->getCanonicalSignature()) &&
"set a generic environment with a different generic signature");
this->GenericSigOrEnv = genericEnv;
if (genericEnv)
genericEnv->setOwningDeclContext(this);
}
GenericEnvironment *
GenericTypeDecl::getLazyGenericEnvironmentSlow() const {
assert(GenericSigOrEnv.is<GenericSignature *>() &&
"not a lazily deserialized generic environment");
auto contextData = getASTContext().getOrCreateLazyGenericTypeData(this,
nullptr);
auto genericEnv = contextData->loader->loadGenericEnvironment(
this, contextData->genericEnvData);
const_cast<GenericTypeDecl *>(this)->setGenericEnvironment(genericEnv);
++NumLazyGenericEnvironmentsLoaded;
return genericEnv;
}
void GenericTypeDecl::setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData) {
assert(GenericSigOrEnv.isNull() && "already have a generic signature");
GenericSigOrEnv = genericSig;
auto contextData =
getASTContext().getOrCreateLazyGenericTypeData(this, lazyLoader);
contextData->genericEnvData = genericEnvData;
++NumLazyGenericEnvironments;
}
TypeAliasDecl::TypeAliasDecl(SourceLoc TypeAliasLoc, SourceLoc EqualLoc, TypeAliasDecl::TypeAliasDecl(SourceLoc TypeAliasLoc, SourceLoc EqualLoc,
Identifier Name, SourceLoc NameLoc, Identifier Name, SourceLoc NameLoc,
GenericParamList *GenericParams, DeclContext *DC) GenericParamList *GenericParams, DeclContext *DC)
@@ -4059,66 +4024,6 @@ SourceRange SubscriptDecl::getSourceRange() const {
return { getSubscriptLoc(), ElementTy.getSourceRange().End }; return { getSubscriptLoc(), ElementTy.getSourceRange().End };
} }
GenericSignature *AbstractFunctionDecl::getGenericSignature() const {
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv->getGenericSignature();
if (auto genericSig = GenericSigOrEnv.dyn_cast<GenericSignature *>())
return genericSig;
return nullptr;
}
GenericEnvironment *AbstractFunctionDecl::getGenericEnvironment() const {
// Fast case: we already have a generic environment.
if (auto genericEnv = GenericSigOrEnv.dyn_cast<GenericEnvironment *>())
return genericEnv;
// If we only have a generic signature, build the generic environment.
if (GenericSigOrEnv.dyn_cast<GenericSignature *>())
return getLazyGenericEnvironmentSlow();
return nullptr;
}
void
AbstractFunctionDecl::setGenericEnvironment(GenericEnvironment *genericEnv) {
assert((GenericSigOrEnv.isNull() ||
getGenericSignature()->getCanonicalSignature() ==
genericEnv->getGenericSignature()->getCanonicalSignature()) &&
"set a generic environment with a different generic signature");
this->GenericSigOrEnv = genericEnv;
if (genericEnv)
genericEnv->setOwningDeclContext(this);
}
GenericEnvironment *
AbstractFunctionDecl::getLazyGenericEnvironmentSlow() const {
assert(GenericSigOrEnv.is<GenericSignature *>() &&
"not a lazily deserialized generic environment");
auto contextData =
getASTContext().getOrCreateLazyFunctionContextData(this, nullptr);
auto genericEnv = contextData->loader->loadGenericEnvironment(
this, contextData->genericEnvData);
const_cast<AbstractFunctionDecl *>(this)->setGenericEnvironment(genericEnv);
++NumLazyGenericEnvironmentsLoaded;
return genericEnv;
}
void AbstractFunctionDecl::setLazyGenericEnvironment(
LazyMemberLoader *lazyLoader,
GenericSignature *genericSig,
uint64_t genericEnvData) {
assert(GenericSigOrEnv.isNull() && "already have a generic signature");
GenericSigOrEnv = genericSig;
auto contextData =
getASTContext().getOrCreateLazyFunctionContextData(this, lazyLoader);
contextData->genericEnvData = genericEnvData;
++NumLazyGenericEnvironments;
}
Type AbstractFunctionDecl::computeInterfaceSelfType(bool isInitializingCtor, Type AbstractFunctionDecl::computeInterfaceSelfType(bool isInitializingCtor,
bool wantDynamicSelf) { bool wantDynamicSelf) {
auto *dc = getDeclContext(); auto *dc = getDeclContext();
@@ -4218,16 +4123,6 @@ DeclName AbstractFunctionDecl::getEffectiveFullName() const {
return DeclName(); return DeclName();
} }
void AbstractFunctionDecl::setGenericParams(GenericParamList *GP) {
// Set the specified generic parameters onto this abstract function, setting
// the parameters' context to the function along the way.
GenericParams = GP;
if (GP)
for (auto Param : *GP)
Param->setDeclContext(this);
}
/// \brief This method returns the implicit 'self' decl. /// \brief This method returns the implicit 'self' decl.
/// ///
/// Note that some functions don't have an implicit 'self' decl, for example, /// Note that some functions don't have an implicit 'self' decl, for example,