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

📄 decl.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
			break;
		case T_LONG | T_DOUBLE | T_IMAGINARY:
			tp = tp_longdoubleimaginary;
			break;
		case T_ALL:
			break;
		default:
#ifndef SYNTAX_CORRECT
			message (ERR_ILLTYPE);
			tp = tp_int;
#endif /* SYNTAX_CORRECT */
			break;
	}
	return qualify_type (tp, qualifier);
}


/*ANSI 3.5.4
 *    direct-declarator:
 *              identifier
 *              ( declarator )
 *              direct-declarator [ type-qualifier-list assignment-expression[opt] ]
 *              direct-declarator [ static type-qualifier-list[opt] assignment-expression ]
 *              direct-declarator [ type-qualifier-list static assignment-expression ]
 *              direct-declarator [ type-qualifier-list[opt] * ]
 *              direct-declarator ( parameter-type-list )
 *              direct-declarator ( identifier-list[opt] )
 *
 *      direct-abstract-declarator:
 *              ( abstract-declarator )
 *              direct-abstract-declarator[opt] [ constant-expression[opt] ]
 *              direct-abstract-declarator[opt] ( parameter-type-list[opt] )
 */
static TYP *direct_declarator_tail P2 (SYM *, sp, TYP *, tp)
{
    SIZE    size, ind;

    switch (lastst) {
		case tk_openbr:
			getsym ();
			if (lastst != tk_closebr) {
				ind = (SIZE) intexpr ();
#ifndef SYNTAX_CORRECT
				/*
				 *Constraint: The expression delimited by [ and ] (which
				 *        specifies the size of an array) shall be an
				 *        integral constant expression that has a value
				 *        greater than zero.
				 */
				if (ind <= 0L) {
					message (ERR_SIZE);
				}
#endif /* SYNTAX_CORRECT */
			} else {
				ind = UNKNOWN_SIZE;
			}
			needpunc (tk_closebr);
			tp = direct_declarator_tail (sp, tp);
			size = tp ? tp->size : (SIZE) 1;
			tp = mk_type (tp_array, tp);
			set_array_index (tp, ind);
			set_derived (tp);
			if (size == UNKNOWN_SIZE || ind == UNKNOWN_SIZE) {
				tp = copy_type (tp);
				tp->size = UNKNOWN_SIZE;
			} else {
				tp->size = size * ind;
			}
			return tp;

		case tk_openpa:
			getsym ();
			tp = mk_type (tp_func, tp);
			set_derived (tp);

			switch (lastst) {
				case tk_id:
					if (!is_typedef_symbol (lastsym)) {
#ifdef FACIST
#ifndef SYNTAX_CORRECT
						message (WARN_OLDDEF);
#endif /* SYNTAX_CORRECT */
#endif /* FACIST */
						beginparamblock ();
						identifier_list ();
						set_parameters (tp, endparamblock ());
#ifndef SYNTAX_CORRECT
						if (obsolete_option) {
							message (WARN_PROTOTYPE, nameof (sp));
						}
#endif /* SYNTAX_CORRECT */
						break;
					}
				/*lint -fallthrough */
				default:
					if (lang_option >= LANG_C90) {
						beginparamblock ();
						parameter_type_list ();
						set_parameters (tp, endparamblock ());
						set_ansi (tp);
					}
					break;
				case tk_closepa:
					set_parameters (tp, &init_block);
#ifndef SYNTAX_CORRECT
#ifdef FACIST
					message (WARN_OLDDEF);
#endif /* FACIST */
					if (obsolete_option) {
						message (WARN_PROTOTYPE, nameof (sp));
					}
#endif /* SYNTAX_CORRECT */
					break;
			}
			needpunc (tk_closepa);
#ifdef ASMCALL
			if (asmcall_option != NULL) {
				funckind (tp) = fc_user;
				funccall (tp) = asmcall_option;
				asmcall_option = NULL;
			}
#endif /* ASMCALL */
			return direct_declarator_tail (sp, tp);
		default:
			return tp;
    }
}

static SYM *direct_declarator P2 (STORAGE, sc, TYP *, tp)
{
    SYM    *sp;

    switch (lastst) {
		case tk_id:
			sp = mk_sym (lastsym, sc, tp);
			getsym ();
			break;
		case tk_openpa:
			getsym ();
			if (lastst == tk_closepa) {
				/*
				 * empty parentheses in a type-name are interpreted as "function
				 * with no parameter specification", rather than redundant
				 * parentheses around the omitted identifier.
				 */
				getsym ();
				tp = mk_type (tp_func, tp);
				sp = mk_sym ((const CHAR *) "", sc, tp);
			} else {
			    TYP    *tp1;

				sp = declarator (sc, NIL_TYP);
				needpunc (tk_closepa);
				tp = direct_declarator_tail (sp, tp);
				tp1 = typeof (sp);
				if (tp1 != NIL_TYP) {
					for (; tp1->btp; tp1 = tp1->btp)
						/* nothing */ ;
						tp1->btp = tp;
				} else {
					set_type (sp, tp);
				}
				size_type (typeof (sp));
			}
			return sp;
		default:
			/* abstract */
			sp = mk_sym ((const CHAR *) "", sc, tp);
			break;
    }
    set_type (sp, direct_declarator_tail (sp, typeof (sp)));
    return sp;
}


/*ANSI 3.5.4
 *    type-qualifier-list:
 *              type-qualifier
 *              type_qualifier-list type-qualifier
 */
static QUALIFIER type_qualifier_list P0 (void)
{
    QUALIFIER qual = QUAL_NONE;

    while (is_type_qualifier (lastst)) {
		qual = type_qualifier (qual);
    }
    return qual;
}


/*ANSI 3.5.4
 *    declarator:
 *              pointer[opt] direct-declarator
 *
 *      abstract-declarator:
 *              pointer
 *              pointer[opt] direct-abstract-declarator
 *
 *      pointer:
 *              * type-qualifier-list[opt]
 *              * type-qualifier-list[opt] pointer
 */
static SYM *declarator P2 (STORAGE, sc, TYP *, tp)
{
    SYM    *sp;

    switch (lastst) {
		case tk_star:
			getsym ();
			tp = mk_type (tp_pointer, tp);
			if (tp->btp == NIL_TYP) {
				/*
				 *       The type of pointer isn't known .... it will only be
				 *       known later.    We must ensure that the same pointer is
				 *       therefore not used more than once.
				 */
				tp = copy_type (tp);
			}
			tp = qualify_type (tp, type_qualifier_list ());
			sp = declarator (sc, tp);
			break;
		case tk_id:
		case tk_openpa:
		case tk_openbr:
			sp = direct_declarator (sc, tp);
			break;
		default:
			sp = mk_sym ((const CHAR *) "", sc, tp);
    }
    return sp;
}

static BLOCK *get_parameters P1 (const SYM *, sp)
{
    BLOCK  *block, *block2;
    SYM    *sp1, *sp2;

    block = parameters (typeof (sp));
    if (is_ansi (typeof (sp))) {
#ifndef SYNTAX_CORRECT
	if (lastst == tk_begin) {
	    /*
	     * Parameters to function definitions must have a name
	     */
	    for (sp2 = symbolsof (block); sp2 != NIL_SYM; sp2 = nextsym (sp2)) {
		if (is_void (typeof (sp2)) || is_ellipsis (typeof (sp2))) {
		    break;
		}
		if (nameof (sp2) == NIL_CHAR || nameof (sp2)[0] == (CHAR) 0) {
		    message (ERR_PARMS);
		    break;
		}
		symbol_set (sp2);
	    }
	}
#endif /* SYNTAX_CORRECT */
    } else {
	beginparamblock ();
	VOIDCAST declaration_list (sc_parms, 0L);

	block2 = endparamblock ();
	set_parameters (typeof (sp), &init_block);

#ifndef SYNTAX_CORRECT
	/*
	 * an id list on a function declaration is illegal
	 */
	if ((lastst != tk_begin) && (symbolsof (block) != NIL_SYM)) {
	    message (ERR_IDLIST);
	}
#endif /* SYNTAX_CORRECT */
	/*
	 * now match up the identifier list with the declarations
	 */
	for (sp1 = symbolsof (block); sp1 != NIL_SYM; sp1 = nextsym (sp1)) {
	    sp2 = search (nameof (sp1), &block2->symbols);
	    if (sp2 == NIL_SYM) {
#ifndef SYNTAX_CORRECT
		message (WARN_IMPLICIT, nameof (sp1));
#endif /* SYNTAX_CORRECT */
		set_type (sp1, tp_int);
	    } else {
		set_storage (sp1, storageof (sp2));
		set_type (sp1, typeof (sp2));
		sp1->value.i = sp2->value.i;
		symbol_set (sp1);
	    }
	}
#ifndef SYNTAX_CORRECT
	/*
	 * now check for declared items which aren't in the
	 * identifier list for the function.
	 */
	for (sp2 = symbolsof (block2); sp2 != NIL_SYM; sp2 = nextsym (sp2)) {
	    if (is_const (sp2)) {
		continue;
	    }
	    if (search (nameof (sp2), &block->symbols) == NIL_SYM) {
		message (ERR_ARG, nameof (sp2));
	    }
	    symbol_set (sp2);
	}
	/*
	 * check the function parameter declarations with any function
	 * prototype which may be in scope.
	 */
	check_parameters (block, sp);
#endif /* SYNTAX_CORRECT */
    }
    return block;
}

/*ANSI 3.7
 *    external-declaration:
 *              function-declaration
 *              declaration
 *
 *ANSI 3.5
 *      declaration:
 *              declaration-specifiers init-declaration-list[opt] ;
 *
 *      init-declaration-list:
 *              init-declarator
 *              init-declarator-list , init-declarator
 *
 *      init-declarator:
 *              declarator
 *              declarator = initializer
 *
 *      function-definition:
 *              declaration-specifiers[opt] declarator declaration-list[opt]
 *                                                      compound-statement
 */
static SIZE declaration P3 (STORAGE, sc, STORAGE, def_sc, SIZE, offset) {
    TYP    *tp;
    SYM    *sp;
    FSPECIFIER fs = fs_none;

    tp = declaration_specifiers (&sc, def_sc, &fs);
#ifndef SYNTAX_CORRECT
    switch (def_sc) {
		case sc_global:
			if (sc == sc_register || sc == sc_auto) {
				message (ERR_ILLCLASS);
			}
			break;
		case sc_parms:
			if (sc != sc_register && sc != sc_parms) {
				message (ERR_ILLCLASS);
			}
			break;
		default:
			break;
	}
#endif /* SYNTAX_CORRECT */
	for (sp = NIL_SYM;;) {
		switch (lastst) {
			case tk_id:
			case tk_star:
			case tk_openpa:
				if (sc != sc_global && tp == NIL_TYP) {
					/*ANSI 3.5
					 * If an identifier for an object is declared with no linkage,
					 * the type for the object shall be complete by the end of its
					 * declarator, or by the end of its identifiers if it has an
					 * initializer.
					 *ANSI 3.1.2.2
					 * The following identifiers have no linkage: an identifier
					 * declared to be anything other than an object or a function;
					 * an identifier declared to be a function parameter; a block
					 * scope identifier for an object declared without the
					 * storage-class specifier extern.
					 */
					return offset;
				}
				sp = declarator (sc, tp);
				switch (typeof (sp)->type) {
					BLOCK  *block;

					case bt_func:
						set_fspecifier (sp, fs);
						check_function_definition (sp);
						if (lastst != tk_semicolon) {
							block = get_parameters (sp);
						} else {
							block = NIL_BLOCK;
						}
						if (def_sc == sc_parms) {
							/*
							* Functions which are passed as a parameter are really
							* pointers to a function.
							*/
							set_type (sp, mk_type (tp_pointer, typeof (sp)));
						}
						if (lastst == tk_begin) {
							/* function declaration */
							sp = declare (sp, def_sc);
#ifndef SYNTAX_CORRECT
							check_function_declaration (sp);
							if (def_sc != sc_global) {
								message (ERR_NESTED, nameof (sp));
								break;
							}
							if (is_symbol_defined (sp)) {
								message (ERR_REDECL, nameof (sp));
							}
							symbol_defined (sp);
#endif /* SYNTAX_CORRECT */
#ifdef EXTERNAL
							funclist (sp);
#endif /* EXTERNAL */
							func_symbol = sp;
							funcbody (sp, block);
							func_symbol = NULL;
							return offset;
						}
						/*lint -fallthrough */
					default:
#ifndef SYNTAX_CORRECT
						if (fs == fs_inline) {
							message (ERR_INLINE);
						}
#endif /* SYNTAX_CORRECT */
						sp = declare (sp, def_sc);
						offset = doinit (sp, offset);
						if (def_sc == sc_auto) {
							switch (storageof (sp)) {
								default:
#ifndef SYNTAX_CORRECT
									check_complete (typeof (sp));
#endif /* SYNTAX_CORRECT */
#ifdef CPU_DEFINED
									addoptinfo (sp, def_sc);
#endif /* CPU_DEFINED */
								/*lint -fallthrough */
								case sc_external:
								case sc_typedef:
									break;
							}
						}
				}
				break;
			case tk_eof:
				return offset;
			case tk_comma:
				needpunc ((TOKEN) (lastst + 1));	/* force error */
				break;
			default:
				break;
		}
		if (lastst != tk_comma) {
			break;
		}
		getsym ();
	}
#ifndef SYNTAX_CORRECT
	if (sp == NIL_SYM) {
		switch (sc) {
			case sc_typedef:
				if (is_anonymous_structure (tp)) {
					/* no declarator defined */
					message (ERR_IDEXPECT);
				} else {
					/* struct declator defined so is legal */
					message (WARN_TYPEDEF);
				}
			/*lint -fallthrough*/
			case sc_external:
			case sc_global:
			case sc_static:
				if (is_structure_type (tp)) {
				} else if (is_enum (tp)) {
				} else {
					message (ERR_IDEXPECT);
				}
				break;
			default:
				break;
		}
	}
#endif /* SYNTAX_CORRECT */
	if (lastst == tk_semicolon) {
		needpunc (tk_semicolon);
	} else {
		needpunc (tk_semicolon);
		getsym ();
	}
	return offset;
}


/*
 * main compiler routine. this routine parses all of the declarations using
 * declare which will call funcbody as functions are encountered.
 *
 *ANSI 3.7
 *      translation-unit:
 *              external-declaration
 *              translation-unit external-declaration
 */
void translation_unit P0 (void) {
    SIZE    offset = 0L;
#ifdef VERBOSE
    clock_t ltime = clock ();

#endif
    global_flag = 1;
    strtab = NIL_STRING;
    beginblock ();
    nextlabel = (LABEL) 1;
#ifdef CPU_DEFINED
    if (code_option) {
		put_start ();
    }
#endif /* CPU_DEFINED */
    while (lastst != tk_eof) {
#ifndef SYNTAX_CORRECT
		if (lastst == tk_semicolon) {
			message (WARN_EMPTY);
		}
#endif /* SYNTAX_CORRECT */
		offset += declaration (sc_global, sc_global, offset);
	}
    endblock ();
#ifdef CPU_DEFINED
    if (code_option) {
		put_literals ();
		put_finish ();
    }
#endif /* CPU_DEFINED */
#ifdef VERBOSE
    decl_time += clock () - ltime;
#endif
}

⌨️ 快捷键说明

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