diff --git a/include/swift/AST/CanTypeVisitor.h b/include/swift/AST/CanTypeVisitor.h index 658f01488ecbf..d0b163630973b 100644 --- a/include/swift/AST/CanTypeVisitor.h +++ b/include/swift/AST/CanTypeVisitor.h @@ -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 +class CanTypeVisitor_AnyNominal : public CanTypeVisitor { +public: + RetTy visitClassType(CanClassType T, Args... args) { + return static_cast(this) + ->visitAnyClassType(T, T->getDecl(), ::std::forward(args)...); + } + RetTy visitBoundGenericClassType(CanBoundGenericClassType T, Args... args) { + return static_cast(this) + ->visitAnyClassType(T, T->getDecl(), ::std::forward(args)...); + } + RetTy visitAnyClassType(CanType T, ClassDecl *D, Args... args) { + return static_cast(this) + ->visitAnyNominalType(T, D, ::std::forward(args)...); + } + + RetTy visitStructType(CanStructType T, Args... args) { + return static_cast(this) + ->visitAnyStructType(T, T->getDecl(), ::std::forward(args)...); + } + RetTy visitBoundGenericStructType(CanBoundGenericStructType T, Args... args) { + return static_cast(this) + ->visitAnyStructType(T, T->getDecl(), ::std::forward(args)...); + } + RetTy visitAnyStructType(CanType T, StructDecl *D, Args... args) { + return static_cast(this) + ->visitAnyNominalType(T, D, ::std::forward(args)...); + } + + RetTy visitEnumType(CanEnumType T, Args... args) { + return static_cast(this) + ->visitAnyEnumType(T, T->getDecl(), ::std::forward(args)...); + } + RetTy visitBoundGenericEnumType(CanBoundGenericEnumType T, Args... args) { + return static_cast(this) + ->visitAnyEnumType(T, T->getDecl(), ::std::forward(args)...); + } + RetTy visitAnyEnumType(CanType T, EnumDecl *D, Args... args) { + return static_cast(this) + ->visitAnyNominalType(T, D, ::std::forward(args)...); + } + + RetTy visitProtocolType(CanProtocolType T, Args... args) { + return static_cast(this) + ->visitAnyNominalType(T, T->getDecl(), ::std::forward(args)...); + } + + RetTy visitAnyNominalType(CanType T, NominalTypeDecl *D, Args... args) { + return static_cast(this) + ->visitType(T, ::std::forward(args)...); + } +}; + } // end namespace swift #endif diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index c5fc0b6f837fa..0a31356b732c6 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -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" diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 635f792db3a44..d320d85ca3909 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -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" diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 0a6bea0cc8ba1..d5cb390955fb6 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -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 { + class IsIRTypeDependent : + public CanTypeVisitor_AnyNominal { IRGenModule &IGM; public: IsIRTypeDependent(IRGenModule &IGM) : IGM(IGM) {} @@ -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)) @@ -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)) @@ -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; diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index bfd08bc1959a0..9a325e8e6e85e 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -3615,8 +3615,8 @@ namespace { /// valid recursive types bottom out in fixed-sized types like classes /// or pointers.) class EmitTypeLayoutRef - : public CanTypeVisitor { + : public CanTypeVisitor_AnyNominal { private: IRGenFunction &IGF; public: @@ -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); @@ -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(""); diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 0799eeca1702a..cae226d28d52a 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -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" diff --git a/lib/SILOptimizer/Utils/InstOptUtils.cpp b/lib/SILOptimizer/Utils/InstOptUtils.cpp index c17b5b83dbc3b..eef9a57156949 100644 --- a/lib/SILOptimizer/Utils/InstOptUtils.cpp +++ b/lib/SILOptimizer/Utils/InstOptUtils.cpp @@ -774,7 +774,8 @@ swift::castValueToABICompatibleType(SILBuilder *builder, SILPassManager *pm, } namespace { - class TypeDependentVisitor : public CanTypeVisitor { + class TypeDependentVisitor : + public CanTypeVisitor_AnyNominal { public: // If the type isn't actually dependent, we're okay. bool visit(CanType type) { @@ -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(); @@ -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()) @@ -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) {