type *type_copy(type *t) { type *tn; param_t *p; type_debug(t); if (tybasic(t->Tty) == TYtemplate) { tn = type_alloc_template(((typetemp_t *)t)->Tsym); } else tn = type_alloc(t->Tty); *tn = *t; switch (tybasic(tn->Tty)) { case TYtemplate: ((typetemp_t *)tn)->Tsym = ((typetemp_t *)t)->Tsym; goto L1; case TYident: tn->Tident = (char *)MEM_PH_STRDUP(t->Tident); break; case TYarray: if (tn->Tflags & TFvla) tn->Tel = el_copytree(tn->Tel); break; default: if (tyfunc(tn->Tty)) { L1: tn->Tparamtypes = NULL; for (p = t->Tparamtypes; p; p = p->Pnext) { param_t *pn; pn = param_append_type(&tn->Tparamtypes,p->Ptype); if (p->Pident) { pn->Pident = (char *)MEM_PH_STRDUP(p->Pident); } assert(!p->Pelem); } } #if SCPP else if (tn->Talternate && typtr(tn->Tty)) tn->Talternate->Tcount++; #endif #if MARS else if (tn->Tkey && typtr(tn->Tty)) tn->Tkey->Tcount++; #endif break; } if (tn->Tnext) { type_debug(tn->Tnext); tn->Tnext->Tcount++; } tn->Tcount = 0; return tn; }
void param_hydrate(param_t **pp) { param_t *p; assert(pp); if (isdehydrated(*pp)) { while (*pp) { assert(isdehydrated(*pp)); p = (param_t *) ph_hydrate(pp); param_debug(p); type_hydrate(&p->Ptype); if (p->Ptype) type_debug(p->Ptype); ph_hydrate(&p->Pident); if (CPP) { el_hydrate(&p->Pelem); if (p->Pelem) elem_debug(p->Pelem); type_hydrate(&p->Pdeftype); if (p->Pptpl) param_hydrate(&p->Pptpl); if (p->Psym) symbol_hydrate(&p->Psym); if (p->PelemToken) token_hydrate(&p->PelemToken); } pp = &p->Pnext; } } }
STATIC void cpp_ecsu_data_type(type *t) { char c; symbol *stag; int i; type_debug(t); switch (tybasic(t->Tty)) { case TYstruct: stag = t->Ttag; switch (stag->Sstruct->Sflags & (STRclass | STRunion)) { case 0: c = 'U'; break; case STRunion: c = 'T'; break; case STRclass: c = 'V'; break; default: assert(0); } CHAR(c); cpp_ecsu_name(stag); break; case TYenum: CHAR('W'); cpp_enum_name(t->Ttag); break; default: #ifdef DEBUG type_print(t); #endif assert(0); } }
type *type_setcv(type **pt,tym_t cv) { unsigned long ty; type_debug(*pt); ty = (*pt)->Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared); return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); }
void param_dehydrate(param_t **pp) { param_t *p; assert(pp); while ((p = *pp) != NULL && !isdehydrated(p)) { param_debug(p); ph_dehydrate(pp); if (p->Ptype && !isdehydrated(p->Ptype)) type_debug(p->Ptype); type_dehydrate(&p->Ptype); ph_dehydrate(&p->Pident); if (CPP) { el_dehydrate(&p->Pelem); type_dehydrate(&p->Pdeftype); if (p->Pptpl) param_dehydrate(&p->Pptpl); if (p->Psym) symbol_dehydrate(&p->Psym); if (p->PelemToken) token_dehydrate(&p->PelemToken); } pp = &p->Pnext; } }
type *type_settype(type **pt, type *t) { if (t) { type_debug(t); t->Tcount++; } type_free(*pt); return *pt = t; }
int type_jparam(type *t) { targ_size_t sz; type_debug(t); return tyjparam(t->Tty) || ((tybasic(t->Tty) == TYstruct || tybasic(t->Tty) == TYarray) && (sz = type_size(t)) <= NPTRSIZE && (sz == 1 || sz == 2 || sz == 4 || sz == 8)); }
void type_hydrate(type **pt) { type *t; assert(pt); while (isdehydrated(*pt)) { t = (type *) ph_hydrate(pt); type_debug(t); #if !TX86 if (t->Tflags & TFhydrated) return; #if SOURCE_4TYPES t->Tsrcpos.Sfilnum += File_Hydrate_Num; /* file number relative header build */ #endif t->Tflags |= TFhydrated; #endif switch (tybasic(t->Tty)) { case TYstruct: case TYenum: case TYmemptr: case TYvtshape: // Cannot assume symbol is hydrated, because entire HX file // may not have been hydrated. Classsym_hydrate(&t->Ttag); symbol_debug(t->Ttag); break; case TYident: ph_hydrate(&t->Tident); break; case TYtemplate: symbol_hydrate(&((typetemp_t *)t)->Tsym); param_hydrate(&t->Tparamtypes); break; case TYarray: if (t->Tflags & TFvla) el_hydrate(&t->Tel); break; default: if (tyfunc(t->Tty)) { param_hydrate(&t->Tparamtypes); list_hydrate(&t->Texcspec, (list_free_fp)type_hydrate); } #if SCPP else if (t->Talternate && typtr(t->Tty)) type_hydrate(&t->Talternate); #endif #if MARS else if (t->Tkey && typtr(t->Tty)) type_hydrate(&t->Tkey); #endif break; } pt = &t->Tnext; } }
type *type_setdependent(type *t) { type_debug(t); if (t->Tcount > 0 && /* if other people pointing at t */ !(t->Tflags & TFdependent)) { t = type_copy(t); } t->Tflags |= TFdependent; return t; }
type *type_allocn(tym_t ty,type *tn) { type *t; //printf("type_allocn(ty = x%x, tn = %p)\n", ty, tn); assert(tn); type_debug(tn); t = type_alloc(ty); t->Tnext = tn; tn->Tcount++; //printf("\tt = %p\n", t); return t; }
STATIC void cpp_this_type(type *tfunc,Classsym *stag) { type *t; type_debug(tfunc); symbol_debug(stag); #if MARS t = type_pointer(stag->Stype); #else t = cpp_thistype(tfunc,stag); #endif //cpp_data_indirect_type(t); cpp_ecsu_data_indirect_type(t); type_free(t); }
param_t *param_append_type(param_t **pp,type *t) { param_t *p; p = param_calloc(); while (*pp) { param_debug(*pp); pp = &((*pp)->Pnext); /* find end of list */ } *pp = p; /* append p to list */ type_debug(t); p->Ptype = t; t->Tcount++; return p; }
void type_dehydrate(type **pt) { type *t; while ((t = *pt) != NULL && !isdehydrated(t)) { ph_dehydrate(pt); #if DEBUG_XSYMGEN /* don't dehydrate types in HEAD when creating XSYM */ if (xsym_gen && (t->Tflags & TFhydrated)) return; #endif type_debug(t); switch (tybasic(t->Tty)) { case TYstruct: case TYenum: case TYmemptr: case TYvtshape: Classsym_dehydrate(&t->Ttag); break; case TYident: ph_dehydrate(&t->Tident); break; case TYtemplate: symbol_dehydrate(&((typetemp_t *)t)->Tsym); param_dehydrate(&t->Tparamtypes); break; case TYarray: if (t->Tflags & TFvla) el_dehydrate(&t->Tel); break; default: if (tyfunc(t->Tty)) { param_dehydrate(&t->Tparamtypes); list_dehydrate(&t->Texcspec, (list_free_fp)type_dehydrate); } #if SCPP else if (t->Talternate && typtr(t->Tty)) type_dehydrate(&t->Talternate); #endif #if MARS else if (t->Tkey && typtr(t->Tty)) type_dehydrate(&t->Tkey); #endif break; } pt = &t->Tnext; } }
STATIC void cpp_this_type(type *tfunc,Classsym *stag) { type *t; type_debug(tfunc); symbol_debug(stag); #if MARS t = type_allocn(TYnptr, stag->Stype); t->Tcount++; #else t = cpp_thistype(tfunc,stag); #endif //cpp_data_indirect_type(t); cpp_ecsu_data_indirect_type(t); type_free(t); }
type *type_setdim(type **pt,targ_size_t dim) { type *t = *pt; type_debug(t); if (t->Tcount > 1) /* if other people pointing at t */ { type *tn; tn = type_copy(t); tn->Tcount++; type_free(t); t = tn; } t->Tflags &= ~TFsizeunknown; /* we have determined its size */ t->Tdim = dim; /* index of array */ return *pt = t; }
int type_isdependent(type *t) { Symbol *stempl; type *tstart; //printf("type_isdependent(%p)\n", t); //type_print(t); for (tstart = t; t; t = t->Tnext) { type_debug(t); if (t->Tflags & TFdependent) goto Lisdependent; if (tyfunc(t->Tty) #if TARGET_SEGMENTED || tybasic(t->Tty) == TYtemplate #endif ) { for (param_t *p = t->Tparamtypes; p; p = p->Pnext) { if (p->Ptype && type_isdependent(p->Ptype)) goto Lisdependent; if (p->Pelem && el_isdependent(p->Pelem)) goto Lisdependent; } } else if (type_struct(t) && (stempl = t->Ttag->Sstruct->Stempsym) != NULL) { for (param_t *p = t->Ttag->Sstruct->Sarglist; p; p = p->Pnext) { if (p->Ptype && type_isdependent(p->Ptype)) goto Lisdependent; if (p->Pelem && el_isdependent(p->Pelem)) goto Lisdependent; } } } //printf("\tis not dependent\n"); return 0; Lisdependent: //printf("\tis dependent\n"); // Dependence on a dependent type makes this type dependent as well tstart->Tflags |= TFdependent; return 1; }
int type_embed(type *t,type *u) { param_t *p; for (; t; t = t->Tnext) { type_debug(t); if (t == u) return 1; if (tyfunc(t->Tty)) { for (p = t->Tparamtypes; p; p = p->Pnext) if (type_embed(p->Ptype,u)) return 1; } } return 0; }
void type_hydrate(type **pt) { type *t; assert(pt); while (isdehydrated(*pt)) { t = (type *) ph_hydrate(pt); type_debug(t); switch (tybasic(t->Tty)) { case TYstruct: case TYenum: case TYmemptr: case TYvtshape: // Cannot assume symbol is hydrated, because entire HX file // may not have been hydrated. Classsym_hydrate(&t->Ttag); symbol_debug(t->Ttag); break; case TYident: ph_hydrate(&t->Tident); break; case TYtemplate: symbol_hydrate(&((typetemp_t *)t)->Tsym); param_hydrate(&t->Tparamtypes); break; case TYarray: if (t->Tflags & TFvla) el_hydrate(&t->Tel); break; default: if (tyfunc(t->Tty)) { param_hydrate(&t->Tparamtypes); list_hydrate(&t->Texcspec, (list_free_fp)type_hydrate); } else if (t->Talternate && typtr(t->Tty)) type_hydrate(&t->Talternate); else if (t->Tkey && typtr(t->Tty)) type_hydrate(&t->Tkey); break; } pt = &t->Tnext; } }
STATIC void cpp_data_type(type *t) { type_debug(t); switch (tybasic(t->Tty)) { case TYvoid: CHAR('X'); break; case TYstruct: case TYenum: CHAR('?'); cpp_ecsu_data_indirect_type(t); cpp_ecsu_data_type(t); break; default: cpp_primary_data_type(t); break; } }
type *type_setty(type **pt,long newty) { type *t; t = *pt; type_debug(t); if ((tym_t)newty != t->Tty) { if (t->Tcount > 1) /* if other people pointing at t */ { type *tn; tn = type_copy(t); tn->Tcount++; type_free(t); t = tn; *pt = t; } t->Tty = newty; } return t; }
void type_free(type *t) { type *tn; tym_t ty; while (t) { //dbg_printf("type_free(%p, Tcount = %d)\n", t, t->Tcount); type_debug(t); assert((int)t->Tcount != -1); if (--t->Tcount) /* if usage count doesn't go to 0 */ break; ty = tybasic(t->Tty); if (tyfunc(ty)) { param_free(&t->Tparamtypes); list_free(&t->Texcspec, (list_free_fp)type_free); } #if !MARS else if (ty == TYtemplate) param_free(&t->Tparamtypes); else if (ty == TYident) MEM_PH_FREE(t->Tident); #endif else if (t->Tflags & TFvla && t->Tel) el_free(t->Tel); #if SCPP else if (t->Talternate && typtr(ty)) type_free(t->Talternate); #endif #if MARS else if (t->Tkey && typtr(ty)) type_free(t->Tkey); #endif #ifdef DEBUG type_num--; //dbg_printf("Free'ing type %p ",t); WRTYxx(t->Tty); dbg_printf("\n"); t->id = 0; /* no longer a valid type */ #endif tn = t->Tnext; t->Tnext = type_list; type_list = t; /* link into free list */ t = tn; } }
type *type_setmangle(type **pt,mangle_t mangle) { type *t; t = *pt; type_debug(t); if (mangle != type_mangle(t)) { if (t->Tcount > 1) // if other people pointing at t { type *tn; tn = type_copy(t); tn->Tcount++; type_free(t); t = tn; *pt = t; } t->Tmangle = mangle; } return t; }
elem *type_vla_fix(type **pt) { type *t; elem *e = NULL; for (t = *pt; t; t = t->Tnext) { type_debug(t); if (tybasic(t->Tty) == TYarray && t->Tflags & TFvla && t->Tel) { symbol *s; elem *ec; s = symbol_genauto(tsuns); ec = el_var(s); ec = el_bint(OPeq, tsuns, ec, t->Tel); e = el_combine(e, ec); t->Tel = el_var(s); } } return e; }
unsigned type_alignsize(type *t) { targ_size_t sz; L1: type_debug(t); sz = tyalignsize(t->Tty); if (sz == (targ_size_t)-1) { switch (tybasic(t->Tty)) { case TYarray: if (t->Tflags & TFsizeunknown) goto err1; t = t->Tnext; goto L1; case TYstruct: t = t->Ttag->Stype; // find main instance // (for const struct X) if (t->Tflags & TFsizeunknown) goto err1; sz = t->Ttag->Sstruct->Salignsize; if (sz > t->Ttag->Sstruct->Sstructalign) sz = t->Ttag->Sstruct->Sstructalign; break; case TYldouble: assert(0); default: err1: // let type_size() handle error messages sz = type_size(t); break; } } //printf("type_alignsize() = %d\n", sz); return sz; }
void param_hydrate(param_t **pp) { param_t *p; assert(pp); if (isdehydrated(*pp)) { while (*pp) { assert(isdehydrated(*pp)); p = (param_t *) ph_hydrate(pp); #if SOURCE_4PARAMS p->Psrcpos.Sfilnum += File_Hydrate_Num; /* file number relative header build */ #endif param_debug(p); type_hydrate(&p->Ptype); if (p->Ptype) type_debug(p->Ptype); ph_hydrate(&p->Pident); if (CPP) { el_hydrate(&p->Pelem); if (p->Pelem) elem_debug(p->Pelem); type_hydrate(&p->Pdeftype); if (p->Pptpl) param_hydrate(&p->Pptpl); if (p->Psym) symbol_hydrate(&p->Psym); if (p->PelemToken) token_hydrate(&p->PelemToken); } pp = &p->Pnext; } } }
void type_print(type *t) { type_debug(t); dbg_printf("Tty="); WRTYxx(t->Tty); dbg_printf(" Tmangle=%d",t->Tmangle); dbg_printf(" Tflags=x%x",t->Tflags); dbg_printf(" Tcount=%d",t->Tcount); if (!(t->Tflags & TFsizeunknown) && tybasic(t->Tty) != TYvoid && tybasic(t->Tty) != TYident && tybasic(t->Tty) != TYmfunc && tybasic(t->Tty) != TYarray && tybasic(t->Tty) != TYtemplate) dbg_printf(" Tsize=%ld",type_size(t)); dbg_printf(" Tnext=%p",t->Tnext); switch (tybasic(t->Tty)) { case TYstruct: case TYmemptr: dbg_printf(" Ttag=%p,'%s'",t->Ttag,t->Ttag->Sident); //dbg_printf(" Sfldlst=%p",t->Ttag->Sstruct->Sfldlst); break; case TYarray: dbg_printf(" Tdim=%ld",t->Tdim); break; case TYident: dbg_printf(" Tident='%s'",t->Tident); break; case TYtemplate: dbg_printf(" Tsym='%s'",((typetemp_t *)t)->Tsym->Sident); { param_t *p; int i; i = 1; for (p = t->Tparamtypes; p; p = p->Pnext) { dbg_printf("\nTP%d (%p): ",i++,p); fflush(stdout); dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext); param_debug(p); if (p->Pident) printf("'%s' ", p->Pident); if (p->Ptype) type_print(p->Ptype); if (p->Pelem) elem_print(p->Pelem); } } break; default: if (tyfunc(t->Tty)) { param_t *p; int i; i = 1; for (p = t->Tparamtypes; p; p = p->Pnext) { dbg_printf("\nP%d (%p): ",i++,p); fflush(stdout); dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext); param_debug(p); if (p->Pident) printf("'%s' ", p->Pident); type_print(p->Ptype); } } break; } dbg_printf("\n"); if (t->Tnext) type_print(t->Tnext); }
targ_size_t type_size(type *t) { targ_size_t s; unsigned long u; tym_t tyb; type_debug(t); tyb = tybasic(t->Tty); #ifdef DEBUG if (tyb >= TYMAX) /*type_print(t),*/ dbg_printf("tyb = x%lx\n",tyb); #endif assert(tyb < TYMAX); s = tysize[tyb]; if (s == (targ_size_t) -1) { switch (tyb) { // in case program plays games with function pointers case TYffunc: case TYfpfunc: #if TX86 case TYnfunc: /* in case program plays games with function pointers */ case TYhfunc: case TYnpfunc: case TYnsfunc: case TYfsfunc: case TYf16func: case TYifunc: case TYjfunc: #endif #if SCPP if (ANSI) synerr(EM_unknown_size,"function"); /* size of function is not known */ #endif s = 1; break; case TYarray: if (t->Tflags & TFsizeunknown) { #if SCPP synerr(EM_unknown_size,"array"); /* size of array is unknown */ #endif t->Tflags &= ~TFsizeunknown; } if (t->Tflags & TFvla) { s = tysize[pointertype]; break; } s = type_size(t->Tnext); u = t->Tdim * (unsigned long) s; #if TX86 && SCPP type_chksize(u); #endif s = u; break; case TYstruct: t = t->Ttag->Stype; /* find main instance */ /* (for const struct X) */ if (t->Tflags & TFsizeunknown) { #if SCPP template_instantiate_forward(t->Ttag); if (t->Tflags & TFsizeunknown) synerr(EM_unknown_size,t->Tty & TYstruct ? prettyident(t->Ttag) : "struct"); t->Tflags &= ~TFsizeunknown; #endif } assert(t->Ttag); s = t->Ttag->Sstruct->Sstructsize; break; #if SCPP case TYenum: if (t->Ttag->Senum->SEflags & SENforward) synerr(EM_unknown_size, prettyident(t->Ttag)); s = type_size(t->Tnext); break; #endif case TYvoid: #if SCPP && TARGET_WINDOS // GNUC allows it, so we will, too synerr(EM_void_novalue); // voids have no value #endif s = 1; break; #if SCPP case TYref: case TYmemptr: case TYvtshape: s = tysize(tym_conv(t)); break; case TYident: synerr(EM_unknown_size, t->Tident); s = 1; break; #endif #if MARS case TYref: s = tysize(TYnptr); break; #endif default: #ifdef DEBUG WRTYxx(t->Tty); #endif assert(0); } } return s; }