Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

init.c File Reference

#include "c.h"

Include dependency graph for init.c:

Include dependency graph

Go to the source code of this file.

Functions

void defpointer (Symbol p)
int genconst (Tree e, int def)
int initarray (int len, Type ty, int lev)
int initchar (int len, Type ty)
void initend (int lev, char follow[])
int initfields (Field p, Field q)
Type initializer (Type ty, int lev)
int initstruct (int len, Type ty, int lev)
Tree initvalue (Type ty)
void swtoseg (int seg)

Variables

int curseg


Function Documentation

void defpointer Symbol  p  ) 
 

Definition at line 7 of file init.c.

References interface::defaddress, interface::defconst, IR, p, symbol::ref, type::size, Symbol, Value, and voidptype.

Referenced by bbcall(), bbfunc(), and bbvars().

00007                           {
00008     if (p) {
00009         (*IR->defaddress)(p);
00010         p->ref++;
00011     } else {
00012         static Value v;
00013         (*IR->defconst)(P, voidptype->size, v);
00014     }
00015 }

int genconst Tree  e,
int  def
[static]
 

Definition at line 18 of file init.c.

References ADDRG, assert, CNST, consttree(), CVF, CVI, CVP, cvtconst(), CVU, interface::defaddress, interface::defconst, e, error(), generic, inttype, IR, isarith, isarray, tree::kids, type::op, tree::op, P, RIGHT, type::size, tree::sym, Tree, tree::type, tree::u, and tree::v.

Referenced by initializer().

00018                                      {
00019     for (;;)
00020         switch (generic(e->op)) {
00021         case ADDRG:
00022             if (def)
00023                 (*IR->defaddress)(e->u.sym);
00024             return e->type->size;
00025         case CNST:
00026             if (e->op == CNST+P && isarray(e->type)) {
00027                 e = cvtconst(e);
00028                 continue;
00029             }
00030             if (def)
00031                 (*IR->defconst)(e->type->op, e->type->size, e->u.v);
00032             return e->type->size;
00033         case RIGHT:
00034             assert(e->kids[0] || e->kids[1]);
00035             if (e->kids[1] && e->kids[0])
00036                 error("initializer must be constant\n");
00037             e = e->kids[1] ? e->kids[1] : e->kids[0];
00038             continue;
00039         case CVP:
00040             if (isarith(e->type))
00041                 error("cast from `%t' to `%t' is illegal in constant expressions\n",
00042                     e->kids[0]->type, e->type);
00043             /* fall thru */
00044         case CVI: case CVU: case CVF:
00045             e = e->kids[0];
00046             continue;
00047         default:
00048             error("initializer must be constant\n");
00049             if (def)
00050                 genconst(consttree(0, inttype), def);
00051             return inttype->size;
00052         }
00053 }

Here is the call graph for this function:

int initarray int  len,
Type  ty,
int  lev
[static]
 

Definition at line 78 of file init.c.

References gettok(), initializer(), n, type::size, t, and Type.

Referenced by initializer().

00078                                                 {
00079     int n = 0;
00080 
00081     do {
00082         initializer(ty, lev);
00083         n += ty->size;
00084         if (len > 0 && n >= len || t != ',')
00085             break;
00086         t = gettok();
00087     } while (t != '}');
00088     return n;
00089 }

Here is the call graph for this function:

int initchar int  len,
Type  ty
[static]
 

Definition at line 92 of file init.c.

References interface::defstring, gettok(), value::i, initvalue(), inttype, IR, n, s, type::size, t, Type, tree::u, and tree::v.

Referenced by initializer().

00092                                       {
00093     int n = 0;
00094     char buf[16], *s = buf;
00095 
00096     do {
00097         *s++ = initvalue(ty)->u.v.i;
00098         if (++n%inttype->size == 0) {
00099             (*IR->defstring)(inttype->size, buf);
00100             s = buf;
00101         }
00102         if (len > 0 && n >= len || t != ',')
00103             break;
00104         t = gettok();
00105     } while (t != '}');
00106     if (s > buf)
00107         (*IR->defstring)(s - buf, buf);
00108     return n;
00109 }

Here is the call graph for this function:

void initend int  lev,
char  follow[]
[static]
 

Definition at line 112 of file init.c.

References gettok(), t, and test().

Referenced by initializer().

00112                                             {
00113     if (lev == 0 && t == ',')
00114         t = gettok();
00115     test('}', follow);
00116 }

Here is the call graph for this function:

int initfields Field  p,
Field  q
[static]
 

Definition at line 119 of file init.c.

References bits, interface::defconst, Field, fieldleft, fieldmask, fieldright, fieldsize, gettok(), value::i, i, initvalue(), inttype, IR, field::link, interface::little_endian, n, p, type::size, t, field::type, value::u, tree::u, unsignedchar, unsignedtype, v, tree::v, Value, and warning().

Referenced by initstruct().

00119                                         {
00120     unsigned int bits = 0;
00121     int i, n = 0;
00122 
00123     do {
00124         i = initvalue(inttype)->u.v.i;
00125         if (fieldsize(p) < 8*p->type->size) {
00126             if (p->type == inttype &&
00127                (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))
00128             ||  p->type == unsignedtype && (i&~fieldmask(p)) !=  0)
00129                 warning("initializer exceeds bit-field width\n");
00130             i &= fieldmask(p);
00131         }
00132         bits |= i<<fieldright(p);
00133         if (IR->little_endian) {
00134             if (fieldsize(p) + fieldright(p) > n)
00135                 n = fieldsize(p) + fieldright(p);
00136         } else {
00137             if (fieldsize(p) + fieldleft(p) > n)
00138                 n = fieldsize(p) + fieldleft(p);
00139         }
00140         if (p->link == q)
00141             break;
00142         p = p->link;
00143     } while (t == ',' && (t = gettok()) != 0);
00144     n = (n + 7)/8;
00145     for (i = 0; i < n; i++) {
00146         Value v;
00147         if (IR->little_endian) {
00148             v.u = (unsigned char)bits;
00149             bits >>= 8;
00150         } else {    /* a big endian */
00151             v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1)));
00152             bits <<= 8;
00153         }
00154         (*IR->defconst)(U, unsignedchar->size, v);
00155     }
00156     return n;
00157 }

Here is the call graph for this function:

Type initializer Type  ty,
int  lev
 

Definition at line 196 of file init.c.

References array(), assign(), symbol::c, cast(), chartype, deallocate(), interface::defconst, interface::defstring, e, error(), expr1(), symbol::flist, genconst(), gettok(), i, initarray(), initchar(), initend(), initstruct(), IR, isarray, ischar, isscalar, isstruct, isunion, n, needconst, type::op, value::p, pointer(), s, symbol::s, SCON, type::size, skipto(), interface::space, STMT, type::sym, t, test(), Tree, tsym, symbol::type, type::type, field::type, tree::type, Type, value::u, symbol::u, type::u, unqual, v, symbol::v, Value, and widechar.

Referenced by dclglobal(), initarray(), initglobal(), and initstruct().

00196                                    {
00197     int n = 0;
00198     Tree e;
00199     Type aty = NULL;
00200     static char follow[] = { IF, CHAR, STATIC, 0 };
00201 
00202     ty = unqual(ty);
00203     if (isscalar(ty)) {
00204         needconst++;
00205         if (t == '{') {
00206             t = gettok();
00207             e = expr1(0);
00208             initend(lev, follow);
00209         } else
00210             e = expr1(0);
00211         e = pointer(e);
00212         if ((aty = assign(ty, e)) != NULL)
00213             e = cast(e, aty);
00214         else
00215             error("invalid initialization type; found `%t' expected `%t'\n",
00216                 e->type, ty);
00217         n = genconst(e, 1);
00218         deallocate(STMT);
00219         needconst--;
00220     }
00221     if ((isunion(ty) || isstruct(ty)) && ty->size == 0) {
00222         static char follow[] = { CHAR, STATIC, 0 };
00223         error("cannot initialize undefined `%t'\n", ty);
00224         skipto(';', follow);
00225         return ty;
00226     } else if (isunion(ty)) {
00227         if (t == '{') {
00228             t = gettok();
00229             n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
00230             initend(lev, follow);
00231         } else {
00232             if (lev == 0)
00233                 error("missing { in initialization of `%t'\n", ty);
00234             n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
00235         }
00236     } else if (isstruct(ty)) {
00237         if (t == '{') {
00238             t = gettok();
00239             n = initstruct(0, ty, lev + 1);
00240             test('}', follow);
00241         } else if (lev > 0)
00242             n = initstruct(ty->size, ty, lev + 1);
00243         else {
00244             error("missing { in initialization of `%t'\n", ty);
00245             n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
00246         }
00247     }
00248     if (isarray(ty))
00249         aty = unqual(ty->type);
00250     if (isarray(ty) && ischar(aty)) {
00251         if (t == SCON) {
00252             if (ty->size > 0 && ty->size == tsym->type->size - 1)
00253                 tsym->type = array(chartype, ty->size, 0);
00254             n = tsym->type->size;
00255             (*IR->defstring)(tsym->type->size, tsym->u.c.v.p);
00256             t = gettok();
00257         } else if (t == '{') {
00258             t = gettok();
00259             if (t == SCON) {
00260                 ty = initializer(ty, lev + 1);
00261                 initend(lev, follow);
00262                 return ty;
00263             }
00264             n = initchar(0, aty);
00265             test('}', follow);
00266         } else if (lev > 0 && ty->size > 0)
00267             n = initchar(ty->size, aty);
00268         else {  /* eg, char c[] = 0; */
00269             error("missing { in initialization of `%t'\n", ty);
00270             n = initchar(1, aty);
00271         }
00272     } else if (isarray(ty)) {
00273         if (t == SCON && aty == widechar) {
00274             int i;
00275             unsigned int *s = tsym->u.c.v.p;
00276             if (ty->size > 0 && ty->size == tsym->type->size - widechar->size)
00277                 tsym->type = array(widechar, ty->size/widechar->size, 0);
00278             n = tsym->type->size;
00279             for (i = 0; i < n; i += widechar->size) {
00280                 Value v;
00281                 v.u = *s++;
00282                 (*IR->defconst)(widechar->op, widechar->size, v);
00283             }
00284             t = gettok();
00285         } else if (t == '{') {
00286             t = gettok();
00287             if (t == SCON && aty == widechar) {
00288                 ty = initializer(ty, lev + 1);
00289                 initend(lev, follow);
00290                 return ty;
00291             }
00292             n = initarray(0, aty, lev + 1);
00293             test('}', follow);
00294         } else if (lev > 0 && ty->size > 0)
00295             n = initarray(ty->size, aty, lev + 1);
00296         else {
00297             error("missing { in initialization of `%t'\n", ty);
00298             n = initarray(aty->size, aty, lev + 1);
00299         }
00300     }   
00301     if (ty->size) {
00302         if (n > ty->size)
00303             error("too many initializers\n");
00304         else if (n < ty->size)
00305             (*IR->space)(ty->size - n);
00306     } else if (isarray(ty) && ty->type->size > 0)
00307         ty = array(ty->type, n/ty->type->size, 0);
00308     else
00309         ty->size = n;
00310     return ty;
00311 }

Here is the call graph for this function:

int initstruct int  len,
Type  ty,
int  lev
[static]
 

Definition at line 160 of file init.c.

References a, type::align, Field, symbol::flist, gettok(), initfields(), initializer(), IR, field::link, field::lsb, n, field::offset, p, q, roundup, symbol::s, type::size, interface::space, type::sym, t, field::type, Type, symbol::u, and type::u.

Referenced by initializer().

00160                                                  {
00161     int a, n = 0;
00162     Field p = ty->u.sym->u.s.flist;
00163 
00164     do {
00165         if (p->offset > n) {
00166             (*IR->space)(p->offset - n);
00167             n += p->offset - n;
00168         }
00169         if (p->lsb) {
00170             Field q = p;
00171             while (q->link && q->link->offset == p->offset)
00172                 q = q->link;
00173             n += initfields(p, q->link);
00174             p = q;
00175         } else {
00176             initializer(p->type, lev);
00177             n += p->type->size;
00178         }
00179         if (p->link) {
00180             p = p->link;
00181             a = p->type->align;
00182         } else
00183             a = ty->align;
00184         if (a && n%a) {
00185             (*IR->space)(a - n%a);
00186             n = roundup(n, a);
00187         }
00188         if (len > 0 && n >= len || t != ',')
00189             break;
00190         t = gettok();
00191     } while (t != '}');
00192     return n;
00193 }

Here is the call graph for this function:

Tree initvalue Type  ty  )  [static]
 

Definition at line 56 of file init.c.

References assign(), cast(), consttree(), e, error(), expr1(), generic, inttype, needconst, tree::op, retype(), Tree, tree::type, and Type.

Referenced by initchar(), and initfields().

00056                                {
00057     Type aty;
00058     Tree e;
00059 
00060     needconst++;
00061     e = expr1(0);
00062     if ((aty = assign(ty, e)) != NULL)
00063         e = cast(e, aty);
00064     else {
00065         error("invalid initialization type; found `%t' expected `%t'\n",
00066             e->type,  ty);
00067         e = retype(consttree(0, inttype), ty);
00068     }
00069     needconst--;
00070     if (generic(e->op) != CNST) {
00071         error("initializer must be constant\n");
00072         e = retype(consttree(0, inttype), ty);
00073     }
00074     return e;
00075 }

Here is the call graph for this function:

void swtoseg int  seg  ) 
 

Definition at line 314 of file init.c.

References curseg, IR, and interface::segment.

Referenced by dclglobal(), defglobal(), emitcode(), funcdefn(), and gencode().

00314                       {
00315     if (curseg != seg)
00316         (*IR->segment)(seg);
00317     curseg = seg;
00318 }


Variable Documentation

int curseg [static]
 

Definition at line 4 of file init.c.

Referenced by swtoseg().


Generated on Thu Aug 25 15:54:41 2005 for Quake III Arena by  doxygen 1.3.9.1