@@ -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,82 @@ 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 a derived address. A derived address refers
564
+ // / to a memory object along with an access path that drills into it.
565
+ struct ArraySymbolicValue final
566
+ : private llvm::TrailingObjects<ArraySymbolicValue, SymbolicValue> {
567
+ friend class llvm ::TrailingObjects<ArraySymbolicValue, SymbolicValue>;
568
+
569
+ const CanType elementType;
570
+
571
+ // / This is the number of indices in the derived address.
572
+ const unsigned numElements;
573
+
574
+ static ArraySymbolicValue *create (ArrayRef<SymbolicValue> elements,
575
+ CanType elementType,
576
+ ASTContext &astContext) {
577
+ auto byteSize =
578
+ ArraySymbolicValue::totalSizeToAlloc<SymbolicValue>(elements.size ());
579
+ auto rawMem = astContext.Allocate (byteSize, alignof (ArraySymbolicValue));
580
+
581
+ // Placement initialize the object.
582
+ auto asv = ::new (rawMem) ArraySymbolicValue (elementType, elements.size ());
583
+ std::uninitialized_copy (elements.begin (), elements.end (),
584
+ asv->getTrailingObjects <SymbolicValue>());
585
+ return asv;
586
+ }
587
+
588
+ // / Return the element constants for this aggregate constant. These are
589
+ // / known to all be constants.
590
+ ArrayRef<SymbolicValue> getElements () const {
591
+ return {getTrailingObjects<SymbolicValue>(), numElements};
592
+ }
593
+
594
+ // This is used by the llvm::TrailingObjects base class.
595
+ size_t numTrailingObjects (OverloadToken<SymbolicValue>) const {
596
+ return numElements;
597
+ }
598
+
599
+ private:
600
+ ArraySymbolicValue () = delete ;
601
+ ArraySymbolicValue (const ArraySymbolicValue &) = delete ;
602
+ ArraySymbolicValue (CanType elementType, unsigned numElements)
603
+ : elementType(elementType), numElements(numElements) {}
604
+ };
605
+ } // end namespace swift
606
+
607
+ // / Produce an array of elements.
608
+ SymbolicValue SymbolicValue::getArray (ArrayRef<SymbolicValue> elements,
609
+ CanType elementType,
610
+ ASTContext &astContext) {
611
+ // TODO: Could compress the empty array representation if there were a reason
612
+ // to.
613
+ auto asv = ArraySymbolicValue::create (elements, elementType, astContext);
614
+ SymbolicValue result;
615
+ result.representationKind = RK_Array;
616
+ result.value .array = asv;
617
+ return result;
618
+ }
619
+
620
+ ArrayRef<SymbolicValue>
621
+ SymbolicValue::getArrayValue (CanType &elementType) const {
622
+ assert (getKind () == Array);
623
+ auto val = *this ;
624
+ if (representationKind == RK_ArrayAddress)
625
+ val = value.arrayAddress ->getValue ();
626
+
627
+ assert (val.representationKind == RK_Array);
628
+
629
+ elementType = val.value .array ->elementType ;
630
+ return val.value .array ->getElements ();
631
+ }
632
+
523
633
// ===----------------------------------------------------------------------===//
524
634
// Higher level code
525
635
// ===----------------------------------------------------------------------===//
@@ -653,22 +763,32 @@ static SymbolicValue getIndexedElement(SymbolicValue aggregate,
653
763
if (aggregate.getKind () == SymbolicValue::UninitMemory)
654
764
return SymbolicValue::getUninitMemory ();
655
765
656
- assert (aggregate.getKind () == SymbolicValue::Aggregate &&
766
+ assert ((aggregate.getKind () == SymbolicValue::Aggregate ||
767
+ aggregate.getKind () == SymbolicValue::Array) &&
657
768
" the accessPath is invalid for this type" );
658
769
659
770
unsigned elementNo = accessPath.front ();
660
771
661
- SymbolicValue elt = aggregate. getAggregateValue ()[elementNo] ;
772
+ SymbolicValue elt;
662
773
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 ();
774
+
775
+ // We need to have an array, struct or a tuple type.
776
+ if (aggregate.getKind () == SymbolicValue::Array) {
777
+ CanType arrayEltTy;
778
+ elt = aggregate.getArrayValue (arrayEltTy)[elementNo];
779
+ eltType = arrayEltTy;
670
780
} else {
671
- llvm_unreachable (" the accessPath is invalid for this type" );
781
+ elt = aggregate.getAggregateValue ()[elementNo];
782
+ if (auto *decl = type->getStructOrBoundGenericStruct ()) {
783
+ auto it = decl->getStoredProperties ().begin ();
784
+ std::advance (it, elementNo);
785
+ eltType = (*it)->getType ();
786
+ } else if (auto tuple = type->getAs <TupleType>()) {
787
+ assert (elementNo < tuple->getNumElements () && " invalid index" );
788
+ eltType = tuple->getElement (elementNo).getType ();
789
+ } else {
790
+ llvm_unreachable (" the accessPath is invalid for this type" );
791
+ }
672
792
}
673
793
674
794
return getIndexedElement (elt, accessPath.drop_front (), eltType);
@@ -718,22 +838,33 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
718
838
aggregate = SymbolicValue::getAggregate (newElts, astCtx);
719
839
}
720
840
721
- assert (aggregate.getKind () == SymbolicValue::Aggregate &&
841
+ assert ((aggregate.getKind () == SymbolicValue::Aggregate ||
842
+ aggregate.getKind () == SymbolicValue::Array) &&
722
843
" the accessPath is invalid for this type" );
723
844
724
845
unsigned elementNo = accessPath.front ();
725
846
726
- ArrayRef<SymbolicValue> oldElts = aggregate. getAggregateValue () ;
847
+ ArrayRef<SymbolicValue> oldElts;
727
848
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 ();
849
+
850
+ // We need to have an array, struct or a tuple type.
851
+ if (aggregate.getKind () == SymbolicValue::Array) {
852
+ CanType arrayEltTy;
853
+ oldElts = aggregate.getArrayValue (arrayEltTy);
854
+ eltType = arrayEltTy;
735
855
} else {
736
- llvm_unreachable (" the accessPath is invalid for this type" );
856
+ oldElts = aggregate.getAggregateValue ();
857
+
858
+ if (auto *decl = type->getStructOrBoundGenericStruct ()) {
859
+ auto it = decl->getStoredProperties ().begin ();
860
+ std::advance (it, elementNo);
861
+ eltType = (*it)->getType ();
862
+ } else if (auto tuple = type->getAs <TupleType>()) {
863
+ assert (elementNo < tuple->getNumElements () && " invalid index" );
864
+ eltType = tuple->getElement (elementNo).getType ();
865
+ } else {
866
+ llvm_unreachable (" the accessPath is invalid for this type" );
867
+ }
737
868
}
738
869
739
870
// Update the indexed element of the aggregate.
@@ -742,7 +873,11 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
742
873
accessPath.drop_front (), newElement,
743
874
eltType, astCtx);
744
875
745
- aggregate = SymbolicValue::getAggregate (newElts, astCtx);
876
+ if (aggregate.getKind () == SymbolicValue::Aggregate)
877
+ aggregate = SymbolicValue::getAggregate (newElts, astCtx);
878
+ else
879
+ aggregate = SymbolicValue::getArray (newElts, eltType->getCanonicalType (),
880
+ astCtx);
746
881
747
882
return aggregate;
748
883
}
0 commit comments