@@ -724,13 +724,6 @@ struct AppliedBuilderTransform {
724
724
725
725
// / The return expression, capturing the last value to be emitted.
726
726
Expr *returnExpr = nullptr ;
727
-
728
- using PatternEntry = std::pair<const PatternBindingDecl *, unsigned >;
729
-
730
- // / Mapping from specific pattern binding entries to the solution application
731
- // / targets capturing their initialization.
732
- llvm::DenseMap<PatternEntry, SolutionApplicationTarget>
733
- patternBindingEntries;
734
727
};
735
728
736
729
// / Describes the fixed score of a solution to the constraint system.
@@ -855,8 +848,111 @@ struct ForEachStmtInfo {
855
848
856
849
// / Key to the constraint solver's mapping from AST nodes to their corresponding
857
850
// / solution application targets.
858
- using SolutionApplicationTargetsKey =
859
- PointerUnion<const StmtConditionElement *, const Stmt *>;
851
+ class SolutionApplicationTargetsKey {
852
+ public:
853
+ enum class Kind {
854
+ empty,
855
+ tombstone,
856
+ stmtCondElement,
857
+ stmt,
858
+ patternBindingEntry,
859
+ };
860
+
861
+ private:
862
+ Kind kind;
863
+
864
+ union {
865
+ const StmtConditionElement *stmtCondElement;
866
+
867
+ const Stmt *stmt;
868
+
869
+ struct PatternBindingEntry {
870
+ const PatternBindingDecl *patternBinding;
871
+ unsigned index;
872
+ } patternBindingEntry;
873
+ } storage;
874
+
875
+ public:
876
+ SolutionApplicationTargetsKey (Kind kind) {
877
+ assert (kind == Kind::empty || kind == Kind::tombstone);
878
+ this ->kind = kind;
879
+ }
880
+
881
+ SolutionApplicationTargetsKey (const StmtConditionElement *stmtCondElement) {
882
+ kind = Kind::stmtCondElement;
883
+ storage.stmtCondElement = stmtCondElement;
884
+ }
885
+
886
+ SolutionApplicationTargetsKey (const Stmt *stmt) {
887
+ kind = Kind::stmt;
888
+ storage.stmt = stmt;
889
+ }
890
+
891
+ SolutionApplicationTargetsKey (
892
+ const PatternBindingDecl *patternBinding, unsigned index) {
893
+ kind = Kind::stmt;
894
+ storage.patternBindingEntry .patternBinding = patternBinding;
895
+ storage.patternBindingEntry .index = index;
896
+ }
897
+
898
+ friend bool operator ==(
899
+ SolutionApplicationTargetsKey lhs, SolutionApplicationTargetsKey rhs) {
900
+ if (lhs.kind != rhs.kind )
901
+ return false ;
902
+
903
+ switch (lhs.kind ) {
904
+ case Kind::empty:
905
+ case Kind::tombstone:
906
+ return true ;
907
+
908
+ case Kind::stmtCondElement:
909
+ return lhs.storage .stmtCondElement == rhs.storage .stmtCondElement ;
910
+
911
+ case Kind::stmt:
912
+ return lhs.storage .stmt == rhs.storage .stmt ;
913
+
914
+ case Kind::patternBindingEntry:
915
+ return (lhs.storage .patternBindingEntry .patternBinding
916
+ == rhs.storage .patternBindingEntry .patternBinding ) &&
917
+ (lhs.storage .patternBindingEntry .index
918
+ == rhs.storage .patternBindingEntry .index );
919
+ }
920
+ }
921
+
922
+ friend bool operator !=(
923
+ SolutionApplicationTargetsKey lhs, SolutionApplicationTargetsKey rhs) {
924
+ return !(lhs == rhs);
925
+ }
926
+
927
+ unsigned getHashValue () const {
928
+ using llvm::hash_combine;
929
+ using llvm::DenseMapInfo;
930
+
931
+ switch (kind) {
932
+ case Kind::empty:
933
+ case Kind::tombstone:
934
+ return llvm::DenseMapInfo<unsigned >::getHashValue (static_cast <unsigned >(kind));
935
+
936
+ case Kind::stmtCondElement:
937
+ return hash_combine (
938
+ DenseMapInfo<unsigned >::getHashValue (static_cast <unsigned >(kind)),
939
+ DenseMapInfo<void *>::getHashValue (storage.stmtCondElement ));
940
+
941
+ case Kind::stmt:
942
+ return hash_combine (
943
+ DenseMapInfo<unsigned >::getHashValue (static_cast <unsigned >(kind)),
944
+ DenseMapInfo<void *>::getHashValue (storage.stmt ));
945
+
946
+ case Kind::patternBindingEntry:
947
+ return hash_combine (
948
+ DenseMapInfo<unsigned >::getHashValue (static_cast <unsigned >(kind)),
949
+ DenseMapInfo<void *>::getHashValue (
950
+ storage.patternBindingEntry .patternBinding ),
951
+ DenseMapInfo<unsigned >::getHashValue (
952
+ storage.patternBindingEntry .index ));
953
+ }
954
+ }
955
+ };
860
956
861
957
// / A complete solution to a constraint system.
862
958
// /
@@ -2610,7 +2706,6 @@ class ConstraintSystem {
2610
2706
2611
2707
void setSolutionApplicationTarget (
2612
2708
SolutionApplicationTargetsKey key, SolutionApplicationTarget target) {
2613
- assert (key && " Expected non-null solution application target key!" );
2614
2709
assert (solutionApplicationTargets.count (key) == 0 &&
2615
2710
" Already set this solution application target" );
2616
2711
solutionApplicationTargets.insert ({key, target});
@@ -5501,4 +5596,25 @@ void forEachExprInConstraintSystem(
5501
5596
5502
5597
} // end namespace swift
5503
5598
5599
+ namespace llvm {
5600
+ template <>
5601
+ struct DenseMapInfo <swift::constraints::SolutionApplicationTargetsKey> {
5602
+ using Key = swift::constraints::SolutionApplicationTargetsKey;
5603
+
5604
+ static inline Key getEmptyKey () {
5605
+ return Key (Key::Kind::empty);
5606
+ }
5607
+ static inline Key getTombstoneKey () {
5608
+ return Key (Key::Kind::tombstone);
5609
+ }
5610
+ static inline unsigned getHashValue (Key key) {
5611
+ return key.getHashValue ();
5612
+ }
5613
+ static bool isEqual (Key a, Key b) {
5614
+ return a == b;
5615
+ }
5616
+ };
5617
+
5618
+ }
5619
+
5504
5620
#endif // LLVM_SWIFT_SEMA_CONSTRAINT_SYSTEM_H
0 commit comments