blob: 9dfc7d39a7cd59dc7324e07350dddc47de549b91 [file] [log] [blame]
//===--- TypeCheckRequests.h - Type Checking Requests -----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines type checking requests.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_TYPE_CHECK_REQUESTS_H
#define SWIFT_TYPE_CHECK_REQUESTS_H
#include "swift/AST/ASTTypeIDs.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/Type.h"
#include "swift/AST/Evaluator.h"
#include "swift/AST/SimpleRequest.h"
#include "swift/AST/TypeResolutionStage.h"
#include "swift/Basic/AnyValue.h"
#include "swift/Basic/Statistic.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/TinyPtrVector.h"
namespace swift {
class AbstractStorageDecl;
class AccessorDecl;
enum class AccessorKind;
class GenericParamList;
class PrecedenceGroupDecl;
struct PropertyWrapperBackingPropertyInfo;
struct PropertyWrapperMutability;
class RequirementRepr;
class SpecializeAttr;
class TypeAliasDecl;
struct TypeLoc;
class ValueDecl;
enum class OpaqueReadOwnership: uint8_t;
class StorageImplInfo;
/// Display a nominal type or extension thereof.
void simple_display(
llvm::raw_ostream &out,
const llvm::PointerUnion<TypeDecl *, ExtensionDecl *> &value);
/// Request the type from the ith entry in the inheritance clause for the
/// given declaration.
class InheritedTypeRequest :
public SimpleRequest<InheritedTypeRequest,
Type(llvm::PointerUnion<TypeDecl *, ExtensionDecl *>,
unsigned,
TypeResolutionStage),
CacheKind::SeparatelyCached>
{
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type>
evaluate(Evaluator &evaluator,
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
unsigned index,
TypeResolutionStage stage) const;
public:
// Source location
SourceLoc getNearestLoc() const;
// Caching
bool isCached() const;
Optional<Type> getCachedResult() const;
void cacheResult(Type value) const;
};
/// Request the superclass type for the given class.
class SuperclassTypeRequest :
public SimpleRequest<SuperclassTypeRequest,
Type(NominalTypeDecl *, TypeResolutionStage),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type>
evaluate(Evaluator &evaluator, NominalTypeDecl *classDecl,
TypeResolutionStage stage) const;
public:
// Cycle handling
void diagnoseCycle(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const;
Optional<Type> getCachedResult() const;
void cacheResult(Type value) const;
};
/// Request the raw type of the given enum.
class EnumRawTypeRequest :
public SimpleRequest<EnumRawTypeRequest,
Type(EnumDecl *, TypeResolutionStage),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type>
evaluate(Evaluator &evaluator, EnumDecl *enumDecl,
TypeResolutionStage stage) const;
public:
// Cycle handling
void diagnoseCycle(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const;
Optional<Type> getCachedResult() const;
void cacheResult(Type value) const;
};
/// Request to determine the set of declarations that were are overridden
/// by the given declaration.
class OverriddenDeclsRequest :
public SimpleRequest<OverriddenDeclsRequest,
llvm::TinyPtrVector<ValueDecl *>(ValueDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<llvm::TinyPtrVector<ValueDecl *>>
evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<llvm::TinyPtrVector<ValueDecl *>> getCachedResult() const;
void cacheResult(llvm::TinyPtrVector<ValueDecl *> value) const;
};
/// Determine whether the given declaration is exposed to Objective-C.
class IsObjCRequest :
public SimpleRequest<IsObjCRequest,
bool(ValueDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
void simple_display(llvm::raw_ostream &out, CtorInitializerKind initKind);
/// Computes the kind of initializer for a given \c ConstructorDecl
class InitKindRequest :
public SimpleRequest<InitKindRequest,
CtorInitializerKind(ConstructorDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<CtorInitializerKind>
evaluate(Evaluator &evaluator, ConstructorDecl *decl) const;
public:
// Caching.
bool isCached() const { return true; }
};
/// Determine whether the given protocol declaration is class-bounded.
class ProtocolRequiresClassRequest :
public SimpleRequest<ProtocolRequiresClassRequest,
bool(ProtocolDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
public:
// Cycle handling.
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Determine whether an existential conforming to a protocol can be matched
/// with a generic type parameter constrained to that protocol.
class ExistentialConformsToSelfRequest :
public SimpleRequest<ExistentialConformsToSelfRequest,
bool(ProtocolDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
public:
// Cycle handling.
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Determine whether we are allowed to refer to an existential type conforming
/// to this protocol.
class ExistentialTypeSupportedRequest :
public SimpleRequest<ExistentialTypeSupportedRequest,
bool(ProtocolDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
public:
// Cycle handling.
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Determine whether the given declaration is 'final'.
class IsFinalRequest :
public SimpleRequest<IsFinalRequest,
bool(ValueDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Determine whether the given declaration is 'dynamic''.
class IsDynamicRequest :
public SimpleRequest<IsDynamicRequest,
bool(ValueDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Compute the requirements that describe a protocol.
class RequirementSignatureRequest :
public SimpleRequest<RequirementSignatureRequest,
ArrayRef<Requirement>(ProtocolDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<ArrayRef<Requirement>> evaluate(Evaluator &evaluator, ProtocolDecl *proto) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<ArrayRef<Requirement>> getCachedResult() const;
void cacheResult(ArrayRef<Requirement> value) const;
};
/// Compute the default definition type of an associated type.
class DefaultDefinitionTypeRequest :
public SimpleRequest<DefaultDefinitionTypeRequest,
Type(AssociatedTypeDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type> evaluate(Evaluator &evaluator, AssociatedTypeDecl *decl) const;
public:
// Caching.
bool isCached() const { return true; }
};
/// Describes the owner of a where clause, from which we can extract
/// requirements.
struct WhereClauseOwner {
/// The declaration context in which the where clause will be evaluated.
DeclContext *dc;
/// The source of the where clause, which can be a generic parameter list
/// or a declaration that can have a where clause.
llvm::PointerUnion<GenericParamList *, Decl *, SpecializeAttr *,
// SWIFT_ENABLE_TENSORFLOW
DifferentiableAttr *>
source;
WhereClauseOwner(Decl *decl);
WhereClauseOwner(DeclContext *dc, GenericParamList *genericParams)
: dc(dc), source(genericParams) {}
WhereClauseOwner(DeclContext *dc, SpecializeAttr *attr)
: dc(dc), source(attr) {}
// SWIFT_ENABLE_TENSORFLOW
WhereClauseOwner(DeclContext *dc, DifferentiableAttr *attr)
: dc(dc), source(attr) {}
SourceLoc getLoc() const;
friend hash_code hash_value(const WhereClauseOwner &owner) {
return llvm::hash_combine(owner.dc, owner.source.getOpaqueValue());
}
friend bool operator==(const WhereClauseOwner &lhs,
const WhereClauseOwner &rhs) {
return lhs.dc == rhs.dc &&
lhs.source.getOpaqueValue() == rhs.source.getOpaqueValue();
}
friend bool operator!=(const WhereClauseOwner &lhs,
const WhereClauseOwner &rhs) {
return !(lhs == rhs);
}
public:
/// Retrieve the array of requirements.
MutableArrayRef<RequirementRepr> getRequirements() const;
/// Visit each of the requirements,
///
/// \returns true after short-circuiting if the callback returned \c true
/// for any of the requirements.
bool
visitRequirements(TypeResolutionStage stage,
llvm::function_ref<bool(Requirement, RequirementRepr *)>
callback) const &&;
};
void simple_display(llvm::raw_ostream &out, const WhereClauseOwner &owner);
/// Retrieve a requirement from the where clause of the given declaration.
class RequirementRequest :
public SimpleRequest<RequirementRequest,
Requirement(WhereClauseOwner, unsigned,
TypeResolutionStage),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
/// Retrieve the requirement this request operates on.
RequirementRepr &getRequirement() const;
// Evaluation.
llvm::Expected<Requirement> evaluate(Evaluator &evaluator,
WhereClauseOwner,
unsigned index,
TypeResolutionStage stage) const;
public:
// Source location
SourceLoc getNearestLoc() const;
// Cycle handling.
void noteCycleStep(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const;
Optional<Requirement> getCachedResult() const;
void cacheResult(Requirement value) const;
};
/// Generate the USR for the given declaration.
class USRGenerationRequest :
public SimpleRequest<USRGenerationRequest,
std::string(const ValueDecl*),
CacheKind::Cached>
{
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<std::string> evaluate(Evaluator &eval, const ValueDecl *d) const;
public:
// Caching
bool isCached() const { return true; }
};
/// Generate the mangling for the given local type declaration.
class MangleLocalTypeDeclRequest :
public SimpleRequest<MangleLocalTypeDeclRequest,
std::string(const TypeDecl*),
CacheKind::Cached>
{
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<std::string> evaluate(Evaluator &eval, const TypeDecl *d) const;
public:
// Caching
bool isCached() const { return true; }
};
void simple_display(llvm::raw_ostream &out, const KnownProtocolKind);
class TypeChecker;
// Find the type in the cache or look it up
class DefaultTypeRequest
: public SimpleRequest<DefaultTypeRequest,
Type(KnownProtocolKind, const DeclContext *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type> evaluate(Evaluator &eval, KnownProtocolKind,
const DeclContext *) const;
public:
// Caching
bool isCached() const { return true; }
Optional<Type> getCachedResult() const;
void cacheResult(Type value) const;
};
/// Retrieve information about a property wrapper type.
class PropertyWrapperTypeInfoRequest
: public SimpleRequest<PropertyWrapperTypeInfoRequest,
PropertyWrapperTypeInfo(NominalTypeDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<PropertyWrapperTypeInfo>
evaluate(Evaluator &eval, NominalTypeDecl *nominal) const;
public:
// Caching
bool isCached() const;
};
/// Request the nominal type declaration to which the given custom attribute
/// refers.
class AttachedPropertyWrappersRequest :
public SimpleRequest<AttachedPropertyWrappersRequest,
llvm::TinyPtrVector<CustomAttr *>(VarDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<llvm::TinyPtrVector<CustomAttr *>>
evaluate(Evaluator &evaluator, VarDecl *) const;
public:
// Caching
bool isCached() const;
};
/// Request the raw (possibly unbound generic) type of the property wrapper
/// that is attached to the given variable.
class AttachedPropertyWrapperTypeRequest :
public SimpleRequest<AttachedPropertyWrapperTypeRequest,
Type(VarDecl *, unsigned),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type>
evaluate(Evaluator &evaluator, VarDecl *var, unsigned i) const;
public:
// Caching
bool isCached() const;
};
/// Request the nominal type declaration to which the given custom attribute
/// refers.
class PropertyWrapperBackingPropertyTypeRequest :
public SimpleRequest<PropertyWrapperBackingPropertyTypeRequest,
Type(VarDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type>
evaluate(Evaluator &evaluator, VarDecl *var) const;
public:
// Caching
bool isCached() const;
};
/// Request information about the mutability of composed property wrappers.
class PropertyWrapperMutabilityRequest :
public SimpleRequest<PropertyWrapperMutabilityRequest,
Optional<PropertyWrapperMutability> (VarDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Optional<PropertyWrapperMutability>>
evaluate(Evaluator &evaluator, VarDecl *var) const;
public:
// Caching
bool isCached() const;
};
/// Request information about the backing property for properties that have
/// attached property wrappers.
class PropertyWrapperBackingPropertyInfoRequest :
public SimpleRequest<PropertyWrapperBackingPropertyInfoRequest,
PropertyWrapperBackingPropertyInfo(VarDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<PropertyWrapperBackingPropertyInfo>
evaluate(Evaluator &evaluator, VarDecl *var) const;
public:
// Caching
bool isCached() const;
};
/// Retrieve the structural type of an alias type.
class StructuralTypeRequest :
public SimpleRequest<StructuralTypeRequest,
Type(TypeAliasDecl*),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type> evaluate(Evaluator &eval, TypeAliasDecl *d) const;
public:
// Caching.
bool isCached() const { return true; }
};
/// Request the most optimal resilience expansion for the code in the context.
class ResilienceExpansionRequest :
public SimpleRequest<ResilienceExpansionRequest,
ResilienceExpansion(DeclContext*),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<ResilienceExpansion> evaluate(Evaluator &eval,
DeclContext *context) const;
public:
// Caching.
bool isCached() const { return true; }
};
void simple_display(llvm::raw_ostream &out,
const ResilienceExpansion &value);
/// Request the custom attribute which attaches a function builder to the
/// given declaration.
class AttachedFunctionBuilderRequest :
public SimpleRequest<AttachedFunctionBuilderRequest,
CustomAttr *(ValueDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<CustomAttr *>
evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Caching
bool isCached() const;
};
/// Request the function builder type attached to the given declaration,
/// if any.
class FunctionBuilderTypeRequest :
public SimpleRequest<FunctionBuilderTypeRequest,
Type(ValueDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
llvm::Expected<Type>
evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Caching
bool isCached() const { return true; }
};
/// Request a function's self access kind.
class SelfAccessKindRequest :
public SimpleRequest<SelfAccessKindRequest,
SelfAccessKind(FuncDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<SelfAccessKind>
evaluate(Evaluator &evaluator, FuncDecl *func) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<SelfAccessKind> getCachedResult() const;
void cacheResult(SelfAccessKind value) const;
};
/// Request whether the storage has a mutating getter.
class IsGetterMutatingRequest :
public SimpleRequest<IsGetterMutatingRequest,
bool(AbstractStorageDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, AbstractStorageDecl *func) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Request whether the storage has a mutating getter.
class IsSetterMutatingRequest :
public SimpleRequest<IsSetterMutatingRequest,
bool(AbstractStorageDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, AbstractStorageDecl *func) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
/// Request whether reading the storage yields a borrowed value.
class OpaqueReadOwnershipRequest :
public SimpleRequest<OpaqueReadOwnershipRequest,
OpaqueReadOwnership(AbstractStorageDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<OpaqueReadOwnership>
evaluate(Evaluator &evaluator, AbstractStorageDecl *storage) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<OpaqueReadOwnership> getCachedResult() const;
void cacheResult(OpaqueReadOwnership value) const;
};
/// Request to build the underlying storage for a lazy property.
class LazyStoragePropertyRequest :
public SimpleRequest<LazyStoragePropertyRequest,
VarDecl *(VarDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<VarDecl *>
evaluate(Evaluator &evaluator, VarDecl *lazyVar) const;
public:
bool isCached() const { return true; }
};
/// Request to type check the body of the given function up to the given
/// source location.
///
/// Produces true if an error occurred, false otherwise.
/// FIXME: it would be far better to return the type-checked body.
class TypeCheckFunctionBodyUntilRequest :
public SimpleRequest<TypeCheckFunctionBodyUntilRequest,
bool(AbstractFunctionDecl *, SourceLoc),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, AbstractFunctionDecl *func,
SourceLoc endTypeCheckLoc) const;
public:
bool isCached() const { return true; }
};
/// Request to obtain a list of stored properties in a nominal type.
///
/// This will include backing storage for lazy properties and
/// property wrappers, synthesizing them if necessary.
class StoredPropertiesRequest :
public SimpleRequest<StoredPropertiesRequest,
ArrayRef<VarDecl *>(NominalTypeDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<ArrayRef<VarDecl *>>
evaluate(Evaluator &evaluator, NominalTypeDecl *decl) const;
public:
bool isCached() const { return true; }
};
/// Request to obtain a list of stored properties in a nominal type,
/// together with any missing members corresponding to stored
/// properties that could not be deserialized.
///
/// This will include backing storage for lazy properties and
/// property wrappers, synthesizing them if necessary.
class StoredPropertiesAndMissingMembersRequest :
public SimpleRequest<StoredPropertiesAndMissingMembersRequest,
ArrayRef<Decl *>(NominalTypeDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<ArrayRef<Decl *>>
evaluate(Evaluator &evaluator, NominalTypeDecl *decl) const;
public:
bool isCached() const { return true; }
};
class StorageImplInfoRequest :
public SimpleRequest<StorageImplInfoRequest,
StorageImplInfo(AbstractStorageDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<StorageImplInfo>
evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<StorageImplInfo> getCachedResult() const;
void cacheResult(StorageImplInfo value) const;
};
class RequiresOpaqueAccessorsRequest :
public SimpleRequest<RequiresOpaqueAccessorsRequest,
bool(VarDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, VarDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
class RequiresOpaqueModifyCoroutineRequest :
public SimpleRequest<RequiresOpaqueModifyCoroutineRequest,
bool(AbstractStorageDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
class IsAccessorTransparentRequest :
public SimpleRequest<IsAccessorTransparentRequest,
bool(AccessorDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, AccessorDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
class SynthesizeAccessorRequest :
public SimpleRequest<SynthesizeAccessorRequest,
AccessorDecl *(AbstractStorageDecl *,
AccessorKind),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<AccessorDecl *>
evaluate(Evaluator &evaluator, AbstractStorageDecl *decl,
AccessorKind kind) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<AccessorDecl *> getCachedResult() const;
void cacheResult(AccessorDecl *value) const;
};
class EmittedMembersRequest :
public SimpleRequest<EmittedMembersRequest,
DeclRange(ClassDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<DeclRange>
evaluate(Evaluator &evaluator, ClassDecl *classDecl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<DeclRange> getCachedResult() const;
void cacheResult(DeclRange value) const;
};
class IsImplicitlyUnwrappedOptionalRequest :
public SimpleRequest<IsImplicitlyUnwrappedOptionalRequest,
bool(ValueDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, ValueDecl *value) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
class ClassAncestryFlagsRequest :
public SimpleRequest<ClassAncestryFlagsRequest,
AncestryFlags (ClassDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<AncestryFlags>
evaluate(Evaluator &evaluator, ClassDecl *value) const;
public:
// Caching.
bool isCached() const { return true; }
};
void simple_display(llvm::raw_ostream &out, AncestryFlags value);
class AbstractGenericSignatureRequest :
public SimpleRequest<AbstractGenericSignatureRequest,
GenericSignature (GenericSignatureImpl *,
SmallVector<GenericTypeParamType *, 2>,
SmallVector<Requirement, 2>),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<GenericSignature>
evaluate(Evaluator &evaluator,
GenericSignatureImpl *baseSignature,
SmallVector<GenericTypeParamType *, 2> addedParameters,
SmallVector<Requirement, 2> addedRequirements) const;
public:
// Separate caching.
bool isCached() const;
/// Abstract generic signature requests never have source-location info.
SourceLoc getNearestLoc() const {
return SourceLoc();
}
};
class InferredGenericSignatureRequest :
public SimpleRequest<InferredGenericSignatureRequest,
GenericSignature (ModuleDecl *,
GenericSignatureImpl *,
GenericParamList *,
SmallVector<Requirement, 2>,
SmallVector<TypeLoc, 2>,
bool),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<GenericSignature>
evaluate(Evaluator &evaluator,
ModuleDecl *module,
GenericSignatureImpl *baseSignature,
GenericParamList *gpl,
SmallVector<Requirement, 2> addedRequirements,
SmallVector<TypeLoc, 2> inferenceSources,
bool allowConcreteGenericParams) const;
public:
// Separate caching.
bool isCached() const;
/// Inferred generic signature requests don't have source-location info.
SourceLoc getNearestLoc() const {
return SourceLoc();
}
// Cycle handling.
void noteCycleStep(DiagnosticEngine &diags) const;
};
void simple_display(llvm::raw_ostream &out, const TypeLoc source);
class ExtendedTypeRequest
: public SimpleRequest<ExtendedTypeRequest,
Type(ExtensionDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type> evaluate(Evaluator &eval, ExtensionDecl *) const;
public:
// Caching.
bool isCached() const { return true; }
};
class FunctionOperatorRequest :
public SimpleRequest<FunctionOperatorRequest,
OperatorDecl *(FuncDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<OperatorDecl *>
evaluate(Evaluator &evaluator, FuncDecl *value) const;
public:
// Caching.
bool isCached() const { return true; }
};
class GenericSignatureRequest :
public SimpleRequest<GenericSignatureRequest,
GenericSignature (GenericContext *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<GenericSignature>
evaluate(Evaluator &evaluator, GenericContext *value) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<GenericSignature> getCachedResult() const;
void cacheResult(GenericSignature value) const;
};
/// Compute the underlying interface type of a typealias.
class UnderlyingTypeRequest :
public SimpleRequest<UnderlyingTypeRequest,
Type(TypeAliasDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<Type> evaluate(Evaluator &evaluator,
TypeAliasDecl *decl) const;
public:
// Caching.
bool isCached() const { return true; }
Optional<Type> getCachedResult() const;
void cacheResult(Type value) const;
void diagnoseCycle(DiagnosticEngine &diags) const;
};
/// Looks up the precedence group of an operator declaration.
class OperatorPrecedenceGroupRequest
: public SimpleRequest<OperatorPrecedenceGroupRequest,
PrecedenceGroupDecl *(InfixOperatorDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<PrecedenceGroupDecl *>
evaluate(Evaluator &evaluator, InfixOperatorDecl *PGD) const;
public:
// Separate caching.
bool isCached() const { return true; }
};
class EnumRawValuesRequest :
public SimpleRequest<EnumRawValuesRequest,
bool (EnumDecl *, TypeResolutionStage),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, EnumDecl *ED, TypeResolutionStage stage) const;
public:
// Cycle handling.
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;
// Separate caching.
bool isCached() const;
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
class IsABICompatibleOverrideRequest
: public SimpleRequest<IsABICompatibleOverrideRequest, bool(ValueDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
public:
// Caching.
bool isCached() const { return true; }
};
/// Builds an opaque result type for a declaration.
class OpaqueResultTypeRequest
: public SimpleRequest<OpaqueResultTypeRequest,
OpaqueTypeDecl *(ValueDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
llvm::Expected<OpaqueTypeDecl *>
evaluate(Evaluator &evaluator, ValueDecl *VD) const;
public:
// Caching.
bool isCached() const { return true; }
};
/// Determines if a function declaration is 'static'.
class IsStaticRequest :
public SimpleRequest<IsStaticRequest,
bool(FuncDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, FuncDecl *value) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
class NeedsNewVTableEntryRequest
: public SimpleRequest<NeedsNewVTableEntryRequest,
bool(AbstractFunctionDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<bool> evaluate(Evaluator &evaluator,
AbstractFunctionDecl *decl) const;
public:
// Separate caching.
bool isCached() const { return true; }
Optional<bool> getCachedResult() const;
void cacheResult(bool value) const;
};
// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
inline bool AnyValue::Holder<Type>::equals(const HolderBase &other) const {
assert(typeID == other.typeID && "Caller should match type IDs");
return value.getPointer() ==
static_cast<const Holder<Type> &>(other).value.getPointer();
}
// Allow AnyValue to compare two GenericSignature values.
template <>
inline bool
AnyValue::Holder<GenericSignature>::equals(const HolderBase &other) const {
assert(typeID == other.typeID && "Caller should match type IDs");
return value.getPointer() ==
static_cast<const Holder<GenericSignature> &>(other)
.value.getPointer();
}
void simple_display(llvm::raw_ostream &out, Type value);
void simple_display(llvm::raw_ostream &out, const TypeRepr *TyR);
#define SWIFT_TYPEID_ZONE TypeChecker
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
#undef SWIFT_TYPEID_ZONE
#undef SWIFT_TYPEID_HEADER
// Set up reporting of evaluated requests.
#define SWIFT_REQUEST(Zone, RequestType, Sig, Caching, LocOptions) \
template<> \
inline void reportEvaluatedRequest(UnifiedStatsReporter &stats, \
const RequestType &request) { \
++stats.getFrontendCounters().RequestType; \
}
#include "swift/AST/TypeCheckerTypeIDZone.def"
#undef SWIFT_REQUEST
} // end namespace swift
#endif // SWIFT_TYPE_CHECK_REQUESTS_H