Skip to content
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
64 changes: 64 additions & 0 deletions include/swift/AST/CanTypeVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,70 @@ class CanTypeVisitor {
#include "swift/AST/TypeNodes.def"
};

/// This is a convenience refinement of CanTypeVisitor which forwards the
/// paired nominal type methods to a common implementation.
///
/// The delegation flow is:
/// {ClassType, BoundGenericClassType} -> AnyClassType -> AnyNominalType -> Type
/// {EnumType, BoundGenericEnumType} -> AnyEnumType -> AnyNominalType -> Type
/// {StructType, BoundGenericStructType} -> AnyStructType -> AnyNominalType -> Type
/// ProtocolType -> AnyNominalType -> Type
///
/// The new visitAny*Type methods take the appropriate Decl* as their second
/// argument.
template<typename ImplClass, typename RetTy = void, typename... Args>
class CanTypeVisitor_AnyNominal : public CanTypeVisitor<ImplClass, RetTy, Args...> {
public:
RetTy visitClassType(CanClassType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyClassType(T, T->getDecl(), ::std::forward<Args>(args)...);
}
RetTy visitBoundGenericClassType(CanBoundGenericClassType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyClassType(T, T->getDecl(), ::std::forward<Args>(args)...);
}
RetTy visitAnyClassType(CanType T, ClassDecl *D, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyNominalType(T, D, ::std::forward<Args>(args)...);
}

RetTy visitStructType(CanStructType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyStructType(T, T->getDecl(), ::std::forward<Args>(args)...);
}
RetTy visitBoundGenericStructType(CanBoundGenericStructType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyStructType(T, T->getDecl(), ::std::forward<Args>(args)...);
}
RetTy visitAnyStructType(CanType T, StructDecl *D, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyNominalType(T, D, ::std::forward<Args>(args)...);
}

RetTy visitEnumType(CanEnumType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyEnumType(T, T->getDecl(), ::std::forward<Args>(args)...);
}
RetTy visitBoundGenericEnumType(CanBoundGenericEnumType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyEnumType(T, T->getDecl(), ::std::forward<Args>(args)...);
}
RetTy visitAnyEnumType(CanType T, EnumDecl *D, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyNominalType(T, D, ::std::forward<Args>(args)...);
}

RetTy visitProtocolType(CanProtocolType T, Args... args) {
return static_cast<ImplClass*>(this)
->visitAnyNominalType(T, T->getDecl(), ::std::forward<Args>(args)...);
}

RetTy visitAnyNominalType(CanType T, NominalTypeDecl *D, Args... args) {
return static_cast<ImplClass*>(this)
->visitType(T, ::std::forward<Args>(args)...);
}
};

} // end namespace swift

#endif
1 change: 0 additions & 1 deletion lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTMangler.h"
#include "swift/AST/Attr.h"
#include "swift/AST/CanTypeVisitor.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsIRGen.h"
#include "swift/AST/GenericEnvironment.h"
Expand Down
1 change: 0 additions & 1 deletion lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
//===----------------------------------------------------------------------===//

#include "swift/AST/ASTContext.h"
#include "swift/AST/CanTypeVisitor.h"
#include "swift/AST/Types.h"
#include "swift/AST/ConformanceLookup.h"
#include "swift/AST/Decl.h"
Expand Down
24 changes: 8 additions & 16 deletions lib/IRGen/GenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2425,7 +2425,8 @@ namespace {
/// type mismatch) if an aggregate type containing a value of this
/// type is generated generically rather than independently for
/// different specializations?
class IsIRTypeDependent : public CanTypeVisitor<IsIRTypeDependent, bool> {
class IsIRTypeDependent :
public CanTypeVisitor_AnyNominal<IsIRTypeDependent, bool> {
IRGenModule &IGM;
public:
IsIRTypeDependent(IRGenModule &IGM) : IGM(IGM) {}
Expand All @@ -2439,11 +2440,8 @@ namespace {

// Dependent struct types need their own implementation if any
// field type might need its own implementation.
bool visitStructType(CanStructType type) {
return visitStructDecl(type->getDecl());
}
bool visitBoundGenericStructType(CanBoundGenericStructType type) {
return visitStructDecl(type->getDecl());
bool visitAnyStructType(CanType type, StructDecl *decl) {
return visitStructDecl(decl);
}
bool visitStructDecl(StructDecl *decl) {
if (IGM.isResilient(decl, ResilienceExpansion::Maximal))
Expand Down Expand Up @@ -2472,11 +2470,8 @@ namespace {

// Dependent enum types need their own implementation if any
// element payload type might need its own implementation.
bool visitEnumType(CanEnumType type) {
return visitEnumDecl(type->getDecl());
}
bool visitBoundGenericEnumType(CanBoundGenericEnumType type) {
return visitEnumDecl(type->getDecl());
bool visitAnyEnumType(CanType type, EnumDecl *decl) {
return visitEnumDecl(decl);
}
bool visitEnumDecl(EnumDecl *decl) {
if (IGM.isResilient(decl, ResilienceExpansion::Maximal))
Expand All @@ -2495,11 +2490,8 @@ namespace {
}

// Conservatively assume classes need unique implementations.
bool visitClassType(CanClassType type) {
return visitClassDecl(type->getDecl());
}
bool visitBoundGenericClassType(CanBoundGenericClassType type) {
return visitClassDecl(type->getDecl());
bool visitAnyClassType(CanType type, ClassDecl *theClass) {
return visitClassDecl(theClass);
}
bool visitClassDecl(ClassDecl *theClass) {
return true;
Expand Down
17 changes: 3 additions & 14 deletions lib/IRGen/MetadataRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3615,8 +3615,8 @@ namespace {
/// valid recursive types bottom out in fixed-sized types like classes
/// or pointers.)
class EmitTypeLayoutRef
: public CanTypeVisitor<EmitTypeLayoutRef, llvm::Value *,
DynamicMetadataRequest> {
: public CanTypeVisitor_AnyNominal<EmitTypeLayoutRef, llvm::Value *,
DynamicMetadataRequest> {
private:
IRGenFunction &IGF;
public:
Expand Down Expand Up @@ -3755,10 +3755,9 @@ namespace {
llvm_unreachable("Not a valid MetatypeRepresentation.");
}

llvm::Value *visitAnyClassType(ClassDecl *classDecl,
llvm::Value *visitAnyClassType(CanType type, ClassDecl *classDecl,
DynamicMetadataRequest request) {
// All class types have the same layout.
auto type = classDecl->getDeclaredType()->getCanonicalType();
switch (type->getReferenceCounting()) {
case ReferenceCounting::Native:
return emitFromValueWitnessTable(IGF.IGM.Context.TheNativeObjectType);
Expand All @@ -3779,16 +3778,6 @@ namespace {
llvm_unreachable("Not a valid ReferenceCounting.");
}

llvm::Value *visitClassType(CanClassType type,
DynamicMetadataRequest request) {
return visitAnyClassType(type->getClassOrBoundGenericClass(), request);
}

llvm::Value *visitBoundGenericClassType(CanBoundGenericClassType type,
DynamicMetadataRequest request) {
return visitAnyClassType(type->getClassOrBoundGenericClass(), request);
}

llvm::Value *visitPackType(CanPackType type,
DynamicMetadataRequest request) {
llvm_unreachable("");
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/IR/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#define DEBUG_TYPE "libsil"

#include "swift/AST/AnyFunctionRef.h"
#include "swift/AST/CanTypeVisitor.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/ForeignInfo.h"
Expand Down
22 changes: 7 additions & 15 deletions lib/SILOptimizer/Utils/InstOptUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,8 @@ swift::castValueToABICompatibleType(SILBuilder *builder, SILPassManager *pm,
}

namespace {
class TypeDependentVisitor : public CanTypeVisitor<TypeDependentVisitor, bool> {
class TypeDependentVisitor :
public CanTypeVisitor_AnyNominal<TypeDependentVisitor, bool> {
public:
// If the type isn't actually dependent, we're okay.
bool visit(CanType type) {
Expand All @@ -783,11 +784,8 @@ namespace {
return CanTypeVisitor::visit(type);
}

bool visitStructType(CanStructType type) {
return visitStructDecl(type->getDecl());
}
bool visitBoundGenericStructType(CanBoundGenericStructType type) {
return visitStructDecl(type->getDecl());
bool visitAnyStructType(CanType type, StructDecl *decl) {
return visitStructDecl(decl);
}
bool visitStructDecl(StructDecl *decl) {
auto rawLayout = decl->getAttrs().getAttribute<RawLayoutAttr>();
Expand All @@ -806,11 +804,8 @@ namespace {
return false;
}

bool visitEnumType(CanEnumType type) {
return visitEnumDecl(type->getDecl());
}
bool visitBoundGenericEnumType(CanBoundGenericEnumType type) {
return visitEnumDecl(type->getDecl());
bool visitAnyEnumType(CanType type, EnumDecl *decl) {
return visitEnumDecl(decl);
}
bool visitEnumDecl(EnumDecl *decl) {
if (decl->isIndirect())
Expand All @@ -835,12 +830,9 @@ namespace {
}

// A class reference does not depend on the layout of the class.
bool visitClassType(CanClassType type) {
bool visitAnyClassType(CanType type, ClassDecl *decl) {
return false;
}
bool visitBoundGenericClassType(CanBoundGenericClassType type) {
return false;
}

// The same for non-strong references.
bool visitReferenceStorageType(CanReferenceStorageType type) {
Expand Down