@@ -66,7 +66,7 @@ void SymbolicValue::print(llvm::raw_ostream &os, unsigned indent) const {
66
66
os << " string: \" " << getStringValue () << " \"\n " ;
67
67
return ;
68
68
case RK_Aggregate: {
69
- ArrayRef<SymbolicValue> elements = getAggregateValue ();
69
+ ArrayRef<SymbolicValue> elements = getAggregateMembers ();
70
70
switch (elements.size ()) {
71
71
case 0 :
72
72
os << " agg: 0 elements []\n " ;
@@ -211,12 +211,12 @@ SymbolicValue::cloneInto(SymbolicValueAllocator &allocator) const {
211
211
case RK_String:
212
212
return SymbolicValue::getString (getStringValue (), allocator);
213
213
case RK_Aggregate: {
214
- auto elts = getAggregateValue ();
214
+ auto elts = getAggregateMembers ();
215
215
SmallVector<SymbolicValue, 4 > results;
216
216
results.reserve (elts.size ());
217
217
for (auto elt : elts)
218
218
results.push_back (elt.cloneInto (allocator));
219
- return getAggregate (results, allocator);
219
+ return getAggregate (results, getAggregateType (), allocator);
220
220
}
221
221
case RK_EnumWithPayload: {
222
222
return getEnumWithPayload (
@@ -350,24 +350,71 @@ StringRef SymbolicValue::getStringValue() const {
350
350
// Aggregates
351
351
// ===----------------------------------------------------------------------===//
352
352
353
- // / This returns a constant Symbolic value with the specified elements in it.
354
- // / This assumes that the elements lifetime has been managed for this.
355
- SymbolicValue SymbolicValue::getAggregate (ArrayRef<SymbolicValue> elements,
356
- SymbolicValueAllocator &allocator) {
357
- // Copy the elements into the bump pointer.
358
- auto *resultElts = allocator.allocate <SymbolicValue>(elements.size ());
359
- std::uninitialized_copy (elements.begin (), elements.end (), resultElts);
353
+ namespace swift {
354
+
355
+ // / Representation of a constant aggregate namely a struct or a tuple.
356
+ struct AggregateSymbolicValue final
357
+ : private llvm::TrailingObjects<AggregateSymbolicValue, SymbolicValue> {
358
+ friend class llvm ::TrailingObjects<AggregateSymbolicValue, SymbolicValue>;
359
+
360
+ const Type aggregateType;
361
+
362
+ const unsigned numElements;
363
+
364
+ static AggregateSymbolicValue *create (ArrayRef<SymbolicValue> members,
365
+ Type aggregateType,
366
+ SymbolicValueAllocator &allocator) {
367
+ auto byteSize =
368
+ AggregateSymbolicValue::totalSizeToAlloc<SymbolicValue>(members.size ());
369
+ auto rawMem = allocator.allocate (byteSize, alignof (AggregateSymbolicValue));
370
+
371
+ // Placement initialize the object.
372
+ auto *aggregate =
373
+ ::new (rawMem) AggregateSymbolicValue (aggregateType, members.size ());
374
+ std::uninitialized_copy (members.begin (), members.end (),
375
+ aggregate->getTrailingObjects <SymbolicValue>());
376
+ return aggregate;
377
+ }
378
+
379
+ // / Return the type of the aggregate.
380
+ Type getAggregateType () const { return aggregateType; }
360
381
382
+ // / Return the symbolic values of members.
383
+ ArrayRef<SymbolicValue> getMemberValues () const {
384
+ return {getTrailingObjects<SymbolicValue>(), numElements};
385
+ }
386
+
387
+ // This is used by the llvm::TrailingObjects base class.
388
+ size_t numTrailingObjects (OverloadToken<SymbolicValue>) const {
389
+ return numElements;
390
+ }
391
+
392
+ private:
393
+ AggregateSymbolicValue () = delete ;
394
+ AggregateSymbolicValue (const AggregateSymbolicValue &) = delete ;
395
+ AggregateSymbolicValue (Type aggregateType, unsigned numElements)
396
+ : aggregateType(aggregateType), numElements(numElements) {}
397
+ };
398
+ } // namespace swift
399
+
400
+ SymbolicValue SymbolicValue::getAggregate (ArrayRef<SymbolicValue> members,
401
+ Type aggregateType,
402
+ SymbolicValueAllocator &allocator) {
361
403
SymbolicValue result;
362
404
result.representationKind = RK_Aggregate;
363
- result.value .aggregate = resultElts;
364
- result. auxInfo . aggregateNumElements = elements. size ( );
405
+ result.value .aggregate =
406
+ AggregateSymbolicValue::create (members, aggregateType, allocator );
365
407
return result;
366
408
}
367
409
368
- ArrayRef<SymbolicValue> SymbolicValue::getAggregateValue () const {
410
+ ArrayRef<SymbolicValue> SymbolicValue::getAggregateMembers () const {
369
411
assert (getKind () == Aggregate);
370
- return ArrayRef<SymbolicValue>(value.aggregate , auxInfo.aggregateNumElements );
412
+ return value.aggregate ->getMemberValues ();
413
+ }
414
+
415
+ Type SymbolicValue::getAggregateType () const {
416
+ assert (getKind () == Aggregate);
417
+ return value.aggregate ->getAggregateType ();
371
418
}
372
419
373
420
// ===----------------------------------------------------------------------===//
@@ -770,7 +817,7 @@ SymbolicValue SymbolicValue::lookThroughSingleElementAggregates() const {
770
817
while (1 ) {
771
818
if (result.getKind () != Aggregate)
772
819
return result;
773
- auto elts = result.getAggregateValue ();
820
+ auto elts = result.getAggregateMembers ();
774
821
if (elts.size () != 1 )
775
822
return result;
776
823
result = elts[0 ];
@@ -1009,7 +1056,7 @@ static SymbolicValue getIndexedElement(SymbolicValue aggregate,
1009
1056
elt = aggregate.getStoredElements (arrayEltTy)[elementNo];
1010
1057
eltType = arrayEltTy;
1011
1058
} else {
1012
- elt = aggregate.getAggregateValue ()[elementNo];
1059
+ elt = aggregate.getAggregateMembers ()[elementNo];
1013
1060
if (auto *decl = type->getStructOrBoundGenericStruct ()) {
1014
1061
eltType = decl->getStoredProperties ()[elementNo]->getType ();
1015
1062
} else if (auto tuple = type->getAs <TupleType>()) {
@@ -1063,7 +1110,7 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
1063
1110
1064
1111
SmallVector<SymbolicValue, 4 > newElts (numMembers,
1065
1112
SymbolicValue::getUninitMemory ());
1066
- aggregate = SymbolicValue::getAggregate (newElts, allocator);
1113
+ aggregate = SymbolicValue::getAggregate (newElts, type, allocator);
1067
1114
}
1068
1115
1069
1116
assert ((aggregate.getKind () == SymbolicValue::Aggregate ||
@@ -1080,7 +1127,7 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
1080
1127
oldElts = aggregate.getStoredElements (arrayEltTy);
1081
1128
eltType = arrayEltTy;
1082
1129
} else {
1083
- oldElts = aggregate.getAggregateValue ();
1130
+ oldElts = aggregate.getAggregateMembers ();
1084
1131
if (auto *decl = type->getStructOrBoundGenericStruct ()) {
1085
1132
eltType = decl->getStoredProperties ()[elementNo]->getType ();
1086
1133
} else if (auto tuple = type->getAs <TupleType>()) {
@@ -1097,8 +1144,12 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
1097
1144
setIndexedElement (newElts[elementNo], accessPath.drop_front (), newElement,
1098
1145
eltType, allocator);
1099
1146
1100
- if (aggregate.getKind () == SymbolicValue::Aggregate)
1101
- return SymbolicValue::getAggregate (newElts, allocator);
1147
+ if (aggregate.getKind () == SymbolicValue::Aggregate) {
1148
+ Type aggregateType = aggregate.getAggregateType ();
1149
+ assert (aggregateType->isEqual (type) &&
1150
+ " input type does not match the type of the aggregate" );
1151
+ return SymbolicValue::getAggregate (newElts, aggregateType, allocator);
1152
+ }
1102
1153
1103
1154
return aggregate = SymbolicValue::getSymbolicArrayStorage (
1104
1155
newElts, eltType->getCanonicalType (), allocator);
0 commit comments