I was looking at swift enums (with value) and noticed they're stored as
{ , } where integer is the enum value, and is sized by the max enum cases.
As far as I could detect, they're all in order of definition, however Optional<T>
does not seem to match this pattern:
@_frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
Why is "none" stored as 1 and some as 0?
var x: Int!
x = 15
x = 13
x = nil
%8 = bitcast %TSiSg* %0 to i64*
store i64 15, i64* %8, align 8
%9 = getelementptr inbounds %TSiSg, %TSiSg* %0, i32 0, i32 1
%10 = bitcast [1 x i8]* %9 to i1*
store i1 false, i1* %10, align 8
%11 = bitcast %TSiSg* %0 to i64*
store i64 13, i64* %11, align 8
%12 = getelementptr inbounds %TSiSg, %TSiSg* %0, i32 0, i32 1
%13 = bitcast [1 x i8]* %12 to i1*
store i1 false, i1* %13, align 8
%14 = bitcast %TSiSg* %0 to i64*
store i64 0, i64* %14, align 8
%15 = getelementptr inbounds %TSiSg, %TSiSg* %0, i32 0, i32 1
%16 = bitcast [1 x i8]* %15 to i1*
store i1 true, i1* %16, align 8
can anyone shed some light on this?
Update:
if I read this correctly; There are two cases, if T is a value type, enum values use logical ordering for the cases with associated data, then if there are cases with non associated data, they use the following numeric value, those then are numbered separately from 0 and are stored in the data itself.
For reference types, the same idea goes, but if there's only 2 options, 1 with and 1 without, it uses nil as a marker for the without associated data case, and stores it as just 1 single field.
Can anyone confirm this is the case?