Skip to content

AST: Introduce new GenericContext base class #7597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 81 additions & 147 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,82 @@ class alignas(RequirementRepr) TrailingWhereClause final :
}
};

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.
///
/// If the enumerators here are changed, make sure to update all diagnostics
Expand Down Expand Up @@ -1483,32 +1559,16 @@ class ImportDecl final : public Decl,
/// ExtensionDecl - This represents a type extension containing methods
/// associated with the type. This is not a ValueDecl and has no Type because
/// 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 {
SourceLoc ExtensionLoc; // Location of 'extension' keyword.
SourceRange Braces;

/// The type being extended.
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;

/// 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.
///
/// The bit indicates whether this extension has been resolved to refer to
Expand Down Expand Up @@ -1543,9 +1603,6 @@ class ExtensionDecl final : public Decl, public DeclContext,
/// Slow path for \c takeConformanceLoader().
std::pair<LazyMemberLoader *, uint64_t> takeConformanceLoaderSlow();

/// Lazily populate the generic environment.
GenericEnvironment *getLazyGenericEnvironmentSlow() const;

public:
using Decl::getASTContext;

Expand All @@ -1566,45 +1623,6 @@ class ExtensionDecl final : public Decl, public DeclContext,
SourceRange getBraces() const { return 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.
Type getExtendedType() const { return ExtendedType.getType(); }

Expand Down Expand Up @@ -2351,61 +2369,13 @@ class TypeDecl : public ValueDecl {

/// A type declaration that can have generic parameters attached to it. Because
/// it has these generic parameters, it is always a DeclContext.
class GenericTypeDecl : public TypeDecl, public DeclContext {
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;

class GenericTypeDecl : public TypeDecl, public GenericContext {
public:
GenericTypeDecl(DeclKind K, DeclContext *DC,
Identifier name, SourceLoc nameLoc,
MutableArrayRef<TypeLoc> inherited,
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.
using TypeDecl::getASTContext;
using DeclContext::operator new;
Expand Down Expand Up @@ -4639,7 +4609,7 @@ struct ImportAsMemberStatus {
};

/// \brief Base class for function-like declarations.
class AbstractFunctionDecl : public ValueDecl, public DeclContext {
class AbstractFunctionDecl : public ValueDecl, public GenericContext {
public:
enum class BodyKind {
/// The function did not have a body in the source code file.
Expand Down Expand Up @@ -4690,15 +4660,6 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
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;

/// Location of the 'throws' token.
Expand All @@ -4711,8 +4672,8 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
unsigned NumParameterLists,
GenericParamList *GenericParams)
: ValueDecl(Kind, Parent, Name, NameLoc),
DeclContext(DeclContextKind::AbstractFunctionDecl, Parent),
Body(nullptr), GenericParams(nullptr), ThrowsLoc(ThrowsLoc) {
GenericContext(DeclContextKind::AbstractFunctionDecl, Parent),
Body(nullptr), ThrowsLoc(ThrowsLoc) {
setBodyKind(BodyKind::None);
setGenericParams(GenericParams);
AbstractFunctionDeclBits.NumParameterLists = NumParameterLists;
Expand All @@ -4727,30 +4688,11 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
AbstractFunctionDeclBits.BodyKind = unsigned(K);
}

void setGenericParams(GenericParamList *GenericParams);

/// Lazily populate the generic environment.
GenericEnvironment *getLazyGenericEnvironmentSlow() const;

public:
/// \brief Should this declaration be treated as if annotated with transparent
/// attribute.
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
bool isImportAsMember() const { return IAMStatus.isImportAsMember(); }
bool isImportAsInstanceMember() const { return IAMStatus.isInstance(); }
Expand Down Expand Up @@ -4930,14 +4872,6 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
}
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.
AbstractFunctionDecl *getOverriddenDecl() const;

Expand Down
Loading