c style alignment of variants within records.
authorPeter B. Kessler <peter@ucbvax.Berkeley.EDU>
Wed, 20 Oct 1982 12:42:22 +0000 (04:42 -0800)
committerPeter B. Kessler <peter@ucbvax.Berkeley.EDU>
Wed, 20 Oct 1982 12:42:22 +0000 (04:42 -0800)
SCCS-vsn: usr.bin/pascal/src/0.h 1.16
SCCS-vsn: usr.bin/pascal/src/rec.c 1.5
SCCS-vsn: usr.bin/pascal/src/var.c 1.13
SCCS-vsn: usr.bin/pascal/src/nl.c 1.9

usr/src/usr.bin/pascal/src/0.h
usr/src/usr.bin/pascal/src/nl.c
usr/src/usr.bin/pascal/src/rec.c
usr/src/usr.bin/pascal/src/var.c

index 732033d..6c7e7fd 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1979 Regents of the University of California */
 
 /* Copyright (c) 1979 Regents of the University of California */
 
-/* static char sccsid[] = "@(#)0.h 1.15 %G%"; */
+/* static char sccsid[] = "@(#)0.h 1.16 %G%"; */
 
 #define DEBUG
 #define CONSETS
 
 #define DEBUG
 #define CONSETS
@@ -249,15 +249,16 @@ struct    nl {
 #      endif PTREE
 };
 
 #      endif PTREE
 };
 
-#define class info[0]
-#define nl_flags info[1]
-#define nl_block info[1]
-#define extra_flags info[2]
+#define class          info[0]
+#define nl_flags       info[1]
+#define nl_block       info[1]
+#define extra_flags    info[2]
+#define align_info     info[3]
 
 
-#define range nl_un.un_range
-#define value nl_un.un_value
-#define ptr nl_un.un_ptr
-#define real nl_un.un_real
+#define range  nl_un.un_range
+#define value  nl_un.un_value
+#define ptr    nl_un.un_ptr
+#define real   nl_un.un_real
 
 extern struct nl *nlp, *disptab[077+1], *Fp;
 extern struct nl nl[INL];
 
 extern struct nl *nlp, *disptab[077+1], *Fp;
 extern struct nl nl[INL];
@@ -314,10 +315,23 @@ extern struct nl nl[INL];
 #define NL_GOLINE 3
 #define NL_FORV 1
 
 #define NL_GOLINE 3
 #define NL_FORV 1
 
-#define        NL_FLDSZ 1
-#define        NL_VARNT 2
-#define        NL_VTOREC 2
-#define        NL_TAG  3
+    /*
+     * nlp -> nl_un.un_ptr[] subscripts for records
+     * NL_FIELDLIST    the chain of fixed fields of a record, in order.
+     *                 the fields are also chained through ptr[NL_FIELDLIST].
+     *                 this does not include the tag, or fields of variants.
+     * NL_VARNT        pointer to the variants of a record,
+     *                 these are then chained through the .chain field.
+     * NL_VTOREC       pointer from a VARNT to the RECORD that is the variant.
+     * NL_TAG          pointer from a RECORD to the tagfield
+     *                 if there are any variants.
+     * align_info      the alignment of a RECORD is in info[3].
+     */
+#define        NL_FIELDLIST    1
+#define        NL_VARNT        2
+#define        NL_VTOREC       2
+#define        NL_TAG          3
+/* and align_info is info[3].  #defined above */
 
 #define        NL_ELABEL 4     /* SCAL - ptr to definition of enums */
 
 
 #define        NL_ELABEL 4     /* SCAL - ptr to definition of enums */
 
@@ -732,10 +746,8 @@ struct nl  *hdefnl();
 struct nl      *defnl();
 struct nl      *enter();
 struct nl      *nlcopy();
 struct nl      *defnl();
 struct nl      *enter();
 struct nl      *nlcopy();
-struct nl      *tyrecl();
+struct nl      *tyrec();
 struct nl      *tyary();
 struct nl      *tyary();
-struct nl      *fields();
-struct nl      *variants();
 struct nl      *deffld();
 struct nl      *defvnt();
 struct nl      *tyrec1();
 struct nl      *deffld();
 struct nl      *defvnt();
 struct nl      *tyrec1();
index 9e42d6c..1a52f95 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1979 Regents of the University of California */
 
 /* Copyright (c) 1979 Regents of the University of California */
 
-static char sccsid[] = "@(#)nl.c 1.8 %G%";
+static char sccsid[] = "@(#)nl.c 1.9 %G%";
 
 #include "whoami.h"
 #include "0.h"
 
 #include "whoami.h"
 #include "0.h"
@@ -583,7 +583,7 @@ con:
                                printf("\t%ld..%ld", p->range[0], p->range[1]);
                                break;
                        case RECORD:
                                printf("\t%ld..%ld", p->range[0], p->range[1]);
                                break;
                        case RECORD:
-                               printf("\t%d(%d)", v, p->value[NL_FLDSZ]);
+                               printf("\t%d", v);
                                break;
                        case FIELD:
                                printf("\t%d", v);
                                break;
                        case FIELD:
                                printf("\t%d", v);
@@ -615,13 +615,37 @@ casedef:
                        printf("\t[%d]", nloff(p->chain));
                switch (p->class) {
                        case RECORD:
                        printf("\t[%d]", nloff(p->chain));
                switch (p->class) {
                        case RECORD:
-                               if (p->ptr[NL_VARNT])
-                                       printf("\tVARNT=[%d]", nloff(p->ptr[NL_VARNT]));
-                               if (p->ptr[NL_TAG])
-                                       printf(" TAG=[%d]", nloff(p->ptr[NL_TAG]));
+                               printf("\tALIGN=%d", p->align_info);
+                               if (p->ptr[NL_FIELDLIST]) {
+                                   printf(" FLIST=[%d]",
+                                       nloff(p->ptr[NL_FIELDLIST]));
+                               } else {
+                                   printf(" FLIST=[]");
+                               }
+                               if (p->ptr[NL_TAG]) {
+                                   printf(" TAG=[%d]",
+                                       nloff(p->ptr[NL_TAG]));
+                               } else {
+                                   printf(" TAG=[]");
+                               }
+                               if (p->ptr[NL_VARNT]) {
+                                   printf(" VARNT=[%d]",
+                                       nloff(p->ptr[NL_VARNT]));
+                               } else {
+                                   printf(" VARNT=[]");
+                               }
+                               break;
+                       case FIELD:
+                               if (p->ptr[NL_FIELDLIST]) {
+                                   printf("\tFLIST=[%d]",
+                                       nloff(p->ptr[NL_FIELDLIST]));
+                               } else {
+                                   printf("\tFLIST=[]");
+                               }
                                break;
                        case VARNT:
                                break;
                        case VARNT:
-                               printf("\tVTOREC=[%d]", nloff(p->ptr[NL_VTOREC]));
+                               printf("\tVTOREC=[%d]",
+                                   nloff(p->ptr[NL_VTOREC]));
                                break;
                }
 #              ifdef PC
                                break;
                }
 #              ifdef PC
index 87dd99b..d28aee0 100644 (file)
@@ -1,21 +1,33 @@
 /* Copyright (c) 1979 Regents of the University of California */
 
 /* Copyright (c) 1979 Regents of the University of California */
 
-static char sccsid[] = "@(#)rec.c 1.4 %G%";
+static char sccsid[] = "@(#)rec.c 1.5 %G%";
 
 #include "whoami.h"
 #include "0.h"
 #include "tree.h"
 #include "opcode.h"
 
 #include "whoami.h"
 #include "0.h"
 #include "tree.h"
 #include "opcode.h"
+#include "align.h"
+
+    /*
+     * set this to TRUE with adb to turn on record alignment/offset debugging.
+     */
+bool   debug_records = FALSE;
+#define        DEBUG_RECORDS(x)        if (debug_records) { x ; } else
 
 /*
  * Build a record namelist entry.
  * Some of the processing here is somewhat involved.
  * The basic structure we are building is as follows.
  *
 
 /*
  * Build a record namelist entry.
  * Some of the processing here is somewhat involved.
  * The basic structure we are building is as follows.
  *
- * Each record has a main RECORD entry, with an attached
- * chain of fields as ->chain;  these include all the fields in all
- * the variants of this record.
+ * Each record has a main RECORD entry,
+ * with an attached chain of fields as ->chain;
+ * these include all the fields in all the variants of this record.
+ * Fields are cons'ed to the front of the ->chain list as they are discovered.
+ * This is for reclook(), but not for sizing and aligning offsets.
  *
  *
+ * If there are variants to the record, NL_TAG points to the field which
+ * is the tag.  If its name is NIL, the tag field is unnamed, and is not
+ * allocated any space in the record.
  * Attached to NL_VARNT is a chain of VARNT structures
  * describing each of the variants.  These are further linked
  * through ->chain.  Each VARNT has, in ->range[0] the value of
  * Attached to NL_VARNT is a chain of VARNT structures
  * describing each of the variants.  These are further linked
  * through ->chain.  Each VARNT has, in ->range[0] the value of
@@ -23,18 +35,20 @@ static char sccsid[] = "@(#)rec.c 1.4 %G%";
  * the subrecord through NL_VTOREC.  These pointers are not unique,
  * more than one VARNT may reference the same RECORD.
  *
  * the subrecord through NL_VTOREC.  These pointers are not unique,
  * more than one VARNT may reference the same RECORD.
  *
- * The involved processing here is in computing the NL_OFFS entry
- * by maxing over the variants.  This works as follows.
- *
- * Each RECORD has two size counters.  NL_OFFS is the maximum size
- * so far of any variant of this record;  NL_FLDSZ gives the size
- * of just the FIELDs to this point as a base for further variants.
- *
- * As we process each variant record, we start its size with the
- * NL_FLDSZ we have so far.  After processing it, if its NL_OFFS
- * is the largest so far, we update the NL_OFFS of this subrecord.
- * This will eventually propagate back and update the NL_OFFS of the
- * entire record.
+ * On the first pass, we traverse the parse tree and construct the namelist
+ * entries.  This pass fills in the alignment of each record (including
+ * subrecords (the alignment of a record is the maximum of the alignments
+ * of any of its fields).
+ * A second pass over the namelist entries fills in the offsets of each field
+ * based on the alignments required.  This second pass uses the NL_FIELDLIST
+ * chaining of fields, and the NL_TAG pointer and the NL_VARNT pointer to get
+ * to fields in the order in which they were declared.
+ * This second pass can not be folded into the first pass,
+ * as the starting offset of all variants is the same,
+ * so we must see all the variants (and especially must know their alignments)
+ * before assigning offsets.  With the alignments calculated (by the first
+ * pass) this can be done in one top down pass, max'ing over the alignment of
+ * variants before assigning offsets to any of them.
  */
 
 /*
  */
 
 /*
@@ -42,71 +56,102 @@ static char sccsid[] = "@(#)rec.c 1.4 %G%";
  */
 struct nl *P0;
 
  */
 struct nl *P0;
 
+struct nl *
 tyrec(r, off)
        int *r, off;
 {
 tyrec(r, off)
        int *r, off;
 {
+       struct nl       *recp;
 
 
-           return tyrec1(r, off, 1);
+       DEBUG_RECORDS(fprintf(stderr,"[tyrec] off=%d\n", off));
+           /*
+            *  build namelist structure for the outermost record type.
+            *  then calculate offsets (starting at 0) of the fields
+            *  in this record and its variant subrecords.
+            */
+       recp = tyrec1(r, TRUE);
+       rec_offsets(recp, 0);
+       return recp;
 }
 
 /*
  * Define a record namelist entry.
 }
 
 /*
  * Define a record namelist entry.
- * R is the tree for the record to be built.
- * Off is the offset for the first item in this (sub)record.
+ * r is the tree for the record to be built.
+ * first is a boolean indicating whether this is an outermost record,
+ * for name lookups.
+ * p is the record we define here.
+ * P0was is a local which stacks the enclosing value of P0 in the stack frame,
+ * since tyrec1() is recursive.
  */
 struct nl *
  */
 struct nl *
-tyrec1(r, off, first)
+tyrec1(r, first)
        register int *r;
        register int *r;
-       int off;
-       char first;
+       bool first;
 {
        register struct nl *p, *P0was;
 
 {
        register struct nl *p, *P0was;
 
+       DEBUG_RECORDS(fprintf(stderr,"[tyrec1] first=%d\n", first));
        p = defnl(0, RECORD, 0, 0);
        P0was = P0;
        if (first)
                P0 = p;
 #ifndef PI0
        p = defnl(0, RECORD, 0, 0);
        P0was = P0;
        if (first)
                P0 = p;
 #ifndef PI0
-       p->value[NL_FLDSZ] = p->value[NL_OFFS] = off;
+       p->align_info = A_MIN;
 #endif
        if (r != NIL) {
                fields(p, r[2]);
                variants(p, r[3]);
        }
 #endif
        if (r != NIL) {
                fields(p, r[2]);
                variants(p, r[3]);
        }
-           /*
-            *  round the lengths of records up to their alignments
-            */
-       p->value[NL_OFFS] = roundup(p->value[NL_OFFS], (long)align(p));
        P0 = P0was;
        return (p);
 }
 
 /*
  * Define the fixed part fields for p.
        P0 = P0was;
        return (p);
 }
 
 /*
  * Define the fixed part fields for p.
+ * hang them, in order, from the record entry, through ->ptr[NL_FIELDLIST].
+ * the fieldlist is a tconc structure, and is manipulated 
+ * just like newlist(), addlist(), fixlist() in the parser.
  */
  */
-struct nl *
 fields(p, r)
        struct nl *p;
        int *r;
 {
 fields(p, r)
        struct nl *p;
        int *r;
 {
-       register int *fp, *tp, *ip;
-       struct nl *jp;
+       register int    *fp, *tp, *ip;
+       struct nl       *jp;
+       struct nl       *fieldnlp;
 
 
+       DEBUG_RECORDS(fprintf(stderr,"[fields]\n"));
        for (fp = r; fp != NIL; fp = fp[2]) {
                tp = fp[1];
                if (tp == NIL)
                        continue;
                jp = gtype(tp[3]);
                line = tp[1];
        for (fp = r; fp != NIL; fp = fp[2]) {
                tp = fp[1];
                if (tp == NIL)
                        continue;
                jp = gtype(tp[3]);
                line = tp[1];
-               for (ip = tp[2]; ip != NIL; ip = ip[2])
-                       deffld(p, ip[1], jp);
+               for (ip = tp[2]; ip != NIL; ip = ip[2]) {
+                   fieldnlp = deffld(p, ip[1], jp);
+                   if ( p->ptr[NL_FIELDLIST] == NIL ) {
+                           /* newlist */
+                       p->ptr[NL_FIELDLIST] = fieldnlp;
+                       fieldnlp->ptr[NL_FIELDLIST] = fieldnlp;
+                   } else {
+                           /* addlist */
+                       fieldnlp->ptr[NL_FIELDLIST] =
+                               p->ptr[NL_FIELDLIST]->ptr[NL_FIELDLIST];
+                       p->ptr[NL_FIELDLIST]->ptr[NL_FIELDLIST] = fieldnlp;
+                       p->ptr[NL_FIELDLIST] = fieldnlp;
+                   }
+               }
+       }
+       if ( p->ptr[NL_FIELDLIST] != NIL ) {
+               /* fixlist */
+           fieldnlp = p->ptr[NL_FIELDLIST]->ptr[NL_FIELDLIST];
+           p->ptr[NL_FIELDLIST]->ptr[NL_FIELDLIST] = NIL;
+           p->ptr[NL_FIELDLIST] = fieldnlp;
        }
 }
 
 /*
  * Define the variants for RECORD p.
  */
        }
 }
 
 /*
  * Define the variants for RECORD p.
  */
-struct nl *
 variants(p, r)
        struct nl *p;
        register int *r;
 variants(p, r)
        struct nl *p;
        register int *r;
@@ -115,6 +160,7 @@ variants(p, r)
        int *vr;
        struct nl *ct;
 
        int *vr;
        struct nl *ct;
 
+       DEBUG_RECORDS(fprintf(stderr,"[variants]\n"));
        if (r == NIL)
                return;
        ct = gtype(r[3]);
        if (r == NIL)
                return;
        ct = gtype(r[3]);
@@ -132,10 +178,15 @@ variants(p, r)
                v = vc[1];
                if (v == NIL)
                        continue;
                v = vc[1];
                if (v == NIL)
                        continue;
-               vr = tyrec1(v[3], p->value[NL_FLDSZ], 0);
+               vr = tyrec1(v[3], FALSE);
 #ifndef PI0
 #ifndef PI0
-               if (vr->value[NL_OFFS] > p->value[NL_OFFS])
-                       p->value[NL_OFFS] = vr->value[NL_OFFS];
+               DEBUG_RECORDS(
+                   fprintf(stderr,
+                       "[variants] p->align_info %d vr->align_info %d\n",
+                       p->align_info, vr->align_info));
+               if (vr->align_info > p->align_info) {
+                   p->align_info = vr->align_info;
+               }
 #endif
                line = v[1];
                for (v = v[2]; v != NIL; v = v[2])
 #endif
                line = v[1];
                for (v = v[2]; v != NIL; v = v[2])
@@ -155,44 +206,41 @@ deffld(p, s, t)
 {
        register struct nl *fp;
 
 {
        register struct nl *fp;
 
+       DEBUG_RECORDS(fprintf(stderr,"[deffld] s=<%s>\n", s));
        if (reclook(P0, s) != NIL) {
 #ifndef PI1
                error("%s is a duplicate field name in this record", s);
 #endif
                s = NIL;
        }
        if (reclook(P0, s) != NIL) {
 #ifndef PI1
                error("%s is a duplicate field name in this record", s);
 #endif
                s = NIL;
        }
-#ifndef PI0
            /*
            /*
-            * it used to be easy to keep track of offsets of fields
-            * and total sizes of records.
-            * but now, the offset of the field is aligned
-            * so only it knows it's offset, and calculating 
-            * the total size of the record is based on it,
-            * rather than just the width of the field.
+            *  enter the field with its type
             */
             */
-       fp = enter(defnl(s, FIELD, t, (int)roundup(p->value[NL_OFFS],
-                       (long)align(t))));
-#else
        fp = enter(defnl(s, FIELD, t, 0));
        fp = enter(defnl(s, FIELD, t, 0));
-#endif
+           /*
+            *  if no name, then this is an unnamed tag,
+            *  so don't link it into reclook()'s chain.
+            */
        if (s != NIL) {
                fp->chain = P0->chain;
                P0->chain = fp;
 #ifndef PI0
                    /*
        if (s != NIL) {
                fp->chain = P0->chain;
                P0->chain = fp;
 #ifndef PI0
                    /*
-                    * and the size of the record is incremented.
+                    * and the alignment is propagated back.
                     */
                     */
-               p -> value[ NL_OFFS ] = fp -> value[ NL_OFFS ] + width( t );
-               p -> value[ NL_FLDSZ ] = p -> value[ NL_OFFS ];
+               fp->align_info = align(t);
+               DEBUG_RECORDS(
+                   fprintf(stderr,
+                       "[deffld] fp->align_info %d p->align_info %d \n",
+                       fp->align_info, p->align_info));
+               if (fp->align_info > p->align_info) {
+                   p->align_info = fp->align_info;
+               }
 #endif
                if (t != NIL) {
                        P0->nl_flags |= t->nl_flags & NFILES;
                        p->nl_flags |= t->nl_flags & NFILES;
                }
 #endif
                if (t != NIL) {
                        P0->nl_flags |= t->nl_flags & NFILES;
                        p->nl_flags |= t->nl_flags & NFILES;
                }
-#              ifdef PC
-                   stabfield( s , p2type( t ) , fp -> value[ NL_OFFS ]
-                               , lwidth( t ) );
-#              endif PC
        }
        return (fp);
 }
        }
        return (fp);
 }
@@ -221,7 +269,7 @@ defvnt(p, t, vr, ct)
 #ifndef PI1
        if (ct != NIL)
                uniqv(p);
 #ifndef PI1
        if (ct != NIL)
                uniqv(p);
-#endif
+#endif not PI1
        av->chain = p->ptr[NL_VARNT];
        p->ptr[NL_VARNT] = av;
        av->ptr[NL_VTOREC] = vr;
        av->chain = p->ptr[NL_VARNT];
        p->ptr[NL_VARNT] = av;
        av->ptr[NL_VTOREC] = vr;
@@ -265,3 +313,124 @@ reclook(p, s)
                        return (p);
        return (NIL);
 }
                        return (p);
        return (NIL);
 }
+
+    /*
+     * descend namelist entry for a record and assign offsets.
+     * fields go at the next higher offset that suits their alignment.
+     * all variants of a record start at the same offset, which is suitable
+     * for the alignment of their worst aligned field.  thus the size of a 
+     * record is independent of whether or not it is a variant
+     * (a desirable property).
+     * records come to us in the namelist, where they have been annotated
+     * with the maximum alignment their fields require.
+     * the starting offset is passed to us, and is passed recursively for
+     * variant records within records.
+     * the final maximum size of each record is recorded in the namelist
+     * in the value[NL_OFFS] field of the namelist for the record.
+     *
+     * this is supposed to match the offsets used by the c compiler
+     * so people can share records between modules in both languages.
+     */
+rec_offsets(recp, offset)
+    struct nl  *recp;          /* pointer to the namelist record */
+    long       offset;         /* starting offset for this record/field */
+{
+    long       origin;         /* offset of next field */
+    struct nl  *fieldnlp;      /* the current field */
+    struct nl  *varntnlp;      /* the current variant */
+    struct nl  *vrecnlp;       /* record for the current variant */
+    long       alignment;      /* maximum alignment for any variant */
+
+    if ( recp == NIL ) {
+       return;
+    }
+    origin = roundup(offset,recp->align_info);
+    if (origin != offset) {
+       fprintf(stderr,
+               "[rec_offsets] offset=%d recp->align_info=%d origin=%d\n",
+               offset, recp->align_info, origin);
+       panic("rec_offsets");
+    }
+    DEBUG_RECORDS(
+       fprintf(stderr,
+           "[rec_offsets] offset %d recp->align %d origin %d\n",
+           offset, recp->align_info, origin));
+       /*
+        *      fixed fields are forward linked though ->ptr[NL_FIELDLIST]
+        *      give them all suitable offsets.
+        */
+    for (   fieldnlp = recp->ptr[NL_FIELDLIST];
+           fieldnlp != NIL;
+           fieldnlp = fieldnlp->ptr[NL_FIELDLIST] ) {
+       origin = roundup(origin,align(fieldnlp->type));
+       fieldnlp->value[NL_OFFS] = origin;
+       DEBUG_RECORDS(
+           fprintf(stderr,"[rec_offsets] symbol %s origin %d\n",
+                   fieldnlp->symbol, origin));
+       origin += lwidth(fieldnlp->type);
+    }
+       /*
+        *      this is the extent of the record, so far
+        */
+    recp->value[NL_OFFS] = origin;
+       /*
+        *      if we have a tag field, we have variants to deal with
+        */
+    if ( recp->ptr[NL_TAG] ) {
+           /*
+            *  if tag field is unnamed, then don't allocate space for it.
+            */
+       fieldnlp = recp->ptr[NL_TAG];
+       if ( fieldnlp->symbol != NIL ) {
+           origin = roundup(origin,align(fieldnlp->type));
+           fieldnlp->value[NL_OFFS] = origin;
+           DEBUG_RECORDS(fprintf(stderr,"[rec_offsets] tag %s origin\n",
+                                   fieldnlp->symbol, origin));
+           origin += lwidth(fieldnlp->type);
+       }
+           /*
+            *  find maximum alignment of records of variants
+            */
+       for (   varntnlp = recp->ptr[NL_VARNT]; 
+               varntnlp != NIL;
+               varntnlp = varntnlp -> chain ) {
+           vrecnlp = varntnlp->ptr[NL_VTOREC];
+           DEBUG_RECORDS(
+               fprintf(stderr,
+                       "[rec_offsets] maxing variant %d align_info %d\n",
+                       varntnlp->value[0], vrecnlp->align_info));
+           origin = roundup(origin,vrecnlp->align_info);
+       }
+       DEBUG_RECORDS(
+           fprintf(stderr, "[rec_offsets] origin of variants %d\n", origin));
+           /*
+            *  assign offsets to fields of records of the variants
+            *  keep maximum length of the current record.
+            */
+       for (   varntnlp = recp->ptr[NL_VARNT]; 
+               varntnlp != NIL;
+               varntnlp = varntnlp -> chain ) {
+           vrecnlp = varntnlp->ptr[NL_VTOREC];
+               /*
+                *      assign offsets to fields of the variant.
+                *      recursive call on rec_offsets.
+                */
+           rec_offsets(vrecnlp,origin);
+               /*
+                *      extent of the record is the
+                *      maximum extent of all variants
+                */
+           if ( vrecnlp->value[NL_OFFS] > recp->value[NL_OFFS] ) {
+               recp->value[NL_OFFS] = vrecnlp->value[NL_OFFS];
+           }
+       }
+    }
+       /*
+        *      roundup the size of the record to its alignment
+        */
+    DEBUG_RECORDS(
+       fprintf(stderr,
+               "[rec_offsets] recp->value[NL_OFFS] %d ->align_info %d\n",
+               recp->value[NL_OFFS], recp->align_info));
+    recp->value[NL_OFFS] = roundup(recp->value[NL_OFFS],recp->align_info);
+}
index 7e045b7..1f26486 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1979 Regents of the University of California */
 
 /* Copyright (c) 1979 Regents of the University of California */
 
-static char sccsid[] = "@(#)var.c 1.12 %G%";
+static char sccsid[] = "@(#)var.c 1.13 %G%";
 
 #include "whoami.h"
 #include "0.h"
 
 #include "whoami.h"
 #include "0.h"
@@ -329,26 +329,10 @@ alignit:
                    return A_CHAR;
            case RECORD:
                        /*
                    return A_CHAR;
            case RECORD:
                        /*
-                        * follow chain through all fields in record,
-                        * taking max of alignments of types of fields.
-                        * short circuit out if i reach the maximum alignment.
-                        * this is pretty likely, as A_MAX is only 4.
+                        * the alignment of a record is in its align_info field
+                        * why don't we use this for the rest of the namelist?
                         */
                         */
-                   {
-                       register long recalign;
-                       register long fieldalign;
-                       
-                       recalign = A_MIN;
-                       p = p -> chain;
-                       while ( ( p != NIL ) && ( recalign < A_MAX ) ) {
-                           fieldalign = align( p -> type );
-                           if ( fieldalign > recalign ) {
-                               recalign = fieldalign;
-                           }
-                           p = p -> chain;
-                       }
-                       return recalign;
-                   }
+                   return p -> align_info;
            default:
                    panic( "align" );
        }
            default:
                    panic( "align" );
        }