| //===--- SubstitutionMap.h - Swift Substitution Map ASTs --------*- 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 the SubstitutionMap class. |
| // |
| // This is a data structure type describing the mapping of abstract types to |
| // replacement types, together with associated conformances to use for deriving |
| // nested types. |
| // |
| // Depending on how the SubstitutionMap is constructed, the abstract types are |
| // either archetypes or interface types. Care must be exercised to only look up |
| // one or the other. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_AST_SUBSTITUTION_MAP_H |
| #define SWIFT_AST_SUBSTITUTION_MAP_H |
| |
| #include "swift/AST/ProtocolConformanceRef.h" |
| #include "swift/AST/Type.h" |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/ADT/Optional.h" |
| #include "llvm/ADT/SmallVector.h" |
| |
| namespace swift { |
| |
| class SubstitutableType; |
| |
| template<class Type> class CanTypeWrapper; |
| typedef CanTypeWrapper<SubstitutableType> CanSubstitutableType; |
| |
| class SubstitutionMap { |
| using ParentType = std::pair<CanType, AssociatedTypeDecl *>; |
| |
| llvm::DenseMap<SubstitutableType *, Type> subMap; |
| llvm::DenseMap<TypeBase *, SmallVector<ProtocolConformanceRef, 1>> conformanceMap; |
| llvm::DenseMap<TypeBase *, SmallVector<ParentType, 1>> parentMap; |
| |
| Optional<ProtocolConformanceRef> |
| lookupConformance(ProtocolDecl *proto, |
| ArrayRef<ProtocolConformanceRef> conformances) const; |
| |
| template<typename Fn> |
| Optional<ProtocolConformanceRef> forEachParent(CanType type, Fn fn) const; |
| |
| public: |
| Optional<ProtocolConformanceRef> |
| lookupConformance(CanType type, ProtocolDecl *proto) const; |
| |
| const llvm::DenseMap<SubstitutableType *, Type> &getMap() const { |
| return subMap; |
| } |
| |
| /// Retrieve the conformances for the given type. |
| ArrayRef<ProtocolConformanceRef> getConformances(CanType type) const; |
| |
| void addSubstitution(CanSubstitutableType type, Type replacement); |
| |
| void addConformance(CanType type, ProtocolConformanceRef conformance); |
| |
| void addParent(CanType type, CanType parent, |
| AssociatedTypeDecl *assocType); |
| |
| bool empty() const { |
| return subMap.empty(); |
| } |
| |
| /// Given that 'derivedDecl' is an override of 'baseDecl' in a subclass, |
| /// and 'derivedSubs' is a set of substitutions written in terms of the |
| /// generic signature of 'derivedDecl', produce a set of substitutions |
| /// written in terms of the generic signature of 'baseDecl'. |
| static SubstitutionMap |
| getOverrideSubstitutions(const ValueDecl *baseDecl, |
| const ValueDecl *derivedDecl, |
| Optional<SubstitutionMap> derivedSubs, |
| LazyResolver *resolver); |
| |
| /// Variant of the above for when we have the generic signatures but not |
| /// the decls for 'derived' and 'base'. |
| static SubstitutionMap |
| getOverrideSubstitutions(const ClassDecl *baseClass, |
| const ClassDecl *derivedClass, |
| GenericSignature *baseSig, |
| GenericSignature *derivedSig, |
| Optional<SubstitutionMap> derivedSubs, |
| LazyResolver *resolver); |
| }; |
| |
| } // end namespace swift |
| |
| #endif |