1989-02-07 11:04:05 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1994-06-27 08:03:14 +00:00
|
|
|
/* $Id$ */
|
1989-02-07 11:04:05 +00:00
|
|
|
/* D E C L A R A T O R M A N I P U L A T I O N */
|
|
|
|
|
2013-05-12 19:45:55 +00:00
|
|
|
#include "parameters.h"
|
2019-02-18 16:42:15 +00:00
|
|
|
#include "declarator.h"
|
1989-02-07 11:04:05 +00:00
|
|
|
#include <alloc.h>
|
1989-09-19 16:13:23 +00:00
|
|
|
#include <flt_arith.h>
|
1989-02-07 11:04:05 +00:00
|
|
|
#include "arith.h"
|
|
|
|
#include "type.h"
|
|
|
|
#include "proto.h"
|
|
|
|
#include "Lpars.h"
|
|
|
|
#include "declar.h"
|
|
|
|
#include "def.h"
|
2019-02-18 16:42:15 +00:00
|
|
|
#include "idf.h"
|
1989-02-07 11:04:05 +00:00
|
|
|
#include "label.h"
|
|
|
|
#include "expr.h"
|
|
|
|
#include "sizes.h"
|
|
|
|
#include "level.h"
|
2019-02-18 16:42:15 +00:00
|
|
|
#include "error.h"
|
1989-02-07 11:04:05 +00:00
|
|
|
|
|
|
|
extern char options[];
|
|
|
|
struct declarator null_declarator;
|
|
|
|
|
|
|
|
struct type *
|
2019-02-18 16:42:15 +00:00
|
|
|
declare_type(
|
|
|
|
struct type *tp,
|
|
|
|
struct declarator *dc)
|
1989-02-07 11:04:05 +00:00
|
|
|
{
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2019-02-18 16:42:15 +00:00
|
|
|
void add_decl_unary(register struct declarator *dc, int fund, int qual, arith count, struct formal *fm, struct proto *pl)
|
1989-02-07 11:04:05 +00:00
|
|
|
{
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2019-02-18 16:42:15 +00:00
|
|
|
void remove_declarator(struct declarator *dc)
|
1989-02-07 11:04:05 +00:00
|
|
|
{
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 16:42:15 +00:00
|
|
|
void reject_params(register struct declarator *dc)
|
1989-02-07 11:04:05 +00:00
|
|
|
{
|
|
|
|
/* The declarator is checked to have no parameters, if it
|
1990-09-12 16:36:16 +00:00
|
|
|
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.
|
1989-02-07 11:04:05 +00:00
|
|
|
*/
|
1990-09-12 16:36:16 +00:00
|
|
|
register struct decl_unary *du = dc->dc_decl_unary;
|
1991-02-27 13:48:54 +00:00
|
|
|
int err_given = 0;
|
1990-09-12 16:36:16 +00:00
|
|
|
|
1989-02-07 11:04:05 +00:00
|
|
|
if (dc->dc_formal) {
|
|
|
|
error("non_empty formal parameter pack");
|
|
|
|
free_formals(dc->dc_formal);
|
|
|
|
dc->dc_formal = 0;
|
1991-02-27 13:48:54 +00:00
|
|
|
err_given = 1;
|
1989-02-07 11:04:05 +00:00
|
|
|
}
|
1990-09-12 16:36:16 +00:00
|
|
|
while (du) {
|
1991-02-27 13:48:54 +00:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
1990-09-12 16:36:16 +00:00
|
|
|
du = du->next;
|
|
|
|
}
|
1989-02-07 11:04:05 +00:00
|
|
|
}
|
|
|
|
|
2019-02-18 16:42:15 +00:00
|
|
|
void check_array_subscript(register struct expr *expr)
|
1989-02-07 11:04:05 +00:00
|
|
|
{
|
|
|
|
arith size = expr->VL_VALUE;
|
|
|
|
|
|
|
|
if (size < 0) {
|
|
|
|
error("array size is negative");
|
|
|
|
expr->VL_VALUE = (arith)1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (size == 0) {
|
1989-09-29 16:20:38 +00:00
|
|
|
strict("array size is 0");
|
1989-02-07 11:04:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if (size & ~max_unsigned) { /* absolutely ridiculous */
|
|
|
|
expr_error(expr, "overflow in array size");
|
|
|
|
expr->VL_VALUE = (arith)1;
|
|
|
|
}
|
|
|
|
}
|