// Copyright (C) 1985-1995 by Symantec // Copyright (C) 2000-2011 by Digital Mars // All Rights Reserved // http://www.digitalmars.com // Written by Walter Bright /* * This source file is made available for personal use * only. The license is in /dmd/src/dmd/backendlicense.txt * or /dm/src/dmd/backendlicense.txt * For any other uses, please contact Digital Mars. */ /* Routines to handle elems. */ #if __SC__ #pragma once #endif #ifndef EL_H #define EL_H 1 /****************************************** * Elems: * Elems are the basic tree element. They can be either * terminal elems (leaves), unary elems (left subtree exists) * or binary elems (left and right subtrees exist). */ struct elem { #ifdef DEBUG unsigned short id; #define IDelem 0x4C45 // 'EL' #define elem_debug(e) assert((e)->id == IDelem) #else #define elem_debug(e) #endif unsigned char Eoper; // operator (OPxxxx) unsigned char Ecount; // # of parents of this elem - 1, // always 0 until CSE elimination is done unsigned char Eflags; #define EFLAGS_variadic 1 // variadic function call union eve EV; // variants for each type of elem union { // PARSER struct { unsigned PEFflags_; #define PEFflags _EU._EP.PEFflags_ #define PEFnotlvalue 1 // although elem may look like // an lvalue, it isn't #define PEFtemplate_id 0x10 // symbol is a template-id #define PEFparentheses 0x20 // expression was within () #define PEFaddrmem 0x40 // address of member #define PEFdependent 0x80 // value-dependent #define PEFmember 0x100 // was a class member access Symbol *Emember_; // if PEFmember, this is the member #define Emember _EU._EP.Emember_ }_EP; // OPTIMIZER struct { tym_t Ety_; // data type (TYxxxx) #define Ety _EU._EO.Ety_ unsigned Eexp_; // index into expnod[] #define Eexp _EU._EO.Eexp_ // These flags are all temporary markers, used once and then // thrown away. unsigned char Nflags_; // NFLxxx #define Nflags _EU._EO.Nflags_ #define NFLli 1 // loop invariant #define NFLnogoal 2 // evaluate elem for side effects only #define NFLassign 8 // unambiguous assignment elem #define NFLaecp 0x10 // AE or CP or VBE expression #define NFLdelcse 0x40 // this is not the generating CSE #define NFLtouns 0x80 // relational operator was changed from signed to unsigned #if MARS unsigned char Ejty_; // original Jupiter/Mars type #define Ejty _EU._EO.Ejty_ #endif }_EO; // CODGEN struct { // Ety2: Must be in same position as Ety! tym_t Ety2_; // data type (TYxxxx) #define Ety2 _EU._EC.Ety2_ unsigned char Ecomsub_; // number of remaining references to // this common subexp (used to determine // first, intermediate, and last references // to a CSE) #define Ecomsub _EU._EC.Ecomsub_ }_EC; }_EU; struct TYPE *ET; // pointer to type of elem if TYstruct | TYarray Srcpos Esrcpos; // source file position }; #define typemask(e) ((!MARS && PARSER) ? (e)->ET->Tty : (e)->Ety ) #define typetym(e) ((e)->ET->Tty) #define el_fl(e) ((enum FL)((e)->EV.sp.Vsym->Sfl)) #define Eoffset EV.sp.Voffset #define Esymnum EV.sp.Vsymnum #define list_elem(list) ((elem *) list_ptr(list)) #define list_setelem(list,ptr) list_ptr(list) = (elem *)(ptr) #define cnst(e) ((e)->Eoper == OPconst) /* Determine if elem is a constant */ #define E1 EV.eop.Eleft /* left child */ #define E2 EV.eop.Eright /* right child */ #define Erd EV.sp.spu.Erd // reaching definition #define el_int(a,b) el_long(a,b) typedef elem *elem_p; /* try to reduce the symbol table size */ void el_init(void); void el_reset(void); void el_term(void); elem_p el_calloc(void); void el_free(elem_p); elem_p el_combine(elem_p ,elem_p); elem_p el_param(elem_p ,elem_p); elem_p el_params(elem_p , ...); elem *el_params(void **args, int length); elem *el_combines(void **args, int length); int el_nparams(elem *e); elem_p el_pair(tym_t, elem_p, elem_p); void el_copy(elem_p ,elem_p); elem_p el_alloctmp(tym_t); elem_p el_selecte1(elem_p); elem_p el_selecte2(elem_p); elem_p el_copytree(elem_p); void el_replace_sym(elem *e,symbol *s1,symbol *s2); elem_p el_scancommas(elem_p); int el_countCommas(elem_p); int el_sideeffect(elem_p); int el_depends(elem *ea,elem *eb); #if LONGLONG targ_llong el_tolongt(elem_p); targ_llong el_tolong(elem_p); #else targ_long el_tolongt(elem_p); targ_long el_tolong(elem_p); #endif int el_allbits(elem_p,int); int el_signx32(elem_p); targ_ldouble el_toldouble(elem_p); void el_toconst(elem_p); elem_p el_same(elem_p *); int el_match(elem_p ,elem_p); int el_match2(elem_p ,elem_p); int el_match3(elem_p ,elem_p); int el_match4(elem_p ,elem_p); int el_match5(elem_p ,elem_p); int el_appears(elem *e,symbol *s); Symbol *el_basesym(elem *e); int el_anydef(elem *ed, elem *e); elem_p el_bint(unsigned,type *,elem_p ,elem_p); elem_p el_unat(unsigned,type *,elem_p); elem_p el_bin(unsigned,tym_t,elem_p ,elem_p); elem_p el_una(unsigned,tym_t,elem_p); #if LONGLONG // DJB elem_p el_longt(type *,targ_llong); #else elem_p el_longt(type *,targ_long); #endif symbol *el_alloc_localgot(); elem_p el_var(symbol *); elem_p el_settype(elem_p ,type *); elem_p el_typesize(type *); elem_p el_ptr(symbol *); void el_replace_sym(elem *e,symbol *s1,symbol *s2); elem * el_ptr_offset(symbol *s,targ_size_t offset); void el_replacesym(elem *,symbol *,symbol *); elem_p el_nelems(type *); #if LONGLONG elem_p el_long(tym_t,targ_llong); #else elem_p el_long(tym_t,targ_long); #endif int ERTOL(elem_p); int el_noreturn(elem_p); elem *el_dctor(elem *e,void *decl); elem *el_ddtor(elem *e,void *decl); elem *el_ctor(elem *ector,elem *e,symbol *sdtor); elem *el_dtor(elem *edtor,elem *e); elem *el_zero(type *t); elem_p el_const(tym_t,union eve *); elem_p el_test(tym_t,union eve *); elem_p * el_parent(elem_p ,elem_p *); #ifdef DEBUG void el_check(elem_p); #else #define el_check(e) ((void)0) #endif elem *el_convfloat(elem *); elem *el_convstring(elem *); elem *el_convert(elem *e); int el_isdependent(elem *); unsigned el_alignsize(elem *); void elem_print(elem *); void el_hydrate(elem **); void el_dehydrate(elem **); #endif