⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decl.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef SYNTAX_CORRECT
			if (lang_option >= LANG_C99) {
				message (ERR_UNDEFINEDFN, nameof (sp));
			} else {
				message (WARN_IMPLICITFN, nameof (sp));
			}
			break;
#endif /* SYNTAX_CORRECT */
		default:
#ifndef SYNTAX_CORRECT
			message (ERR_UNDEFINED, nameof (sp));
#endif /* SYNTAX_CORRECT */
			break;
	}
    sym_append (&sp);
    return sp;
}


/*ANSI 3.6.2
 *    declaration-list:
 *              declaration
 *              declaration-list declaration
 */
SIZE declaration_list P2 (STORAGE, def_sc, SIZE, offset)
{
    while (is_declaration_specifier (lastst)) {
		if ((def_sc != sc_member) && is_label (lastst)) {
			return offset;
		}
		offset = declaration (def_sc, def_sc, offset);
    }
    return offset;
}


/*ANSI 3.5.4
 *    identifier-list:
 *              identifier
 *              identifier-list , identifier
 */
static void identifier_list P0 (void)
{
    SYM    *sp;

    global_flag--;
    assert (lastst == tk_id);
    for (;;) {
		switch (lastst) {
			case tk_id:
				sp = mk_sym (lastsym, sc_parms, NIL_TYP);
				getsym ();
				sym_append (&sp);
				break;
			default:
#ifndef SYNTAX_CORRECT
				message (ERR_PARMS);
#endif /* SYNTAX_CORRECT */
				global_flag++;
				return;
		}
		if (lastst != tk_comma) {
			global_flag++;
			return;
		}
		getsym ();
    }
}


/*ANSI 3.5.5
 *    type-name:
 *              specifier-qualifier-list abstract-declarator[opt]
 */
TYP    *type_name P0 (void)
{
    TYP    *tp = NIL_TYP;
    SYM    *sp = NIL_SYM;
    STORAGE sc;

    if (is_type_name (lastst)) {
		sc = sc_tag;
		tp = declaration_specifiers (&sc, sc_global, NULL);
		switch (lastst) {
			case tk_star:
			case tk_openbr:
			case tk_openpa:
				sp = declarator (sc, tp);
				tp = typeof (sp);
				break;
			default:
				break;
		}
    }
    return tp;
}


/*ANSI 3.5.4
 *    parameter-type-list:
 *              parameter-list
 *              parameter-list , ...
 *
 *      parameter-list:
 *              parameter-declaration
 *              parameter-list , parameter-declaration
 *
 *      parameter-declaration:
 *              declaration-specifiers declarator
 *              declaration-specifiers abstract-declarator[opt]
 */
static void parameter_type_list P0 (void)
{
    TYP    *tp;
    SYM    *sp;
    STORAGE sc;

    global_flag++;		/* allocate into global heap */
    while (is_declaration_specifier (lastst)) {
		sc = sc_parms;
		tp = declaration_specifiers (&sc, sc_parms, NULL);
		if (sc == sc_auto) {
			sc = sc_parms;
		}
		sp = declarator (sc, tp);
		if (is_func (typeof (sp))) {
			/*
			 * Functions which are passed as a parameter are really
			 * pointers to a function.
			 */
			set_type (sp, mk_type (tp_pointer, typeof (sp)));
		}
		sym_append (&sp);
		if (lastst != tk_comma || is_void (typeof (sp))) {
			break;
		}
		getsym ();
		switch (lastst) {
			case tk_ellipsis:
				getsym ();
				check_stdarg (sp);
				tp = mk_type (tp_ellipsis, NIL_TYP);
				sp = mk_sym ((const CHAR *) "", sc_tag, tp);
				sym_append (&sp);
				global_flag--;
				return;
			case tk_closepa:
				if (lattice_option) {
					tp = mk_type (tp_ellipsis, NIL_TYP);
					sp = mk_sym ((const CHAR *) "", sc_tag, tp);
					sym_append (&sp);
					global_flag--;
					return;
				}
				break;
			default:
				break;
		}
    }
    global_flag--;
    return;
}

/*ANSI 3.5.2.2
 *    enumeration-list:
 *              enumerator
 *              enumerator-list , enumerator
 *
 *      enumerator:
 *              enumeration-constant
 *              enumeration-constant = constant-expression
 *
 *      enumeration-constant:
 *              identifier
 */
static TYP *enumeration_list P0 (void)
{
    IVAL    evalue, minval, maxval;
    int     count;
    TYP    *tp = mk_type (tp_enum, NIL_TYP);
    TYP    *tp2 = mk_type (tp_int, NIL_TYP);

    set_derived (tp2);
    set_enum (tp2);
    set_enumtype (tp2, tp);
    for (count = 0, minval = maxval = 0L, evalue = -1L; lastst == tk_id;) {
		SYM    *sp = mk_sym (lastsym, sc_const, tp2);

		getsym ();
		if (lastst == tk_assign) {
			getsym ();
			evalue = intexpr ();
		} else {
#ifndef SYNTAX_CORRECT
			switch (tp_int->size) {
				case 2L:
					if (evalue == 32767L)
						message (ERR_ENUMWRAP);
					break;
				case 4L:
					if (evalue == 2147483647L)
						message (ERR_ENUMWRAP);
					break;
		
#ifdef LONGLONG
#ifndef LONGLONG_BOOTSTRAP
#if 0
				case 8L:
					if (evalue == 9223372036854775807LL)
						message (ERR_ENUMWRAP);
					break;
		
#endif	/*  */
#endif	/* LONGLONG_BOOTSTRAP */
#endif	/* LONGLONG */
				default:
					break;
			}
#endif /* SYNTAX_CORRECT */
			evalue++;
		}
		/*
		 *Constraint: The expression that defines the value of an enumeration
		 *            constant shall be an integral constant expression that
		 *            has a value representable as an int.
		 */
		check_representable (evalue, tp_int);
		if (evalue < minval) {
			minval = evalue;
		}
		if (evalue > maxval) {
			maxval = evalue;
		}
		sp->value.i = evalue;
		sym_append (&sp);
		count++;
		if (lastst != tk_comma) {
			break;
		}
		getsym ();
    }
#ifndef SYNTAX_CORRECT
    if (count == 0) {
		message (ERR_INCOMPLETE, "enum");
    }
#endif /* SYNTAX_CORRECT */
    /* now determine the best integer type to hold the enumeration */
#ifdef PACKENUM
    if (packenum_option) {
		if (minval >= -128L && maxval <= 127L) {
			tp2 = tp_schar;
		} else if (minval >= 0L && maxval <= 256L) {
			tp2 = tp_uchar;
		} else if (minval >= -32768L && maxval <= 32767L) {
			tp2 = tp_short;
		} else if (minval >= 0L && maxval <= 65535L) {
			tp2 = tp_ushort;
		} else {
			tp2 = tp_long;
		}
    } else
#endif /* PACKENUM */
		tp2 = tp_int;
    tp->type = tp2->type;
    tp->size = tp2->size;
    set_enum (tp);
    set_enumtype (tp, tp);
    return tp;
}



/*ANSI 3.5.2.2
 *    enum-specifier:
 *              "enum" identifier[opt] { enumeration-list }
 *              "enum" identifier
 */
static TYP *enum_specifier P1 (STORAGE, sc)
{
    TYP    *tp;
    SYM    *sp;

    assert (lastst == kw_enum);
    getsym ();
    switch (lastst) {
		case tk_begin:
			getsym ();
			tp = enumeration_list ();
			needpunc (tk_end);
			break;
		case tk_id:
			if ((sp = tag_search (lastsym)) == NIL_SYM) {
				sp = mk_sym (lastsym, sc_tag, tp_enum);
				tag_append (&sp);
#ifndef SYNTAX_CORRECT
				if (sc == sc_parms) {
					message (WARN_DUBIOUS, "enum");
				}
#endif /* SYNTAX_CORRECT */
				getsym ();
				if (lastst == tk_begin) {
					getsym ();
					tp = enumeration_list ();
					set_type (sp, tp);
					set_nameoftype (tp, nameof (sp));
					needpunc (tk_end);
#ifndef SYNTAX_CORRECT
				} else {
					tp = tp_int;
					message (ERR_INCOMPLETE, "enum");
					break;
#endif /* SYNTAX_CORRECT */
				}
			} else {
				getsym ();
				if (is_local_scope (sp) || lastst != tk_begin) {
					check_tag (sp, tp_int);
					tp = typeof (sp);
#ifndef SYNTAX_CORRECT
					if (lastst == tk_semicolon) {
						message (ERR_INCOMPLETE, "enum");
					}
#endif /* SYNTAX_CORRECT */
				} else {
					getsym ();
					tp = enumeration_list ();
					set_type (sp, tp);
					set_nameoftype (tp, nameof (sp));
					needpunc (tk_end);
				}
			}
			break;
		default:
#ifndef SYNTAX_CORRECT
			tp = tp_int;
			message (ERR_INCOMPLETE, "enum");
#endif /* SYNTAX_CORRECT */
			break;
    }
    return tp;
}


static int bit_width, bit_offset, bit_next;

/*ANSI 3.5.2.1
 *    struct-declarator-list:
 *              struct-declarator
 *              struct-declarator-list , struct-declarator
 *ANSI 3.5.2.1
 *      struct-declarator:
 *              declarator
 *              declarator[opt] : constant-expression
 */
static SIZE struct_declarator_list P3 (TYP *, tp, SIZE, offset, const TYP *, stp)
{
    SIZE    size, al;
    int     int_bits;
    TYP   *tp_bit = tp_int;

    for (size = 0L;;) {
		SYM    *sp = NIL_SYM;

		switch (lastst) {
			case tk_id:
			case tk_star:
			case tk_openpa:
				sp = declarator (sc_member, tp);
#ifndef SYNTAX_CORRECT
				check_complete (typeof (sp));
				if (is_func (typeof (sp))) {
					message (ERR_FUNC);
				}
#endif /* SYNTAX_CORRECT */
				if (lastst != tk_colon) {
					switch (stp->type) {
						case bt_struct:
							al = align (typeof (sp), offset + size);
							sp->value.i = (IVAL) (offset + size + al);	/*lint !e776*/	/* possible truncation of addition */
							field_append (&sp);
							size += typeof (sp)->size + al;
							break;
						case bt_union:
							al = align (typeof (sp), offset);
							sp->value.i = (IVAL) (offset + al);	/*lint !e776*/	/* possible truncation of addition */
							field_append (&sp);
							size = typeof (sp)->size + al;
							break;
						default:
							CANNOT_REACH_HERE ();
					}
					bit_next = 0;
					break;
				}
				tp = typeof (sp);
			/*lint -fallthrough */
			case tk_colon:
				getsym ();
				/*
				 *Semantic:   A bit-field shall have type int, unsigned int, or
				 *            signed int.
				 */
#ifndef SYNTAX_CORRECT
				if (!is_same_type (tp, tp_int)
					&& !is_same_type (tp, tp_uint)
					&& !is_same_type (tp, tp_bool)) {
					if (tp->size > tp_int->size) {
						message (ERR_FLDTYPE);
					} else {
						message (WARN_FLDTYPE);
					}
				}
#endif /* SYNTAX_CORRECT */
				bit_width = (int) intexpr ();
				bit_offset = bit_next;
				if (packbit_option)
					tp_bit = tp;

				/*
				 *Constraint: The expression that specified the width of a bit-field
				 *            shall be an integral constant expression that has
				 *            nonnegative value that shall not exceed the number
				 *            of bits in an ordinary object of compatible type.
				 */
				int_bits = (int) (tp_bit->size * bits_in_sizeunit);
#ifndef SYNTAX_CORRECT
				if (bit_width < 0 || bit_width > int_bits) {
					message (ERR_WIDTH);
					bit_width = 1;
				}
#endif /* SYNTAX_CORRECT */
				/*ANSI 3.5.2.1
				 *Constraint: If the value is zero, the declaration shall have
				 *            no declarator.
				 *
				 *Semantic:   A bit-field structure member with a width of 0
				 *            indicates that no further bit-field is to be
				 *            packed into the unit in which the previous
				 *            bit-field, if any, was placed.
				 */
				if (bit_width == 0 || bit_offset + bit_width > int_bits) {
					bit_offset = 0;
				}
				bit_next = bit_offset + bit_width;
				if (sp != NIL_SYM) {
#ifndef SYNTAX_CORRECT
					if (bit_width == 0) {
						message (ERR_WIDTH);
					}
#endif /* SYNTAX_CORRECT */
					set_type (sp, copy_type (tp));
					typeof (sp)->type =
						(BTYPE) (is_signed_type (tp) ? bt_bitfield :
						(is_bool (tp) ? bt_bool : bt_ubitfield));
					typeof (sp)->size = tp_bit->size;
					set_bit_width (typeof (sp), (BITSIZE) bit_width);
					if (bitfield_option) {
						set_bit_offset (typeof (sp),
							(BITSIZE) ((int_bits - bit_offset) - bit_width));
					} else {
						set_bit_offset (typeof (sp), (BITSIZE) bit_offset);
					}
					if (bit_offset > 0) {
						offset -= tp_bit->size;	/* shares space with previous field */
					}
					al = align (typeof (sp), offset + size);
					sp->value.i = (IVAL) (offset + size + al);	/*lint !e776*/	/* possible truncation of addition */
					field_append (&sp);
					size += typeof (sp)->size + al;
					if (bit_offset > 0) {
						size -= tp_bit->size;
					}
				} else {
					if (bit_offset > 0) {
						offset -= tp_bit->size;	/* shares space with previous field */
					}
					al = align (tp_bit, offset + size);
					size += tp_bit->size + al;
					if (bit_offset > 0) {
						size -= tp_bit->size;
					}
				}

				break;
			case tk_comma:
				needpunc ((TOKEN) (lastst + 1));	/* force error */
				break;
			default:
				break;
		}
		if (lastst != tk_comma) {
			break;
		}
		getsym ();
	}
	return size;
}

static BOOL is_struct_declarator P1 (TOKEN, st)
{
    switch (st) {
		case tk_colon:
			return TRUE;
		default:
			return is_specifier_qualifier (st);
    }
}

/*ANSI 3.5.2.1
 *    struct-declaration-list:
 *              struct-declaration
 *              struct-declaration-list struct-declaration
 *
 *ANSI .5.2.1
 *      struct-declaration:
 *              specifier-qualifier-list struct-declarator-list ;
 */
static SIZE struct_declaration_list P1 (const TYP *, tp)
{
    SIZE    offset = 0L;
    SIZE    max_size = UNKNOWN_SIZE;
    int     count;

    beginstructblock (members (tp));
    bit_next = 0;
    bit_offset = 0;
    for (count = 0; is_struct_declarator (lastst); count++) {
		TYP    *tp1;
		SIZE    size;
		STORAGE sc = sc_member;

		tp1 = declaration_specifiers (&sc, sc_member, NULL);
		size = struct_declarator_list (tp1, offset, tp);
		if (offset + size > max_size) {
			max_size = offset + size;
		}
		switch (tp->type) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -