@@ -28,8 +28,7 @@ class SILValue;
28
28
class SILBuilder ;
29
29
class SerializedSILLoader ;
30
30
31
- struct APIntSymbolicValue ;
32
- struct ArraySymbolicValue ;
31
+ struct SymbolicArrayStorage ;
33
32
struct DerivedAddressValue ;
34
33
struct EnumWithPayloadSymbolicValue ;
35
34
struct SymbolicValueMemoryObject ;
@@ -256,6 +255,12 @@ class SymbolicValue {
256
255
257
256
// / This represents an index *into* a memory object.
258
257
RK_DerivedAddress,
258
+
259
+ // / This represents the internal storage of an array.
260
+ RK_ArrayStorage,
261
+
262
+ // / This represents an array.
263
+ RK_Array,
259
264
};
260
265
261
266
union {
@@ -299,6 +304,31 @@ class SymbolicValue {
299
304
// / When this SymbolicValue is of "DerivedAddress" kind, this pointer stores
300
305
// / information about the memory object and access path of the access.
301
306
DerivedAddressValue *derivedAddress;
307
+
308
+ // The following fields are for representing an Array.
309
+ //
310
+ // In Swift, an array is a non-trivial struct that stores a reference to an
311
+ // internal storage: _ContiguousArrayStorage. Though arrays have value
312
+ // semantics in Swift, it is not the case in SIL. In SIL, an array can be
313
+ // mutated by taking the address of the internal storage i.e., through a
314
+ // shared, mutable pointer to the internal storage of the array. In fact,
315
+ // this is how an array initialization is lowered in SIL. Therefore, the
316
+ // symbolic representation of an array is an addressable "memory cell"
317
+ // (i.e., a SymbolicValueMemoryObject) containing the array storage. The
318
+ // array storage is modeled by the type: SymbolicArrayStorage. This
319
+ // representation of the array enables obtaining the address of the internal
320
+ // storage and modifying the array through that address. Array operations
321
+ // such as `append` that mutate an array must clone the internal storage of
322
+ // the array, following the semantics of the Swift implementation of those
323
+ // operations.
324
+
325
+ // / Representation of array storage (RK_ArrayStorage). SymbolicArrayStorage
326
+ // / is a container for a sequence of symbolic values.
327
+ SymbolicArrayStorage *arrayStorage;
328
+
329
+ // / When this symbolic value is of an "Array" kind, this stores a memory
330
+ // / object that contains a SymbolicArrayStorage value.
331
+ SymbolicValueMemoryObject *array;
302
332
} value;
303
333
304
334
RepresentationKind representationKind : 8 ;
@@ -348,6 +378,12 @@ class SymbolicValue {
348
378
// / This value represents the address of, or into, a memory object.
349
379
Address,
350
380
381
+ // / This represents an internal array storage.
382
+ ArrayStorage,
383
+
384
+ // / This represents an array value.
385
+ Array,
386
+
351
387
// / These values are generally only seen internally to the system, external
352
388
// / clients shouldn't have to deal with them.
353
389
UninitMemory
@@ -471,6 +507,32 @@ class SymbolicValue {
471
507
// / Return just the memory object for an address value.
472
508
SymbolicValueMemoryObject *getAddressValueMemoryObject () const ;
473
509
510
+ // / Create a symbolic array storage containing \c elements.
511
+ static SymbolicValue
512
+ getSymbolicArrayStorage (ArrayRef<SymbolicValue> elements, CanType elementType,
513
+ SymbolicValueAllocator &allocator);
514
+
515
+ // / Create a symbolic array using the given symbolic array storage, which
516
+ // / contains the array elements.
517
+ static SymbolicValue getArray (Type arrayType, SymbolicValue arrayStorage,
518
+ SymbolicValueAllocator &allocator);
519
+
520
+ // / Return the elements stored in this SymbolicValue of "ArrayStorage" kind.
521
+ ArrayRef<SymbolicValue> getStoredElements (CanType &elementType) const ;
522
+
523
+ // / Return the symbolic value representing the internal storage of this array.
524
+ SymbolicValue getStorageOfArray () const ;
525
+
526
+ // / Return the symbolic value representing the address of the element of this
527
+ // / array at the given \c index. The return value is a derived address whose
528
+ // / base is the memory object \c value.array (which contains the array
529
+ // / storage) and whose accesspath is \c index.
530
+ SymbolicValue getAddressOfArrayElement (SymbolicValueAllocator &allocator,
531
+ unsigned index) const ;
532
+
533
+ // / Return the type of this array symbolic value.
534
+ Type getArrayType () const ;
535
+
474
536
// ===--------------------------------------------------------------------===//
475
537
// Helpers
476
538
@@ -545,7 +607,6 @@ struct SymbolicValueMemoryObject {
545
607
SymbolicValueMemoryObject (const SymbolicValueMemoryObject &) = delete ;
546
608
void operator =(const SymbolicValueMemoryObject &) = delete ;
547
609
};
548
-
549
610
} // end namespace swift
550
611
551
612
#endif
0 commit comments