ack/lang/cem/cemcom.ansi/declarator.c
1994-06-27 08:03:14 +00:00

144 lines
3.1 KiB
C

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
/* D E C L A R A T O R M A N I P U L A T I O N */
#include "debug.h"
#include "botch_free.h"
#include <alloc.h>
#include <flt_arith.h>
#include "arith.h"
#include "type.h"
#include "proto.h"
#include "Lpars.h"
#include "declar.h"
#include "def.h"
#include "idf.h"
#include "label.h"
#include "expr.h"
#include "sizes.h"
#include "level.h"
extern char options[];
struct declarator null_declarator;
struct type *
declare_type(tp, dc)
struct type *tp;
struct declarator *dc;
{
/* Applies the decl_unary list starting at dc->dc_decl_unary
to the type tp and returns the result.
Functions that are declared within a parameter type list
are purely prototypes. Simply add the type list to the
function node.
*/
register struct decl_unary *du = dc->dc_decl_unary;
while (du) {
tp = construct_type(du->du_fund, tp, du->du_typequal,
du->du_count, du->du_proto);
du = du->next;
}
return tp;
}
add_decl_unary(dc, fund, qual, count, fm, pl)
register struct declarator *dc;
int qual;
arith count;
struct formal *fm;
struct proto *pl;
{
/* A decl_unary describing a constructor with fundamental
type fund and with size count is inserted in front of the
declarator dc.
*/
register struct decl_unary *new = new_decl_unary();
new->next = dc->dc_decl_unary;
new->du_fund = fund;
new->du_count = count;
new->du_typequal = qual;
new->du_proto = pl;
if (fm) {
if (dc->dc_decl_unary) {
/* parameters only allowed at first decl_unary */
error("formal parameters list discarded");
}
else {
/* register the proto */
dc->dc_formal = fm;
}
}
dc->dc_decl_unary = new;
}
remove_declarator(dc)
struct declarator *dc;
{
/* The decl_unary list starting at dc->dc_decl_unary is
removed.
*/
register struct decl_unary *du = dc->dc_decl_unary;
while (du) {
struct decl_unary *old_du = du;
du = du->next;
free_decl_unary(old_du);
}
}
reject_params(dc)
register struct declarator *dc;
{
/* The declarator is checked to have no parameters, if it
is an old-style function. If it is a new-style function,
the identifiers are removed. The function is not called in
case of a function definition.
*/
register struct decl_unary *du = dc->dc_decl_unary;
int err_given = 0;
if (dc->dc_formal) {
error("non_empty formal parameter pack");
free_formals(dc->dc_formal);
dc->dc_formal = 0;
err_given = 1;
}
while (du) {
if (du->du_fund == FUNCTION) {
if (du->du_proto) remove_proto_idfs(du->du_proto);
else if (! err_given && ! options['o']) {
err_given = 1;
warning("old-fashioned function declaration");
}
}
du = du->next;
}
}
check_array_subscript(expr)
register struct expr *expr;
{
arith size = expr->VL_VALUE;
if (size < 0) {
error("array size is negative");
expr->VL_VALUE = (arith)1;
}
else
if (size == 0) {
strict("array size is 0");
}
else
if (size & ~max_unsigned) { /* absolutely ridiculous */
expr_error(expr, "overflow in array size");
expr->VL_VALUE = (arith)1;
}
}