📄 init.c
字号:
if (is_unknown_size (tp)) { tp->size = nbytes;#ifndef SYNTAX_CORRECT } else if (tp->size < nbytes) { message (ERR_INITSIZE);#endif /* SYNTAX_CORRECT */ }#ifdef CPU_DEFINED for (; tp->size > nbytes; nbytes++) put_byte ((UVAL) Ox0UL);#endif /* CPU_DEFINED */ return nbytes;}static SIZE initunion P2 (const TYP *, tp, BOOL, brace_seen){ SYM *sp = membersof (tp); SIZE nbytes;/* * Initialize the first branch */ if (sp == NIL_SYM) { return 0L; } check_brace (brace_seen); nbytes = inittype (typeof (sp));#ifdef CPU_DEFINED for (; nbytes < tp->size; nbytes++) put_byte ((UVAL) Ox0UL);#endif /* CPU_DEFINED */ return nbytes;}#ifdef CPU_DEFINEDstatic SIZE alignfield P2 (SIZE, nbytes, SIZE, offset){ if (was_bitfield && nbytes < offset) { if (tp_int->size == 2L) { put_word (bit_value); } else { put_dword (bit_value); } bit_value = (UVAL) 0; was_bitfield = FALSE; nbytes += tp_int->size; } for (; nbytes < offset; nbytes++) put_byte ((UVAL) Ox0UL); return nbytes;}#endif /* CPU_DEFINED */static SIZE initstruct P2 (const TYP *, tp, BOOL, brace_seen){ SYM *sp;#ifdef CPU_DEFINED SIZE nbytes = 0L;#endif /* CPU_DEFINED */ check_brace (brace_seen); for (sp = membersof (tp); sp != NIL_SYM;) { if (is_const (sp)) { sp = nextsym (sp); continue; }#ifdef CPU_DEFINED nbytes = alignfield (nbytes, (SIZE) sp->value.i); nbytes += inittype (typeof (sp));#endif /* CPU_DEFINED */ sp = nextsym (sp); if (lastst != tk_comma || sp == NIL_SYM) { break; } getsym (); /* comma */ if (lastst == tk_end) { break; } }#ifndef SYNTAX_CORRECT if (sp != NIL_SYM) { message (WARN_INCOMPLETE); }#endif /* SYNTAX_CORRECT */#ifdef CPU_DEFINED nbytes = alignfield (nbytes, tp->size);#endif /* CPU_DEFINED */ return tp->size;}static SIZE initbitfield P1 (TYP *, tp){ EXPR *ep; UVAL val;#ifdef CPU_DEFINED was_bitfield = TRUE;#endif /* CPU_DEFINED */ if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; } val = ep->v.u & bitmask (bitfield_width (tp)); bit_value |= (val << (int) bitfield_offset (tp)); return 0L;}static SIZE initbool P1 (TYP *, tp){ EXPR *ep; if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; }#ifdef CPU_DEFINED put_char (unsymbolexpr (ep));#endif /* CPU_DEFINED */ return tp->size;}static SIZE initchar P1 (TYP *, tp){ EXPR *ep; if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; }#ifdef CPU_DEFINED put_char (unsymbolexpr (ep));#endif /* CPU_DEFINED */ return tp->size;}static SIZE initshort P1 (TYP *, tp){ EXPR *ep; if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; }#ifdef CPU_DEFINED put_short (unsymbolexpr (ep));#endif /* CPU_DEFINED */ return tp->size;}static SIZE initlong P1 (TYP *, tp){ EXPR *ep; if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; }#ifdef CPU_DEFINED put_long (unsymbolexpr (ep));#endif /* CPU_DEFINED */ return tp->size;}#ifdef LONGLONG_SUPPORTstatic SIZE initlonglong P1 (TYP *, tp){ EXPR *ep; if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; }#ifdef CPU_DEFINED put_longlong (unsymbolexpr (ep));#endif /* CPU_DEFINED */ return tp->size;}#endif /* LONGLONG_SUPPORT */#ifdef FLOAT_SUPPORT#ifndef FLOAT_BOOTSTRAPstatic SIZE initfloat P1 (TYP *, tp){ RVAL val; floatexpr (tp, &val);#ifdef CPU_DEFINED put_float (&val);#endif /* CPU_DEFINED */ return tp->size;}static SIZE initdouble P1 (TYP *, tp){ RVAL val; floatexpr (tp, &val);#ifdef CPU_DEFINED put_double (&val);#endif /* CPU_DEFINE */ return tp->size;}static SIZE initlongdouble P1 (TYP *, tp){ RVAL val; floatexpr (tp, &val);#ifdef CPU_DEFINED put_longdouble (&val);#endif /* CPU_DEFINED */ return tp->size;}#endif /* FLOAT_BOOTSTRAP */#endif /* FLOAT_SUPPORT */static SIZE initpointer P1 (TYP *, tp){ EXPR *ep; if ((ep = constexpr (tp)) == NIL_EXPR) { return 0L; }#ifdef CPU_DEFINED put_pointer (unsymbolexpr (ep));#endif /* CPU_DEFINED */ return tp->size;}static EXPR *constexpr P1 (TYP *, tp){ EXPR *ep = exprnc ();#ifndef SYNTAX_CORRECT if (ep == NIL_EXPR) { message (ERR_CONSTEXPR); getsym (); return NIL_EXPR; }#endif /* SYNTAX_CORRECT */ ep = implicit_castop (ep, tp); ep = constantopt (ep); /* ep may still contain casts between 32-bit integers and pointers */ while ((ep->nodetype == en_cast) && (ep->etp->type == bt_long || ep->etp->type == bt_ulong || ep->etp->type == bt_int32 || ep->etp->type == bt_uint32 || ep->etp->type == bt_pointer32) && (ep->v.p[0]->etp->type == bt_long || ep->v.p[0]->etp->type == bt_ulong || ep->v.p[0]->etp->type == bt_int32 || ep->v.p[0]->etp->type == bt_uint32 || ep->v.p[0]->etp->type == bt_pointer32)) { ep->v.p[0]->etp = ep->etp; ep = ep->v.p[0]; }#ifndef SYNTAX_CORRECT if (!tst_const (ep)) { message (ERR_CONSTEXPR); getsym (); return NIL_EXPR; }#endif /* SYNTAX_CORRECT */ return ep;}void initfuncid P2 (const SYM *, sp, const SYM *, funcsp){ SIZE nbytes = (SIZE) strlen ((const char *) nameof (funcsp)) + 1; TYP *tp = typeof (sp);#ifdef CPU_DEFINED const CHAR *p; SIZE len; put_cseg (alignment_of_type (tp)); put_label (sp->value.l); for (len = nbytes, p = nameof (funcsp); len--;) put_byte ((UVAL) *p++);#endif /* CPU_DEFINED */ tp->size = nbytes;}/* * initializer: * assignment_expression * { initializer-list } * { initializer-list , } */static EXPR *initializer P3 (TYP *, tp, SIZE, offset, STORAGE, sc){ EXPR *ep = NIL_EXPR; int brace_level = 0; /* * the type of the entity to be initialized shall be an * array of unknown size or an object type that is not * a variable length array type. */ switch (lastst) { case tk_begin: getsym (); ep = initializer_list (tp, offset, sc); if (lastst == tk_comma) { getsym (); } needpunc (tk_end); break; default: while (lastst == tk_begin) { brace_level++; getsym (); } switch (tp->type) { case bt_pointer16: case bt_pointer32: if (is_array_type (tp)) { TYP *rtp = referenced_type (tp); if (lastst == tk_sconst && (is_char (rtp) || rtp->type == bt_uchar || rtp->type == bt_schar)) { /* * An aray of character type may be initialized * by a character string literal, optionally * enclosed in braces. Successive characters of * the character string literal (including the * terminating null character if there is room or * if the array is of unknown size) initializes the * elements of the array. */ if (is_unknown_size (tp)) { tp->size = lastsymlen + 1L;#ifndef SYNTAX_CORRECT } else if (lastsymlen > tp->size) { message (ERR_INITSIZE);#endif /* SYNTAX_CORRECT */ } ep = mk_scon (lastsym, tp); getsym (); } else if (lastst == tk_wsconst && is_same_type (rtp, tp_wchar)) { /* An array with element type compatible with * wchar_t may be initialized by a wide string * literal,optionally enclosed in braces. * Succesive wide charaters of the wide string * literal (including the terminating null wide * character if there is room or if the array * is of unknon size) initialized the elemens of * the array. */ if (is_unknown_size (tp)) { tp->size = lastsymlen + 1L;#ifndef SYNTAX_CORRECT } else if (lastsymlen > tp->size) { message (ERR_INITSIZE);#endif /* SYNTAX_CORRECT */ } ep = mk_scon (lastsym, tp); getsym (); } else { } break; } /*lint -fallthrough */ case bt_bool: case bt_char: case bt_schar: case bt_charu: case bt_uchar: case bt_short: case bt_int16: case bt_ushort: case bt_uint16: case bt_int32: case bt_uint32: case bt_long: case bt_ulong: case bt_longlong: case bt_ulonglong: case bt_float: case bt_double: case bt_longdouble: /* * The initialize for a scalar shall be a single * expression, optionally enclosed in braces. The * initial value of the object is that of the * expression (after conversion); the same type * constraints and conversions as for simple * assignment apply, taking the type of the scalar * to be the unqualified version of its declared * type */ ep = exprnc (); break; case bt_struct: case bt_union: /* * The initializer for a structure or union object * that has automatic storage duration shall be * shall be either an initializer list, or a * single expression that has compatible structure * or union type. In the latter case, the initial * value of the object, including unnamed members, * is that of the expression. */ switch (lastst) { case tk_id: case tk_star: case tk_openpa: break; default: ep = exprnc (); break; } break; default: CANNOT_REACH_HERE (); } while (brace_level--) { needpunc (tk_end); } /* * All the expressions in an initializer for an object * that has static storage duration shall be constant * expressions or string literals */ switch (sc) { case sc_static:#ifndef SYNTAX_CORRECT if (!tst_const (ep)) { message (ERR_CONSTEXPR); }#endif /* SYNTAX_CORRECT */ break; default: break; } ep = implicit_castop (ep, tp); ep = mk_litval (ep, offset); break; } return ep;}/* * initializer-list: * designation[opt] initializer * initializer-list , designation[opt] initializer * * designation: * designator-list = * * designator-list: * designator * desingator-list designator * * designator: * [ constant-expression ] * . identifier */EXPR *initializer_list P3 (TYP *, tp, SIZE, offset, STORAGE, sc){ EXPR *ephead, *eptail; EXPR *ep1; /* * Each brace-enclosed initializer list has an * associated current object. When no * designations are present, subobjects of the * current object are initialized in order * according to the type of the current object: * array elements in increasing subscript order, * structure members in declaration order, and * the first named member of a union. In contrast, * a designation causes the following initializer * to begin initialization of the subobject * described by the designator. Initialization * then continues forward in order, beginning * with the next subobject after that described by * the designator. */ /* * Each designator list begins its description with * with the current object associated with the * closest surrounding brace pair. Each item in * the designator list (in order) specifies a * particular member of its current object and * changes the current object for the next * designator (if any) to be that member. The * current object that results at the end of the * designator list is the subobject to be initialized * by the following initializer. */ /* * The initialization shall occur in initializer * list order, Each initializer provided for a * particular subobject overriding any previously * listed initializer for the same subobject; all * subobjects that are not initialized explicitly * shall be initialized the same as objects that * have static storage duration. */ ephead = eptail = NIL_EXPR; for (;;) { TYP *tp1 = tp; SIZE off = offset; switch (lastst) { case tk_openbr: case tk_dot: for (;;) { SIZE ind; SYM *sp; switch (lastst) { case tk_openbr: /* * If a designator has the form * * [ constant-expression ] * * then the current object shall have array type and * the expression shall be an integer constant * expression. If the array is of unknown size, * any nonnegative value is valid. */ getsym ();#ifndef SYNTAX_CORRECT if (!is_array_type (tp1)) { message (ERR_NOARRAY); }#endif /* SYNTAX_CORRECT */ ind = (SIZE) intexpr (); tp1 = referenced_type (tp1); needpunc (tk_closebr); off += tp1->size * ind; break; case tk_dot: /* * If a designator has the form * * . identifier * * then the current object shall have structure or * union type and the identifier shall be the name * of a member of that type. */ getsym (); if (lastst == tk_id) { if (is_structure_type (tp1) && (members (tp1) != NIL_BLOCK) && ((sp = search (lastsym, &(members (tp1)->symbols))) != NIL_SYM)) { tp1 = typeof (sp); getsym (); off += (SIZE) sp->value.u;#ifndef SYNTAX_CORRECT } else { message (ERR_NOMEMBER, lastsym);#endif /* SYNTAX_CORRECT */ }#ifndef SYNTAX_CORRECT } else { message (ERR_IDEXPECT);#endif /* SYNTAX_CORRECT */ } break; case tk_assign: getsym (); goto common; /*lint !e801*/ /* use of goto is deprecated */ default: needpunc (tk_assign); return NIL_EXPR; } } break; default: common: ep1 = initializer (tp1, off, sc); break; } if (eptail) { eptail->v.p[1] = mk_node (en_list, ep1, NIL_EXPR, tp_void); eptail = eptail->v.p[1]; } else { ephead = eptail = mk_node (en_list, ep1, NIL_EXPR, tp_void); } if (lastst != tk_comma) return ephead; getsym (); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -