@@ -106,6 +106,27 @@ void SymbolicValue::print(llvm::raw_ostream &os, unsigned indent) const {
106
106
os << " \n " ;
107
107
break ;
108
108
}
109
+ case RK_Array:
110
+ case RK_ArrayAddress: {
111
+ CanType elementType;
112
+ ArrayRef<SymbolicValue> elements = getArrayValue (elementType);
113
+ os << " array<" << elementType << " >: " << elements.size ();
114
+ switch (elements.size ()) {
115
+ case 0 :
116
+ os << " elements []\n " ;
117
+ return ;
118
+ case 1 :
119
+ os << " elt: " ;
120
+ elements[0 ].print (os, indent + 2 );
121
+ return ;
122
+ default :
123
+ os << " elements [\n " ;
124
+ for (auto elt : elements)
125
+ elt.print (os, indent + 2 );
126
+ os.indent (indent) << " ]\n " ;
127
+ return ;
128
+ }
129
+ }
109
130
}
110
131
}
111
132
@@ -137,6 +158,9 @@ SymbolicValue::Kind SymbolicValue::getKind() const {
137
158
case RK_DirectAddress:
138
159
case RK_DerivedAddress:
139
160
return Address;
161
+ case RK_Array:
162
+ case RK_ArrayAddress:
163
+ return Array;
140
164
}
141
165
}
142
166
@@ -177,6 +201,16 @@ SymbolicValue::cloneInto(ASTContext &astContext) const {
177
201
memObject->getType (), memObject->getValue (), astContext);
178
202
return getAddress (newMemObject, accessPath, astContext);
179
203
}
204
+ case RK_Array:
205
+ case RK_ArrayAddress: {
206
+ CanType elementType;
207
+ auto elts = getArrayValue (elementType);
208
+ SmallVector<SymbolicValue, 4 > results;
209
+ results.reserve (elts.size ());
210
+ for (auto elt : elts)
211
+ results.push_back (elt.cloneInto (astContext));
212
+ return getArray (results, elementType, astContext);
213
+ }
180
214
}
181
215
}
182
216
@@ -520,6 +554,81 @@ SymbolicValueMemoryObject *SymbolicValue::getAddressValueMemoryObject() const {
520
554
return value.derivedAddress ->memoryObject ;
521
555
}
522
556
557
+ // ===----------------------------------------------------------------------===//
558
+ // Arrays
559
+ // ===----------------------------------------------------------------------===//
560
+
561
+ namespace swift {
562
+
563
+ // / This is the representation of an array.
564
+ struct ArraySymbolicValue final
565
+ : private llvm::TrailingObjects<ArraySymbolicValue, SymbolicValue> {
566
+ friend class llvm ::TrailingObjects<ArraySymbolicValue, SymbolicValue>;
567
+
568
+ const CanType elementType;
569
+
570
+ // / This is the number of indices in the derived address.
571
+ const unsigned numElements;
572
+
573
+ static ArraySymbolicValue *create (ArrayRef<SymbolicValue> elements,
574
+ CanType elementType,
575
+ ASTContext &astContext) {
576
+ auto byteSize =
577
+ ArraySymbolicValue::totalSizeToAlloc<SymbolicValue>(elements.size ());
578
+ auto rawMem = astContext.Allocate (byteSize, alignof (ArraySymbolicValue));
579
+
580
+ // Placement initialize the object.
581
+ auto asv = ::new (rawMem) ArraySymbolicValue (elementType, elements.size ());
582
+ std::uninitialized_copy (elements.begin (), elements.end (),
583
+ asv->getTrailingObjects <SymbolicValue>());
584
+ return asv;
585
+ }
586
+
587
+ // / Return the element constants for this aggregate constant. These are
588
+ // / known to all be constants.
589
+ ArrayRef<SymbolicValue> getElements () const {
590
+ return {getTrailingObjects<SymbolicValue>(), numElements};
591
+ }
592
+
593
+ // This is used by the llvm::TrailingObjects base class.
594
+ size_t numTrailingObjects (OverloadToken<SymbolicValue>) const {
595
+ return numElements;
596
+ }
597
+
598
+ private:
599
+ ArraySymbolicValue () = delete ;
600
+ ArraySymbolicValue (const ArraySymbolicValue &) = delete ;
601
+ ArraySymbolicValue (CanType elementType, unsigned numElements)
602
+ : elementType(elementType), numElements(numElements) {}
603
+ };
604
+ } // end namespace swift
605
+
606
+ // / Produce an array of elements.
607
+ SymbolicValue SymbolicValue::getArray (ArrayRef<SymbolicValue> elements,
608
+ CanType elementType,
609
+ ASTContext &astContext) {
610
+ // TODO: Could compress the empty array representation if there were a reason
611
+ // to.
612
+ auto asv = ArraySymbolicValue::create (elements, elementType, astContext);
613
+ SymbolicValue result;
614
+ result.representationKind = RK_Array;
615
+ result.value .array = asv;
616
+ return result;
617
+ }
618
+
619
+ ArrayRef<SymbolicValue>
620
+ SymbolicValue::getArrayValue (CanType &elementType) const {
621
+ assert (getKind () == Array);
622
+ auto val = *this ;
623
+ if (representationKind == RK_ArrayAddress)
624
+ val = value.arrayAddress ->getValue ();
625
+
626
+ assert (val.representationKind == RK_Array);
627
+
628
+ elementType = val.value .array ->elementType ;
629
+ return val.value .array ->getElements ();
630
+ }
631
+
523
632
// ===----------------------------------------------------------------------===//
524
633
// Higher level code
525
634
// ===----------------------------------------------------------------------===//
@@ -653,22 +762,32 @@ static SymbolicValue getIndexedElement(SymbolicValue aggregate,
653
762
if (aggregate.getKind () == SymbolicValue::UninitMemory)
654
763
return SymbolicValue::getUninitMemory ();
655
764
656
- assert (aggregate.getKind () == SymbolicValue::Aggregate &&
765
+ assert ((aggregate.getKind () == SymbolicValue::Aggregate ||
766
+ aggregate.getKind () == SymbolicValue::Array) &&
657
767
" the accessPath is invalid for this type" );
658
768
659
769
unsigned elementNo = accessPath.front ();
660
770
661
- SymbolicValue elt = aggregate. getAggregateValue ()[elementNo] ;
771
+ SymbolicValue elt;
662
772
Type eltType;
663
- if (auto *decl = type->getStructOrBoundGenericStruct ()) {
664
- auto it = decl->getStoredProperties ().begin ();
665
- std::advance (it, elementNo);
666
- eltType = (*it)->getType ();
667
- } else if (auto tuple = type->getAs <TupleType>()) {
668
- assert (elementNo < tuple->getNumElements () && " invalid index" );
669
- eltType = tuple->getElement (elementNo).getType ();
773
+
774
+ // We need to have an array, struct or a tuple type.
775
+ if (aggregate.getKind () == SymbolicValue::Array) {
776
+ CanType arrayEltTy;
777
+ elt = aggregate.getArrayValue (arrayEltTy)[elementNo];
778
+ eltType = arrayEltTy;
670
779
} else {
671
- llvm_unreachable (" the accessPath is invalid for this type" );
780
+ elt = aggregate.getAggregateValue ()[elementNo];
781
+ if (auto *decl = type->getStructOrBoundGenericStruct ()) {
782
+ auto it = decl->getStoredProperties ().begin ();
783
+ std::advance (it, elementNo);
784
+ eltType = (*it)->getType ();
785
+ } else if (auto tuple = type->getAs <TupleType>()) {
786
+ assert (elementNo < tuple->getNumElements () && " invalid index" );
787
+ eltType = tuple->getElement (elementNo).getType ();
788
+ } else {
789
+ llvm_unreachable (" the accessPath is invalid for this type" );
790
+ }
672
791
}
673
792
674
793
return getIndexedElement (elt, accessPath.drop_front (), eltType);
@@ -718,22 +837,33 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
718
837
aggregate = SymbolicValue::getAggregate (newElts, astCtx);
719
838
}
720
839
721
- assert (aggregate.getKind () == SymbolicValue::Aggregate &&
840
+ assert ((aggregate.getKind () == SymbolicValue::Aggregate ||
841
+ aggregate.getKind () == SymbolicValue::Array) &&
722
842
" the accessPath is invalid for this type" );
723
843
724
844
unsigned elementNo = accessPath.front ();
725
845
726
- ArrayRef<SymbolicValue> oldElts = aggregate. getAggregateValue () ;
846
+ ArrayRef<SymbolicValue> oldElts;
727
847
Type eltType;
728
- if (auto *decl = type->getStructOrBoundGenericStruct ()) {
729
- auto it = decl->getStoredProperties ().begin ();
730
- std::advance (it, elementNo);
731
- eltType = (*it)->getType ();
732
- } else if (auto tuple = type->getAs <TupleType>()) {
733
- assert (elementNo < tuple->getNumElements () && " invalid index" );
734
- eltType = tuple->getElement (elementNo).getType ();
848
+
849
+ // We need to have an array, struct or a tuple type.
850
+ if (aggregate.getKind () == SymbolicValue::Array) {
851
+ CanType arrayEltTy;
852
+ oldElts = aggregate.getArrayValue (arrayEltTy);
853
+ eltType = arrayEltTy;
735
854
} else {
736
- llvm_unreachable (" the accessPath is invalid for this type" );
855
+ oldElts = aggregate.getAggregateValue ();
856
+
857
+ if (auto *decl = type->getStructOrBoundGenericStruct ()) {
858
+ auto it = decl->getStoredProperties ().begin ();
859
+ std::advance (it, elementNo);
860
+ eltType = (*it)->getType ();
861
+ } else if (auto tuple = type->getAs <TupleType>()) {
862
+ assert (elementNo < tuple->getNumElements () && " invalid index" );
863
+ eltType = tuple->getElement (elementNo).getType ();
864
+ } else {
865
+ llvm_unreachable (" the accessPath is invalid for this type" );
866
+ }
737
867
}
738
868
739
869
// Update the indexed element of the aggregate.
@@ -742,7 +872,11 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
742
872
accessPath.drop_front (), newElement,
743
873
eltType, astCtx);
744
874
745
- aggregate = SymbolicValue::getAggregate (newElts, astCtx);
875
+ if (aggregate.getKind () == SymbolicValue::Aggregate)
876
+ aggregate = SymbolicValue::getAggregate (newElts, astCtx);
877
+ else
878
+ aggregate = SymbolicValue::getArray (newElts, eltType->getCanonicalType (),
879
+ astCtx);
746
880
747
881
return aggregate;
748
882
}
0 commit comments