//===--- ProtocolConformanceAnalysis.h - Protocol Conformance ---*- 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 analysis collects a set of nominal types (classes, structs, and enums) // that conform to a protocol during whole module compilation. We only track // protocols that are non-public. #ifndef SWIFT_SILOPTIMIZER_ANALYSIS_PROTOCOLCONFORMANCE_H #define SWIFT_SILOPTIMIZER_ANALYSIS_PROTOCOLCONFORMANCE_H #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILValue.h" #include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Debug.h" namespace swift { class SILModule; class NominalTypeDecl; class ProtocolDecl; class ProtocolConformanceAnalysis : public SILAnalysis { public: typedef SmallVector NominalTypeList; typedef llvm::DenseMap ProtocolConformanceMap; typedef llvm::DenseMap SoleConformingTypeMap; ProtocolConformanceAnalysis(SILModule *Mod) : SILAnalysis(SILAnalysisKind::ProtocolConformance), M(Mod) {} ~ProtocolConformanceAnalysis(); static bool classof(const SILAnalysis *S) { return S->getKind() == SILAnalysisKind::ProtocolConformance; } /// Invalidate all information in this analysis. virtual void invalidate() override {} /// Invalidate all of the information for a specific function. virtual void invalidate(SILFunction *F, InvalidationKind K) override {} /// Notify the analysis about a newly created function. virtual void notifyAddedOrModifiedFunction(SILFunction *F) override {} /// Notify the analysis about a function which will be deleted from the /// module. virtual void notifyWillDeleteFunction(SILFunction *F) override {} /// Notify the analysis about changed witness or vtables. virtual void invalidateFunctionTables() override {} /// Get the nominal types that implement a protocol. ArrayRef getConformances(const ProtocolDecl *P) { populateConformanceCacheIfNecessary(); auto ConformsListIt = ProtocolConformanceCache->find(P); return ConformsListIt != ProtocolConformanceCache->end() ? ArrayRef(ConformsListIt->second.begin(), ConformsListIt->second.end()) : ArrayRef(); } /// Traverse ProtocolConformanceMapCache recursively to determine sole /// conforming concrete type. NominalTypeDecl *findSoleConformingType(ProtocolDecl *Protocol); // Wrapper function to findSoleConformingType that checks for additional // constraints for classes using ClassHierarchyAnalysis. bool getSoleConformingType(ProtocolDecl *Protocol, ClassHierarchyAnalysis *CHA, CanType &ConcreteType); private: /// The module. SILModule *M; /// A cache that maps a protocol to its conformances. std::optional ProtocolConformanceCache; /// A cache that holds SoleConformingType for protocols. SoleConformingTypeMap SoleConformingTypeCache; /// Populates `ProtocolConformanceCache` if necessary. void populateConformanceCacheIfNecessary(); }; } // namespace swift #endif