/*ident "@(#)cls4:src/cfront.h 1.28" */ /******************************************************************************* 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. * Here are all the class definitions for cfront, and most of the externs *******************************************************************************/ #ifndef _CFRONT_H #define _CFRONT_H #include "token.h" #include "typedef.h" #ifndef GRAM extern char* prog_name; // compiler name and version extern int inline_restr; // inline expansion restrictions #endif extern TOK tlex(); extern Pname syn(); extern void ext(int); extern Ptype unconst_type(Ptype); extern char* make_name(TOK); extern char* make_nested_name(char*,Pclass); extern void make_dummy(); extern Pname dummy_fct; extern Pname really_dominate(Pname, Pname, bit); extern int exact1(Pname, Ptype); extern int exact2(Pname, Ptype); extern int exact3(Pname, Ptype); extern char* strdup(const char*); extern int friend_check(Pclass start,Pclass stop, Pfct f); struct loc // a source file location { short file; // index into file_name[], or zero short line; #ifndef GRAM void put(FILE*); void putline(); #endif }; extern Loc curloc; extern int curr_file; extern char* curr_filename(); extern char* src_file_name; extern loc noloc; // dummy null location extern bit binary_val; extern bit stmtno; extern Ptable tmp_tbl; extern Ptable bound_expr_tbl; struct ea { // fudge portable printf-like formatting for error() union { const void* p; long i; }; ea(const void* pp) {p = pp;} ea(long ii) { i = ii; } ea() {} }; extern ea* ea0; int error(const char*); int error(const char*, const ea&, const ea& = *ea0, const ea& = *ea0, const ea& = *ea0); int error(int, const char*); int error(int, const char*, const ea&, const ea& = *ea0, const ea& = *ea0, const ea& = *ea0); int error(loc*, const char*, const ea& = *ea0, const ea& = *ea0, const ea& = *ea0, const ea& = *ea0); int error(int, loc*, const char*, const ea& = *ea0, const ea& = *ea0, const ea& = *ea0, const ea& = *ea0); extern char emode; extern int error_count; extern int vtbl_opt; extern int debug_opt; extern int warning_opt; extern int ansi_opt; extern int pt_opt; extern int perf_opt; extern int dtpt_opt; extern int se_opt; extern int strict_opt; extern FILE* out_file; extern FILE* pt_file; extern FILE* dtpt_file; extern char scan_started; extern int bl_level; //SYM Tables replacing the ktbl extern Pktab Gtbl; //SYM global parsing table extern Pktab Ctbl; //SYM current parsing table //SYM Ctbl is also set during dcl for accurate TNAME lookup. //SYM This is ok since parsing and dcl are disjoint operations. extern Pname k_find_name( char*, Pktab, TOK ); extern Pname k_find_member( char*, Pclass, TOK ); extern Pname insert_type( Pname, Pktab, TOK ); extern Pname insert_name( Pname, Pktab ); extern Ptable gtbl; // global names extern Ptable ptbl; extern char* oper_name(TOK); extern char* name_oper(char *); extern int is_probably_temp(char*); extern Pname def_name; extern Pname pdef_name; extern Pclass ccl; extern Pbase defa_type; extern Pbase moe_type; extern Pbase mptr_type; #ifndef GRAM extern Pstmt Cstmt; // current statement, or 0 extern Pname Cdcl; // name currently being declared, or 0 extern int largest_int; #endif extern Pbase any_type; extern Pbase int_type; extern Pbase char_type; extern Pbase short_type; extern Pbase long_type; extern Pbase uint_type; extern Pbase float_type; extern Pbase double_type; extern Pbase ldouble_type; extern Pbase void_type; #ifndef GRAM extern Pbase uchar_type; extern Pbase ushort_type; extern Pbase ulong_type; extern Ptype Pchar_type; extern Ptype Pint_type; extern Ptype Pvptr_type; extern Ptype Pfctvec_type; extern Ptype Pvoid_type; extern Pbase zero_type; extern Ptype size_t_type; extern int byte_offset; extern int bit_offset; extern int max_align; extern int const_save; extern bit const_problem; #endif extern Pexpr dummy; /* the empty expression */ extern Pexpr zero; extern Pexpr one; extern Pname sta_name; /* qualifier for unary :: */ #define DEL(p) if (p && (p->permanent==0)) p->del() #define PERM(p) p->permanent=1 #define UNPERM(p) p->permanent=0 struct node { TOK base; bit permanent; bit baseclass; // base classes have NAME in their base ... #ifdef DBG bit displayed; // avoid infinite recursion in display functions bit allocated; // set when not on free list long id; #endif }; #ifdef DBG extern long node_id; extern int Adebug; #define DBID() { node::id = ++::node_id; node::allocated=1; displayed=0; \ if(Adebug>=1)fprintf(stderr,"\n*** allocated %d base %d\n",id,base); } #else #define DBID() /**/ #endif struct table : public node { /* a table is a node only to give it a "base" for debugging */ bit init_stat; /* ==0 if block(s) of table not simplified, ==1 if simplified but had no initializers, ==2 if simplified and had initializers. */ TOK t_realbase; // is this part of a ktable? short size; short hashsize; short free_slot; /* next free slot in entries */ Pname* entries; short* hashtbl; Pstmt real_block; /* the last block the user wrote, not one of the ones cfront created */ Ptable next; /* table for enclosing scope */ Pname t_name; /* name of the table */ static Ptable table_free; void* operator new(size_t); void operator delete(void*,size_t); table(short, Ptable, Pname); ~table(); Pname look(char*, TOK); Pname insert(Pname, TOK); inline Pname insert_copy(Pname, TOK); void reinit(); #ifndef GRAM void grow(int); void set_name(Pname n) { t_name = n; }; int max() { return free_slot-1; }; void dcl_print(TOK,TOK); #endif // return a pointer to the i'th entry, or 0 if it does not exist Pname get_mem(int i) { return (i<=0 || free_slot<=i) ? 0 : entries[i]; } void del(); char* whatami(); #ifdef DBG void dump( int verbose = 1 ); #endif }; #define NEXT_NAME(tbl,n,i) (n = (n->n_tbl_list ? n->n_tbl_list : tbl->get_mem(++i))) struct ktable : public node { //SYM parsing table /* a ktable is a node only to give it a "base" for debugging */ union { Ptable k_t; // hash table Pname k_n; // list of names for tiny tables such as arg lists }; short k_size; // if k_tiny, number of names in small table bit k_tiny; // set when table is small (not hash table) TOK k_id; // ARG CLASS BLOCK TEMPLATE 0 Pktab k_next; // table for enclosing scope Pname k_name; // name of table ktable(int, Pktab, Pname); ~ktable(); static Pktab table_free; void* operator new(size_t); void operator delete(void*,size_t); Pname look(char*, TOK); Pname insert(Pname, TOK); Pname find_cn(char*); // find name of this class table void expand(int);// expand tiny table to hash table void hoist(); // hoist names in this table to enclosing table Pname get_mem(int); void del(); char* whereami(); // return name or description of table }; #ifndef GRAM extern bit Nold; extern bit vec_const, fct_const; #endif //SYM -- tn stuff removed // local class extern Plist local_class; //SYM -- preserve for use in del.c extern char *make_local_name(Ptype, Pname); // nested type extern Pname curr_fct; extern Pname start_cl(TOK, Pname, Pbcl); extern void end_cl(); extern Pbase end_enum(Pname, nlist*); /************ types : basic types, aggregates, declarators ************/ #ifndef GRAM extern bit new_type; extern Pname cl_obj_vec; extern Pname eobj; #endif #define DEFINED 01 /* definition fed through ?::dcl() */ #define SIMPLIFIED 02 /* in ?::simpl() */ #define DEF_SEEN 04 /* definition seen, but not processed */ #define REF_SEEN 010 /* reference seen (classdef) */ /* used for class members in norm.c */ #define IN_ERROR 020 #define TNAME_SEEN 040 /* used in typedef TNAME name */ #define COPIED 0100 /* used by copy_walker in tree_copy.c */ enum Templ_type { VANILLA, FCT_TEMPLATE, CL_TEMPLATE, BOUND_TEMPLATE, INSTANTIATED, UNINSTANTIATED }; struct type : public node { bit defined; /* flags DEF_SEEN, DEFINED, SIMPLIFIED, IN_ERROR not used systematically yet */ bit lex_level; Templ_type templ_base; // CL_TEMPLATE(specialization) or BOUND_TEMPLATE Pclass in_class; // nested type Pname in_fct; char *nested_sig; char *local_sig; bit b_const; bit ansi_const; // turns off constness when print ansi C char *signature(char*,int=0); Ptype tlist; bit check(Ptype, TOK, bit=0); Ptype mkconst(); // encapsulate casts Pclass classtype(); inline Penum enumtype(); inline Ptype bname_type(); inline Pname bname(); inline bit is_templ_instance(); Ptype skiptypedefs(); // skip over typedef's Ptype skiptypedefs(bit &isconst); // same, but `OR' b_const's in isconst #ifndef GRAM void print(); void dcl_print(Pname); void base_print(); Pptr is_ref(); Pptr is_ptr(); Pptr is_ptr_or_ref(); bit is_unsigned(); void dcl(Ptable); int tsizeof(int = 0); bit tconst(); bit is_const_object(); TOK set_const(bit); int align(); TOK kind(TOK,TOK,bit=1); TOK integral(TOK oo) { return kind(oo,'I'); }; TOK numeric(TOK oo) { return kind(oo,'N'); }; TOK num_ptr(TOK oo) { return kind(oo,'P'); }; bit vec_type(); Ptype deref(); inline Pptr addrof(); inline bit is_or_pts_to(TOK); Pfct memptr(); #endif Pname is_cl_obj(); /* sets cl_obj_vec */ void del(); }; struct enumdef : public type { /* ENUM */ bit e_body; short no_of_enumerators; unsigned short e_strlen; // strlen(string) or strlen(local_sig) char* string; // name of enum Pname mem; Pbase e_type; // type representing the enum enumdef(Pname n) { base=ENUM; mem=n; }; #ifndef GRAM void print(); void dcl_print(Pname); void dcl(Pname, Ptable); void simpl(); #endif }; struct velem { Pname n; int offset; }; struct virt : public node { Pvirt next; int n_init; velem* virt_init; // vector of vtbl initializers (zero-terminated) Pclass vclass; // for class vclass char* string; bit is_vbase; // vtable for virtual base bit printed; virt(Pclass cl, velem* v, char* s, bit flag, int ni) {base = XVIRT; vclass=cl; virt_init=v; string=s; is_vbase=flag; next=0; n_init = ni;} }; enum { C_VPTR=1, C_XREF=2, C_ASS=4, C_VBASE=8, C_REFM=16 }; typedef class cons *Pcons; typedef class basic_template *Ptempl_base; struct classdef : public type { /* CLASS */ Templ_type class_base; /* recognize template classes */ bit c_body; /* print definition only once */ TOK csu; /* CLASS, STRUCT, UNION, or ANON */ bit obj_align; bit c_xref; // 1 set: has vptr(s) // 2 set: X(X&) exists // 4 set: operator=(X&) exists // 8 set: has vbaseptr(s) // 16 set: has reference data member(s) short virt_count; // number of virtual functions // starting at max base class virt_count in bit virt_merge; // set when no virtual functions, but // need to merge virtual base classes bit has_vvtab; // set if class has vtable from virtual base unsigned short c_strlen;// strlen(string) or strlen(local_sig) Pbcl baselist; // list of base classes char* string; /* name of class */ Pname c_abstract; // abstract class: don't instantiate: virt func name Pname mem_list; Ptable memtbl; Pktab k_tbl; //SYM parsing table Ptable c_context; int obj_size; int real_size; /* obj_size - alignment waste */ Pcons templ_friends; /* list of template friends: template friend ... */ Plist friend_list; Pname pubdef; Ptype this_type; Pvirt virt_list; // vtbl initializers Pname c_ctor; // constuctor: possibly overloaded Pname c_dtor; // destructor Pname c_itor; /* constructor X(X&) */ Pname c_vtor; /* x::x() ctor for vec_new */ Pname conv; /* operator T() chain */ struct toknode *c_funqf, *c_funqr; // token Q for parsing function defs after class def classdef(TOK); ~classdef(); TOK is_simple() { return (csu==CLASS)?0:csu; }; bit same_class(Pclass p,int=0); #ifndef GRAM void print(); void dcl_print(Pname); void simpl(); void print_members(); void dcl(Pname, Ptable); void make_vec_ctor(Pname); // bit has_friend(Pname); bit has_friend(Pclass); bit has_friend(Pfct); bit has_base(Pclass cl,int level=0,int ccflag=0); bit baseof(Pname); bit baseof(Pclass); Pclass is_base(char*,TOK* =0,int level=0); Pname has_oper(TOK); Pname has_ctor() { return c_ctor; } Pname has_dtor() { return c_dtor; } Pname has_itor() { return c_itor; } Pname has_vtor() { return c_vtor; } Pname has_ictor(); Pname make_itor(int); Pexpr find_name(char*, Pclass, int=0, int=0); int do_virtuals(Pvirt, char*, int, bit); int all_virt(Pclass, char*, int, bit); void add_vtbl(velem*, char*, bit, int); void print_all_vtbls(Pclass); void print_vtbl(Pvirt); void really_print(Pvirt); int check_dup(Pclass, TOK); int has_allocated_base(Pclass,bit=0); char *has_allocated_base(char*); int get_offset(char*,bit=0); Pbcl get_base(char*); Pexpr get_vptr_exp(char*); Pexpr find_in_base(char*, Pclass, int, int=0); void modify_inst_names(char *s); // Adjust ctor names for instantiation bit parametrized_class(); bit has_const_mem(); #endif }; inline int same_class (Pclass c1, Pclass c2, int dummy=0) { // this function does the trick of comparing two classes in a // templatized scenerio, so, any usage of comparing two classes should // call this function, instead of doing " c1 == c2 " . return (c1==c2 ? 1 : c1->same_class(c2, dummy) ); } #ifndef GRAM class clist { Pclass cl; clist* next; public: clist(Pclass c, clist* n) { cl=c; next=n; } int onlist(Pclass); void clear(); }; extern clist * vcllist; struct vl { struct vl* next; Pvirt vt; classdef* cl; vl(classdef* c, Pvirt v, struct vl* n) { cl = c; vt = v; next = n; } }; extern vl* vlist; extern int nin; extern int Noffset; extern TOK Nvis; extern TOK Nvirt; extern Pexpr Nptr; extern Pbcl Nvbc_alloc; extern char *Nalloc_base; extern Pexpr rptr(Ptype,Pexpr,int); extern Pexpr vbase_args(Pfct, Pname); extern Pexpr cdvec(Pname,Pexpr,Pclass,Pname,int,Pexpr,Pexpr=0); extern Pexpr mk_zero_init(Ptype,Pname,Pname); extern Pexpr find_name(Pname, Pclass, Ptable, int, Pname); extern Pname find_virtual(Pclass,Pname); extern Pname vfct(Pclass, char*); extern int Vcheckerror; extern int ignore_const; extern int mex; extern Pclass mec; extern Pclass tcl; extern int processing_sizeof; // suppresscertain referencing errors for args to sizeof #endif struct basetype : public type /* ZTYPE CHAR SHORT INT LONG FLOAT DOUBLE FIELD EOBJ COBJ TYPE ANY */ /* used for gathering all the attributes for a list of declarators ZTYPE is the (generic) type of ZERO ANY is the generic type of an undeclared name */ { bit b_unsigned; bit b_signed; bit b_volatile; bit b_typedef; bit b_inline; bit b_virtual; bit b_short; bit b_long; bit b_bits; /* number of bits in field */ bit b_offset; // bit offset of field TOK b_sto; /* AUTO STATIC EXTERN REGISTER 0 */ Pname b_name; /* name of non-basic type */ Ptable b_table; /* memtbl for b_name, or 0 */ Pname b_xname; /* extra name */ union { Ptype b_fieldtype; char* b_linkage; }; basetype(TOK, Pname); Pbase type_adj(TOK); Pbase base_adj(Pbase); Pbase name_adj(Pname); Pname aggr(); Pbase check(Pname); #ifndef GRAM void dcl_print(); Pbase arit_conv(Pbase); bit parametrized_class(); #endif int discriminator(int); // union discriminator fcn }; enum Linkage { linkage_default, linkage_C, linkage_Cplusplus }; extern Linkage linkage; void set_linkage(char*); struct fct : public type { // FCT Templ_type fct_base; // recognize template function TOK nargs; // count of arguments TOK nargs_known; // 0 if unknown, 1 if known, or ELLIPSIS bit last_stmt; bit f_vdef; // 1 if this is the first virtual definition // of this function bit f_inline; // 1 if inline, 2 if being expanded, else 0 bit f_is_inline; // because f_inline is set to 0 // before laying down static version of inline bit f_const; // one if member function that may be called for // a const object, else 0 bit f_static; // 1 if static member function, else 0 short f_virtual; // index in virtual table, or 0 meaning non-virtual short f_imeasure; // some measure of the size of an inline function Ptype returns; Pname argtype; Ptype s_returns; Pname f_this; Pclass memof; // member of class memof Pclass def_context; // defined in def_context (as for friends) Pblock body; Pname f_init; // base and member initializers Pexpr f_expr; // body expanded into an expression Pexpr last_expanded; Pname nrv; // named return value name Pname f_result; // extra second argument of type X& Pname f_args; // argument list including args added by cfront Linkage f_linkage; char* f_signature; // character encoding of function type Plist local_class; // list of local classes //SYM -- preserve for use in del.c static Pfct fct_free; void* operator new(size_t); void operator delete(void*,size_t); fct(Ptype, Pname, TOK); void argdcl(Pname,Pname); #ifndef GRAM Ptype normalize(Ptype); void arg_print(); void dcl_print(); void dcl(Pname); Pexpr base_init(Pclass, Pexpr, Ptable, int); Pexpr mem_init(Pname, Pexpr, Ptable); void init_bases(Pclass, Pexpr); bit declared() { return nargs_known; }; void simpl(); int ctor_simpl(Pclass, Pexpr); Pstmt dtor_simpl(Pclass, Pexpr); Pexpr expand(Pname,Ptable,Pexpr); void sign(); int is_templ() { return fct_base != VANILLA; } #endif int discriminator(int); // union discriminator fcn }; struct name_list : public node { Pname f; Plist l; name_list(Pname ff, Plist ll); }; #ifndef GRAM enum gen_types { no_templ, some_templ, all_templ }; struct gen : public type { // OVERLOAD Plist fct_list; gen_types holds_templ; // does fct_list hold a template? gen() { base = OVERLOAD; } Pname add(Pname); Pname find(Pfct, bit); Pname match(Pname, Pfct, bit); Pname exactMatch(Pexpr, int); Pname oneArgMatch(Pexpr, int); Pname multArgMatch(Pexpr, int); int has_templ() { return holds_templ != no_templ; } int pure_templ() { return holds_templ == all_templ; } }; #endif struct pvtyp : public type { Ptype typ; }; struct vec : public pvtyp // VEC // typ [ dim ] { Pexpr dim; int size; static Pvec vec_free; void* operator new(size_t); void operator delete(void*,size_t); vec(Ptype t, Pexpr e) { base=VEC; typ=t; dim=e; DBID(); } #ifndef GRAM Ptype normalize(Ptype); #endif }; struct ptr : public pvtyp // PTR, RPTR i.e. reference { Pclass memof; // pointer to member of memof: memof::* Pname ptname; // template class: T::*, adjusted in type::dcl static Pptr ptr_free; void* operator new(size_t); void operator delete(void*,size_t); ptr(TOK b, Ptype t) { base=b; typ=t; DBID(); } #ifndef GRAM Ptype normalize(Ptype); #endif }; #ifndef GRAM inline Pptr type::addrof() { return new ptr(PTR,this); } inline bit type::is_or_pts_to(TOK k) { Ptype t = skiptypedefs(); if (t->base == PTR) t = Pptr(t)->typ->skiptypedefs(); return (t->base == k) ? 1 : 0; } #endif /****************************** constants ********************************/ /* STRING ZERO ICON FCON CCON ID */ /* IVAL FVAL LVAL */ /***************************** expressions ********************************/ #ifndef GRAM extern Pexpr next_elem(); extern void new_list(Pexpr); extern void list_check(Pname, Ptype, Pexpr, Ptable=0); extern Pexpr ref_init(Pptr,Pexpr,Ptable); extern Pexpr class_init(Pexpr,Ptype,Pexpr,Ptable); extern Pexpr check_cond(Pexpr, TOK, Ptable); extern Pexpr ptof(Pfct,Pexpr,Ptable); extern void dosimpl(Pexpr, Pname); extern int ref_initializer; extern int ntok; extern void ptbl_init(int); extern void ptbl_add_pair(char*,char*); extern char *ptbl_lookup(char*); extern char *st_name(char*); #endif struct expr : public node /* PLUS, MINUS, etc. */ /* IMPORTANT: all expressions are of sizeof(expr) */ /* DEREF => *e1 (e2==0) OR e1[e2] UMINUS => -e2 INCR (e1==0) => ++e2 INCR (e2==0) => e1++ CM => e1 , e2 ILIST => LC e1 RC (an initializer list) a Pexpr may denote a name */ { union { Ptype tp; char *string4; }; union { Pexpr e1; long i1; char* string; }; union { Pexpr e2; int i2; char* string2; Pexpr n_initializer; Ptype tpdef; // local and nested typedef info }; union { /* used by the derived classes */ Ptype tp2; Pname fct_name; // of a call expr Pexpr cond; Pexpr mem; Ptype as_type; Ptable n_table; Pin il; Pname query_this; }; static Pexpr expr_free; void* operator new(size_t); void operator delete(void*,size_t); expr(TOK, Pexpr, Pexpr); void del(); #ifndef GRAM void print(); Pexpr typ0(Ptable); Pexpr typ(Ptable); long eval(); unsigned long ueval(long,long); int lval(TOK); Ptype call_fct(Ptable); Pexpr address(); Pexpr contents(); void simpl(); Pexpr expand(); bit not_simple(int inflag=0); bit is_const_obj(); Pexpr oper_overload(Ptable); Pexpr docast(Ptable); Pexpr dovalue(Ptable); Pexpr donew(Ptable); void simpl_new(); void simpl_delete(); #endif int discriminator(int); // union discriminator fcn }; struct texpr : public expr { // G_CAST, CAST NEW VALUE (also ICALL) texpr(TOK bb, Ptype tt, Pexpr ee) : expr (bb,ee,0) { tp2=tt; } }; struct cast : public expr { // G_CAST cast(Ptype tt, Pexpr ee) : expr (G_CAST,ee,0) { tp=tp2=tt; } }; struct ival : public expr { // IVAL ival(long ii) : expr (IVAL,0,0) { i1 = ii;} }; struct call : public expr { // CALL call(Pexpr aa, Pexpr bb) : expr (CALL,aa,bb) { } #ifndef GRAM void simpl(); Pexpr expand(Ptable); #endif }; struct qexpr : public expr { // QUEST cond ? e1 : e2 qexpr(Pexpr ee, Pexpr ee1, Pexpr ee2) : expr (QUEST,ee1,ee2) { cond=ee; } }; struct ref : public expr { // REF DOT e1->mem OR e1.mem ref(TOK ba, Pexpr a, Pexpr b) : expr (ba,a,0) { mem=b; } }; struct mdot : public expr { // MDOT a.b mdot(char* a, Pexpr b) : expr (MDOT,0,0) { string2=a; mem=b; } }; struct text_expr : public expr { // TEXT (vtbl_name) text_expr(char* a, char* b) : expr (TEXT,0,0) { string=a; string2=b; } }; extern char* vtbl_name(char*,char*); /************************* names (are expressions) ****************************/ struct basecl : public node { // NAME => base class // VIRTUAL => virtual base class TOK ppp; // private / public / protected bit allocated; // allocated virtual base bit promoted; // non-explicit, promoted virtual base Pclass bclass; Pexpr init; // base class initializers for ctors int ptr_offset; // pointer's relative position in derived class int obj_offset; // object's relative position in derived class Pname* virt_init; // vector of vtbl table initializers basecl* next; basecl(Pclass cl, basecl* n) { baseclass=1; bclass=cl; next=n; promoted=0; init=0;} }; enum template_formal_types { template_type_formal =1 , template_expr_formal, template_actual_arg_dummy // used during the parse }; extern TOK ppbase; struct name : public expr { // NAME TNAME DTOR and the lexical keywords TOK n_oper; // name of operator or 0 TOK n_sto; // EXTERN STATIC AUTO REGISTER ENUM 0 TOK n_stclass; // STATIC AUTO REGISTER 0 TOK n_scope; // EXTERN STATIC FCT ARG PUBLIC 0 TOK n_key; /* for names in table: class */ bit n_evaluated; // 0 or n_val holds the value bit n_xref; // argument of type X(X&) unsigned char lex_level; TOK n_protect; // PROTECTED (<=>n_scope==0) or 0 bit n_dcl_printed; // 1: declaration printed // 2: definition printed // 0: declaration not printed // if this is set it implies that n_template_arg == template_type_formal char n_template_arg; // One of template_formal_types for template arguments bit n_template_fct; // non-class template function bit n_redefined ; // set only for PT function names && classes // where an explict definition was provided. short n_addr_taken; short n_used; short n_assigned_to; Loc where; int n_offset; // byte offset in frame or struct char* n_anon; // 0, or anon union object name union {//SYM ??? Pname n_list; // next name in arg or other list Pname n_hidden; //SYM type name hidden by this name in parse table Pname n_dtag; // base==DTOR -- name after ~ or 0 for basic type dtor }; Pname n_tbl_list; char *n_gen_fct_name; // used to be punned with n_tbl_list. char *n_template_arg_string ; // the mangled string name Pktab n_ktable;//SYM parsing table in which name is entered union { /* * n_qualifier: name of containing class * n_realscope: for labels (always entered in function table) * the table for the actual scope in which label occurred. * syn_class: lex table only */ Pname n_qualifier; Ptable n_realscope; int syn_class; }; /* n_val: the value of n_initializer */ long n_val; /* for inlines, the number of the argument when base == ANAME */ int argno; static Pname name_free; void* operator new(size_t); void operator delete(void*,size_t); name(char* =0); Pname normalize(Pbase, Pblock, bit); Pname tdef(); Pname tname(TOK); void hide(); #ifndef GRAM Pname dcl(Ptable,TOK); int no_of_names(); void use() { n_used++; }; void assign(); void take_addr(); void check_oper(Pname); void simpl(); void print(bit fullprint=0); void dcl_print(TOK); void field_align(); Pname dofct(Ptable,TOK); inline Pfct get_fct(); bit is_template_fct() { return n_template_fct; } bit inst_body(); bit finst_body(); bit dinst_body(); #endif // this works only for function templates which require type formals bit is_template_arg() { return n_template_arg == template_type_formal; } void del(); inline Pfct fct_type(); int discriminator(int); // union discriminator fcn }; extern int friend_in_class; extern int in_class_dcl; // from parser extern int in_class_decl; extern int parsing_class_members; extern int in_mem_fct; extern int in_arg_list; extern Ptype in_typedef; extern int defer_check; // redefinition typedef check delay extern int declTag; // !1: inline, virtual mod permitted extern Pname in_tag; extern int DECL_TYPE; /******************** statements *********************************/ struct stmt : public node { /* BREAK CONTINUE DEFAULT */ /* IMPORTANT: all statement nodes have sizeof(stmt) */ Pstmt s; Pstmt s_list; Pstmt gt; Loc where; union { Pname d; // goto/block -- destination Pexpr e2; // for iteration Pstmt has_default; // switch statement default int case_value; Ptype ret_tp; // pair }; union { Pexpr e; bit own_tbl; Pstmt s2; }; Ptable memtbl; Pktab k_tbl; //SYM parsing table union { Pstmt for_init; Pstmt else_stmt; Pstmt case_list; Loc where2; // location of } at end of block // in DO loops, location of conditional }; static Pstmt stmt_free; void* operator new(size_t); void operator delete(void*,size_t); stmt(TOK, loc, Pstmt); void del(); #ifndef GRAM void print(); void dcl(int forflag=0); void dcl1(Pstmt&); void reached(); Pstmt simpl(); Pstmt expand(); Pstmt copy(); // PAIR and BLOCK pun on `e': if (s->e) not safe bit has_expr() { return (base != BLOCK && base != PAIR)?e!=0:0; } #endif int discriminator(int); // union discriminator fcn }; #ifndef GRAM extern char* Neval; extern Ptable scope; extern Ptable expand_tbl; extern Pname expand_fn; #endif struct estmt : public stmt /* SM WHILE DO SWITCH RETURN CASE */ /* SM (e!=0) => e; in particular assignments and function calls SM (e==0) => ; (the null statement) CASE => case e : s ; SM_PARAM => e is the template_statement_tree_formal name */ { estmt(TOK t, loc ll, Pexpr ee, Pstmt ss) : stmt (t,ll,ss) { e=ee;} }; struct ifstmt : public stmt /* IF */ // else_stmt==0 => if (e) s // else_stmt!=0 => if (e) s else else_stmt { ifstmt(loc ll, Pexpr ee, Pstmt ss1, Pstmt ss2) : stmt (IF,ll,ss1) { e=ee; else_stmt=ss2; }; }; struct lstmt : public stmt /* LABEL GOTO */ /* d : s goto d */ { lstmt(TOK bb, loc ll, Pname nn, Pstmt ss) : stmt (bb,ll,ss) { d=nn; } }; struct forstmt : public stmt { // FOR forstmt(loc ll, Pstmt fss, Pexpr ee1, Pexpr ee2, Pstmt ss) : stmt (FOR,ll,ss) { for_init=fss; e=ee1; e2=ee2; } }; struct block : public stmt { // BLOCK { d s } block(loc ll, Pname nn, Pstmt ss, loc rr = noloc ) : stmt (BLOCK,ll,ss) { d=nn; where2=rr; } #ifndef GRAM void dcl(Ptable); Pstmt simpl(); #endif }; struct handler : public stmt { // not implemented -- currently set to BLOCK handler( Pstmt tt, Pstmt hh ) : stmt (BLOCK,tt?tt->where:curloc,tt) { d=0; s->s_list=hh; where2=curloc; } }; #ifndef GRAM struct pair : public stmt { // PAIR pair(loc ll, Pstmt a, Pstmt b) : stmt (PAIR,ll,a) { s2 = b; } }; #endif struct nlist { Pname head; Pname tail; nlist(Pname); void add(Pname n) { tail->n_list = n; tail = n; }; void add_list(Pname); }; extern Pname name_unlist(nlist*); struct slist { Pstmt head; Pstmt tail; slist(Pstmt s) { /*Nl++;*/ head = tail = s; }; void add(Pstmt s) { tail->s_list = s; tail = s; }; }; extern Pstmt stmt_unlist(slist*); struct elist { Pexpr head; Pexpr tail; elist(Pexpr e) { /*Nl++;*/ head = tail = e; }; void add(Pexpr e) { tail->e2 = e; tail = e; }; }; extern Pexpr expr_unlist(elist*); #ifndef GRAM extern class dcl_context * cc; #define MAXCONT 100 extern dcl_context ccvec[MAXCONT]; struct dcl_context { Pname c_this; /* current fct's "this" */ Ptype tot; /* type of "this" or 0 */ Pname not; /* name of "this"'s class or 0 */ Pclass cot; /* the definition of "this"'s class */ Ptable ftbl; /* current fct's symbol table */ Pname nof; /* current fct's name */ void stack() { cc++; cc >= &ccvec[MAXCONT] ? error('i', "ccvec buffer overflow") : 0; *cc = *(cc-1); }; void unstack() { cc--; }; }; #endif extern void yyerror(const char*); #ifndef GRAM extern char* line_format; extern Plist stat_mem_list; extern Plist isf_list; extern Pstmt st_ilist; extern Pstmt st_dlist; extern Ptable sti_tbl; extern Ptable std_tbl; extern int need_sti( Pexpr e, Ptable tbl = 0, bit is_static_ok = 0 ); Pexpr try_to_coerce(Ptype, Pexpr, char*, Ptable); extern bit can_coerce(Ptype, Ptype); extern Ptype np_promote(TOK, TOK, TOK, Ptype, Ptype, TOK, bit=1); extern bit enum_promote; extern int suppress_error; extern void delete_local(); extern int over_call(Pname, Pexpr); extern Pname overFound; extern Pname Nover; extern Pname Ncoerce; extern int Nover_coerce; struct ia : public node { Pname local; // local variable for argument Pexpr arg; // actual arguments for call Ptype tp; // type of formal argument ia() { base = XIA; }; }; struct iline : public node { Pname fct_name; /* fct called */ Pin i_next; Ptable i_table; int i_slots; // no of arg slots pointer to by i_args ia* i_args; iline() { base = XILINE; }; }; struct con_dtor { Pname tn; Pexpr condition; con_dtor *next; con_dtor(Pname n, Pexpr e) : tn(n), condition(e), next(0) {} }; extern con_dtor *pdlist; extern Pexpr curr_expr; extern Pin curr_icall; #define FUDGE111 11111 #define VTOK 22222 #define ITOR 77 extern Pstmt curr_loop; extern Pblock curr_block; extern Pstmt curr_switch; extern loc last_line; // last #line + number of '\n's output since extern int last_ll; // 0 or line of current stmt/dcl being printed extern FILE* out_file; // output file descriptor extern bit Cast; extern bit TCast; extern bit simpl_friend; // are we simplifying a friend function extern bit in_return; // are we calling ref_init with a RETURN extern loc no_where; extern long str_to_long(const char*); extern int c_strlen(const char* s); #endif #ifndef GRAM extern Pname vec_new_fct; extern Pname new_fct; extern Pname del_fct; extern Pname vec_del_fct; extern int Nstd; // standard coercion used (derived* =>base* or int=>long or ...) extern int stcount; // number of names generated using make_name() Pexpr replace_temp(Pexpr,Pexpr); void make_res(Pfct); extern int Pchecked; Pexpr ptr_init(Pptr,Pexpr,Ptable); Pexpr call_ctor(Ptable, Pexpr p, Pexpr ctor, Pexpr args, int d = REF, Pexpr vb_args = 0); Pexpr call_dtor(Pexpr p, Pexpr dtor, Pexpr arg = 0, int d = DOT, Pexpr vb_args = 0); void check_visibility(Pname, Pname, Pclass, Ptable, Pname); int make_assignment(Pname); extern Pname make_tmp(char, Ptype, Ptable); Pexpr init_tmp(Pname, Pexpr, Ptable); extern Pname Ntmp; extern Pname Ntmp_refd; extern Pname Ntmp_flag; extern Pexpr Ntmp_dtor; extern int is_unique_base(Pclass, char*, int, int = 0, Pclass priSeen = 0); extern Pexpr rptr(Ptype, Pexpr, int); extern int read_align(char*); extern void new_init(); extern void Eprint(Pexpr); extern Pexpr cast_cptr(Pclass ccl, Pexpr ee, Ptable tbl, int real_cast); extern Pexpr mptr_assign(Pexpr,Pexpr); extern Pclass Mptr; #endif extern bit fake_sizeof; // suppress error message for ``int v[];'' extern TOK lalex(); // encapsulate casts inline Pname type::bname() { return Pbase(this)->b_name; } inline Ptype type::bname_type() { return Pbase(this)->b_name->tp; } //move to typ.c because 2.0 bug /* inline Pclass type::classtype() { return (base==COBJ)?Pclass(Pbase(this)->b_name->tp) : (error('i',"T::classtype(): %k cobjX",base),0); } */ inline Penum type::enumtype() { return (base==EOBJ)?Penum(Pbase(this)->b_name->tp) : (error('i',"T::enumtype(): %k eobjX",base),Penum(0)); } inline Pfct name::fct_type() { return (tp->base==FCT) ? Pfct(tp) : (error('i',"N::fct_type():%n is %k notF",this,tp->base),Pfct(0)); } inline bit type::is_templ_instance() { Templ_type t = (base==FCT) ? Pfct(this)->fct_base : (base==CLASS) ? Pclass(this)->class_base : (Templ_type)0; return (t==INSTANTIATED || t==UNINSTANTIATED); } #ifndef GRAM inline Pfct name::get_fct() { return (tp->base==FCT) ? Pfct(tp) : Pfct(Pgen(tp)->fct_list->f->tp); } inline Pname table::insert_copy(Pname n, TOK k) { Pname nn = new name; *nn = *n; nn->n_table = 0; nn->n_tbl_list = 0; return insert(nn,k); } #endif #ifdef DBG extern "C" { extern void display_expr( Pexpr, char* = 0, int = 0 ); extern void display_stmt( Pstmt, char* = 0, int = 0 ); extern void display_type( Ptype ); extern void display_namelist( Plist, char* = 0, int = 0 ); #ifndef GRAM extern void display_context( dcl_context*, char* = "", int = 0 ); #endif extern void process_debug_flags( char* ); } #define DB(a) if(scan_started){a;} extern int Adebug; // allocation (ctor/del) debugging extern int Bdebug; // table.c debugging extern char* Bdebarg; // arg for B flag extern int Ddebug; // dcl debugging extern int Edebug; // expr debugging extern int Kdebug; // parsing table debugging extern int Ldebug; // lex/lalex debugging extern int Mdebug; // trace function matching extern int Ndebug; // norm debugging extern int Pdebug; // print debugging extern int Rdebug; // run() debugging extern int Sdebug; // simpl debugging extern int Tdebug; // typ debugging #define Ydebug yydebug extern int Ydebug; // yacc debugging #else #define DB(a) /**/ #endif #endif /* end */