summary refs log tree commit diff stats
path: root/compiler/sizealignoffsetimpl.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/sizealignoffsetimpl.nim')
-rw-r--r--compiler/sizealignoffsetimpl.nim41
1 files changed, 16 insertions, 25 deletions
diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim
index a34383d9f..fb256b895 100644
--- a/compiler/sizealignoffsetimpl.nim
+++ b/compiler/sizealignoffsetimpl.nim
@@ -18,7 +18,7 @@ const
   szIllegalRecursion* = -2
   szUncomputedSize* = -1
 
-proc computeSizeAlign(conf: ConfigRef; typ: PType): void
+proc computeSizeAlign(conf: ConfigRef; typ: PType)
 
 proc computeSubObjectAlign(conf: ConfigRef; n: PNode): BiggestInt =
   ## returns object alignment
@@ -49,13 +49,14 @@ proc computeSubObjectAlign(conf: ConfigRef; n: PNode): BiggestInt =
   else:
     result = 1
 
-proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, initialOffset: BiggestInt): tuple[offset, align: BiggestInt] =
+proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode,
+                                      initialOffset: BiggestInt): tuple[offset, align: BiggestInt] =
   ## ``offset`` is the offset within the object, after the node has been written, no padding bytes added
   ## ``align`` maximum alignment from all sub nodes
   assert n != nil
   if n.typ != nil and n.typ.size == szIllegalRecursion:
     result.offset = szIllegalRecursion
-    result.align  = szIllegalRecursion
+    result.align = szIllegalRecursion
     return
 
   result.align = 1
@@ -71,66 +72,52 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, initialOffset:
       of nkOfBranch, nkElse:
         # offset parameter cannot be known yet, it needs to know the alignment first
         let align = computeSubObjectAlign(conf, n.sons[i].lastSon)
-
         if align == szIllegalRecursion:
-          result.offset  = szIllegalRecursion
+          result.offset = szIllegalRecursion
           result.align = szIllegalRecursion
           return
-
         if align == szUnknownSize or maxChildAlign == szUnknownSize:
           maxChildAlign = szUnknownSize
         else:
           maxChildAlign = max(maxChildAlign, align)
       else:
         internalError(conf, "computeObjectOffsetsFoldFunction(record case branch)")
-
     if maxChildAlign == szUnknownSize:
       result.align  = szUnknownSize
       result.offset = szUnknownSize
     else:
       # the union neds to be aligned first, before the offsets can be assigned
       let kindUnionOffset = align(kindOffset, maxChildAlign)
-
       var maxChildOffset: BiggestInt = 0
       for i in 1 ..< sonsLen(n):
         let (offset, align) = computeObjectOffsetsFoldFunction(conf, n.sons[i].lastSon, kindUnionOffset)
         maxChildOffset = max(maxChildOffset, offset)
-
       result.align = max(kindAlign, maxChildAlign)
       result.offset = maxChildOffset
-
-
   of nkRecList:
     result.align = 1 # maximum of all member alignments
     var offset = initialOffset
-
     for i, child in n.sons:
       let (new_offset, align) = computeObjectOffsetsFoldFunction(conf, child, offset)
-
       if new_offset == szIllegalRecursion:
         result.offset = szIllegalRecursion
         result.align = szIllegalRecursion
         return
-
       elif new_offset == szUnknownSize or offset == szUnknownSize:
         # if anything is unknown, the rest becomes unknown as well
         offset = szUnknownSize
         result.align = szUnknownSize
-
       else:
         offset = new_offset
         result.align = max(result.align, align)
-
     # final alignment
     if offset == szUnknownSize:
       result.offset = szUnknownSize
     else:
       result.offset = align(offset, result.align)
-
   of nkSym:
     var size = szUnknownSize
     var align = szUnknownSize
-
     if n.sym.bitsize == 0: # 0 represents bitsize not set
       computeSizeAlign(conf, n.sym.typ)
       size = n.sym.typ.size.int
@@ -155,7 +142,6 @@ proc computePackedObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, initialOf
     let kindOffset = computePackedObjectOffsetsFoldFunction(conf, n.sons[0], initialOffset, debug)
     # the union neds to be aligned first, before the offsets can be assigned
     let kindUnionOffset = kindOffset
-
     var maxChildOffset: BiggestInt = kindUnionOffset
     for i in 1 ..< sonsLen(n):
       let offset = computePackedObjectOffsetsFoldFunction(conf, n.sons[i].lastSon, kindUnionOffset, debug)
@@ -168,9 +154,17 @@ proc computePackedObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, initialOf
       if result == szIllegalRecursion:
         break
   of nkSym:
-    computeSizeAlign(conf, n.sym.typ)
-    n.sym.offset = initialOffset.int
-    result = n.sym.offset + n.sym.typ.size
+    var size = szUnknownSize
+    if n.sym.bitsize == 0:
+      computeSizeAlign(conf, n.sym.typ)
+      size = n.sym.typ.size.int
+
+    if initialOffset == szUnknownSize or size == szUnknownSize:
+      n.sym.offset = szUnknownSize
+      result = szUnknownSize
+    else:
+      n.sym.offset = int(initialOffset)
+      result = initialOffset + n.sym.typ.size
   else:
     result = szUnknownSize
 
@@ -324,7 +318,6 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
     var headerAlign: int16
     if typ.sons[0] != nil:
       # compute header size
-
       if conf.cmd == cmdCompileToCpp:
         # if the target is C++ the members of this type are written
         # into the padding byets at the end of the parent type. At the
@@ -364,7 +357,6 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
       typ.size = szUnknownSize
       typ.align = szUnknownSize
       return
-
     # header size is already in size from computeObjectOffsetsFoldFunction
     # maxAlign is probably not changed at all from headerAlign
     if tfPacked in typ.flags:
@@ -373,7 +365,6 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
     else:
       typ.align = int16(max(align, headerAlign))
       typ.size = align(offset, typ.align)
-
   of tyInferred:
     if typ.len > 1:
       computeSizeAlign(conf, typ.lastSon)