/*ident "@(#)cls4:src/norm2.c 1.4" */ /******************************************************************************* C++ source for the C++ Language System, Release 3.0. This product is a new release of the original cfront developed in the computer science research center of AT&T Bell Laboratories. Copyright (c) 1993 UNIX System Laboratories, Inc. Copyright (c) 1991, 1992 AT&T and UNIX System Laboratories, Inc. Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System Laboratories, Inc. The copyright notice above does not evidence any actual or intended publication of such source code. norm2.c: "normalization" handles problems which could have been handled by the syntax analyser; but has not been done. The idea is to simplify the grammar and the actions associated with it, and to get a more robust error handling ****************************************************************************/ #include "cfront.h" #include "size.h" #ifdef DBG long node_id = 0; #define DBCHECK() if(node::allocated) error('i',"allocated node (id %d, base%k) on free list! (src: \"%s\", %d",node::id,node::base,__FILE__,__LINE__); #else #define DBCHECK() /**/ #endif fct::fct(Ptype t, Pname arg, TOK known) { base = FCT; nargs_known = known; returns = t; argtype = arg; DBID(); if (arg==0 || arg->base==ELIST) return; //error('d',"fct::fct %d sig %d",this,f_signature); register Pname n; Pname pn = 0; for (n=arg; n; pn=n,n=n->n_list) { if( n->n_sto==EXTERN ) error("cannot specify extern linkage for anA"); if( n->n_sto==STATIC ) error("cannot specify static forA%n",arg); switch (n->tp->skiptypedefs()->base) { case VOID: argtype = 0; nargs_known = 1; if(n->n_initializer) error("voidFA"); else if (n->string) error("voidFA%n",n); else if (nargs || n->n_list) { error("voidFA"); nargs_known = 0; } nargs = 0; break; case CLASS: case ENUM: error("%k defined inAL (will not be in scope at point of call)",n->tp->base); if (n == argtype) argtype = n->n_list; else pn->n_list = n->n_list; break; default: nargs++; } } } expr::expr(TOK ba, Pexpr a, Pexpr b) { DBCHECK(); base = ba; e1 = a; e2 = b; DBID(); } stmt::stmt(TOK ba, loc ll, Pstmt a) { DBCHECK(); base = ba; where = ll; s=a; memtbl = 0; k_tbl = 0;//SYM DBID(); } classdef::classdef(TOK b) { base = CLASS; csu = b; memtbl = new table(CTBLSIZE,0,0); k_tbl = 0;//SYM DBID(); } classdef::~classdef() { delete memtbl; } basetype::basetype(TOK b, Pname n) { switch (b) { case 0: break; case TYPEDEF: b_typedef = 1; break; case INLINE: b_inline = 1; break; case VIRTUAL: b_virtual = 1; break; case CONST: b_const = 1; break; case UNSIGNED: b_unsigned = 1; break; case FRIEND: case OVERLOAD: case EXTERN: case STATIC: case AUTO: case REGISTER: b_sto = b; break; case SHORT: b_short = 1; break; case LONG: b_long = 1; break; case VLONG: b_vlong = 1; break; case ANY: case ZTYPE: case VOID: case CHAR: case INT: case FLOAT: case LDOUBLE: case DOUBLE: base = b; break; case TYPE: case COBJ: case EOBJ: case FIELD: case ASM: base = b; b_name = n; break; case SIGNED: case VOLATILE: error('w',"\"%k\" not implemented (ignored)",b); break; default: error('i',"badBT:%k",b); } DBID(); } name::name(char* s) : expr(NAME,0,0) { // DBCHECK() called in expr::expr() string = s; where = curloc; lex_level = bl_level; } name_list::name_list(Pname ff, Plist ll) { base = XNLIST; f=ff; l=ll; }; nlist::nlist(Pname n) { head = n; for (Pname nn=n; nn->n_list; nn=nn->n_list); tail = nn; } void nlist::add_list(Pname n) { if (n->tp && (n->tp->defined & IN_ERROR)) return; tail->n_list = n; for (Pname nn=n; nn->n_list; nn=nn->n_list); tail = nn; } Pname name_unlist(Pnlist l) { if (l == 0) return 0; Pname n = l->head; delete l; return n; } Pstmt stmt_unlist(Pslist l) { if (l == 0) return 0; Pstmt s = l->head; // NFl++; delete l; return s; } Pexpr expr_unlist(Pelist l) { if (l == 0) return 0; Pexpr e = l->head; // NFl++; delete l; return e; } void sig_name(Pname n) { static char buf[1024]; buf[0] = '_'; buf[1] = '_'; buf[2] = 'o'; buf[3] = 'p'; char* p = n->tp->signature(buf+4); if (255 < p-buf) error('i',"sig_name():N buffer overflow"); char *s = new char [ p - buf + 1 ]; strcpy(s,buf); n->string = s; n->tp = 0; } Ptype tok_to_type(TOK b) { Ptype t; switch (b) { case CHAR: t = char_type; break; case SHORT: t = short_type; break; case LONG: t = long_type; break; case VLONG: t = vlong_type; break; case UNSIGNED: t = uint_type; break; case FLOAT: t = float_type; break; case DOUBLE: t = double_type; break; case LDOUBLE: t = ldouble_type; break; case VOID: t = void_type; break; default: error("illegalK:%k",b); case INT: t = int_type; } return t; } Pbase defa_type; Pbase moe_type; Pexpr dummy; Pexpr zero; Pclass ccl; //SYM -- tn stuff removed Plist local_class = 0; //SYM -- preserve for use in del.c void memptrdcl(Pname bn, Pname tn, Ptype ft, Pname n) { Pptr p = new ptr(PTR,0); p->memof = Pclass(Pbase(bn->tp)->b_name->tp); Pbase b = new basetype(TYPE,tn); PERM(p); Pfct f = Pfct(ft); Ptype t = n->tp; if (t) { p->typ = t; ltlt: switch (t->base) { case PTR: case RPTR: case VEC: if (Pptr(t)->typ == 0) { Pptr(t)->typ = b; break; } t = Pptr(t)->typ; goto ltlt; default: error('s',"P toMFT too complicated"); } } else p->typ = b; f->returns = p; n->tp = f; }