STATIC void cpp_symbol_name(symbol *s) { char *p; p = s->Sident; #if SCPP if (tyfunc(s->Stype->Tty) && s->Sfunc) { if (s->Sfunc->Fflags & Finstance) { Mangle save = mangle; char *q; int len; p = template_mangle(s, s->Sfunc->Fptal); len = strlen(p); q = (char *)alloca(len + 1); memcpy(q, p, len + 1); mangle = save; p = q; } else if (s->Sfunc->Fflags & Foperator) { // operator_name ::= '?' operator_code //CHAR('?'); // already there STR(p); return; } } #endif #if MARS && 0 //It mangles correctly, but the ABI doesn't match, // leading to copious segfaults. At least with the // wrong mangling you get link errors. if (tyfunc(s->Stype->Tty) && s->Sfunc) { if (s->Sfunc->Fflags & Fctor) { cpp_zname(cpp_name_ct); return; } if (s->Sfunc->Fflags & Fdtor) { cpp_zname(cpp_name_dt); return; } } #endif cpp_zname(p); }
STATIC void cpp_symbol_name(symbol *s) { char *p; p = s->Sident; #if SCPP if (tyfunc(s->Stype->Tty) && s->Sfunc) { if (s->Sfunc->Fflags & Finstance) { Mangle save = mangle; char *q; int len; p = template_mangle(s, s->Sfunc->Fptal); len = strlen(p); q = (char *)alloca(len + 1); memcpy(q, p, len + 1); mangle = save; p = q; } else if (s->Sfunc->Fflags & Foperator) { // operator_name ::= '?' operator_code //CHAR('?'); // already there STR(p); return; } } #endif cpp_zname(p); }
int typematch(type *t1,type *t2,int relax) { tym_t t1ty, t2ty; tym_t tym; tym = ~(mTYimport | mTYnaked); return t1 == t2 || t1 && t2 && ( /* ignore name mangling */ (t1ty = (t1->Tty & tym)) == (t2ty = (t2->Tty & tym)) ) && (tybasic(t1ty) != TYarray || t1->Tdim == t2->Tdim || t1->Tflags & TFsizeunknown || t2->Tflags & TFsizeunknown) && (tybasic(t1ty) != TYstruct && tybasic(t1ty) != TYenum && tybasic(t1ty) != TYmemptr || t1->Ttag == t2->Ttag) && typematch(t1->Tnext,t2->Tnext, 0) && (!tyfunc(t1ty) || ((t1->Tflags & TFfixed) == (t2->Tflags & TFfixed) && paramlstmatch(t1->Tparamtypes,t2->Tparamtypes) )) ; }
Symbol *Dsymbol::toImport(Symbol *sym) { char *id; char *n; Symbol *s; type *t; //printf("Dsymbol::toImport('%s')\n", sym->Sident); n = sym->Sident; id = (char *) alloca(6 + strlen(n) + 1 + sizeof(type_paramsize(sym->Stype))*3 + 1); if (sym->Stype->Tmangle == mTYman_std && tyfunc(sym->Stype->Tty)) { if (config.exe == EX_WIN64) sprintf(id,"__imp_%s",n); else sprintf(id,"_imp__%s@%lu",n,(unsigned long)type_paramsize(sym->Stype)); } else if (sym->Stype->Tmangle == mTYman_d) sprintf(id,"_imp_%s",n); else sprintf(id,"_imp__%s",n); t = type_alloc(TYnptr | mTYconst); t->Tnext = sym->Stype; t->Tnext->Tcount++; t->Tmangle = mTYman_c; t->Tcount++; s = symbol_calloc(id); s->Stype = t; s->Sclass = SCextern; s->Sfl = FLextern; slist_add(s); return s; }
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 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_fake(tym_t ty) { type *t; #if MARS assert(ty != TYstruct); #endif t = type_alloc(ty); if (typtr(ty) || tyfunc(ty)) { t->Tnext = type_alloc(TYvoid); /* fake with pointer to void */ t->Tnext->Tcount = 1; } return t; }
STATIC void cpp_pointer_type(type *t) { tym_t ty; if (tyfunc(t->Tnext->Tty)) { cpp_function_indirect_type(t); cpp_function_type(t->Tnext); } else { cpp_data_indirect_type(t); cpp_pointer_data_type(t->Tnext); } }
targ_size_t type_paramsize(type *t) { targ_size_t sz = 0; if (tyfunc(t->Tty)) { for (param_t *p = t->Tparamtypes; p; p = p->Pnext) { size_t n = type_size(p->Ptype); n = align(REGSIZE,n); // align to REGSIZE boundary sz += n; } } return sz; }
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_member_function_type(symbol *s) { assert(tyfunc(s->Stype->Tty)); cpp_this_type(s->Stype,(Classsym *)s->Sscope); if (s->Sfunc->Fflags & (Fctor | Fdtor)) { type *t = s->Stype; cpp_calling_convention(t); CHAR('@'); // return_type for ctors & dtors cpp_argument_types(t); cpp_throw_types(t); } else cpp_static_member_function_type(s); }
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; } }
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; } }
STATIC void cpp_function_type(type *t) { tym_t ty; type *tn; //printf("cpp_function_type()\n"); //type_debug(t); assert(tyfunc(t->Tty)); cpp_calling_convention(t); //cpp_return_type(s); tn = t->Tnext; ty = tn->Tty; if (LARGEDATA && (tybasic(ty) == TYstruct || tybasic(ty) == TYenum) && !(ty & mTYLINK)) tn->Tty |= mTYfar; cpp_data_type(tn); tn->Tty = ty; cpp_argument_types(t); cpp_throw_types(t); }
void cv8_func_term(Symbol *sfunc) { //printf("cv8_func_term(%s)\n", sfunc->Sident); assert(currentfuncdata.sfunc == sfunc); currentfuncdata.section_length = retoffset + retsize; funcdata->write(¤tfuncdata, sizeof(currentfuncdata)); // Write function symbol assert(tyfunc(sfunc->ty())); idx_t typidx; func_t* fn = sfunc->Sfunc; if(fn->Fclass) { // generate member function type info // it would be nicer if this could be in cv4_typidx, but the function info is not available there unsigned nparam; unsigned char call = cv4_callconv(sfunc->Stype); idx_t paramidx = cv4_arglist(sfunc->Stype,&nparam); unsigned next = cv4_typidx(sfunc->Stype->Tnext); type* classtype = (type*)fn->Fclass; unsigned classidx = cv4_typidx(classtype); type *tp = type_allocn(TYnptr, classtype); unsigned thisidx = cv4_typidx(tp); // TODO debtyp_t *d = debtyp_alloc(2 + 4 + 4 + 4 + 1 + 1 + 2 + 4 + 4); TOWORD(d->data,LF_MFUNCTION_V2); TOLONG(d->data + 2,next); // return type TOLONG(d->data + 6,classidx); // class type TOLONG(d->data + 10,thisidx); // this type d->data[14] = call; d->data[15] = 0; // reserved TOWORD(d->data + 16,nparam); TOLONG(d->data + 18,paramidx); TOLONG(d->data + 22,0); // this adjust typidx = cv_debtyp(d); } else typidx = cv_typidx(sfunc->Stype); const char *id = sfunc->prettyIdent ? sfunc->prettyIdent : prettyident(sfunc); size_t len = strlen(id); if(len > CV8_MAX_SYMBOL_LENGTH) len = CV8_MAX_SYMBOL_LENGTH; /* * 2 length (not including these 2 bytes) * 2 S_GPROC_V3 * 4 parent * 4 pend * 4 pnext * 4 size of function * 4 size of function prolog * 4 offset to function epilog * 4 type index * 6 seg:offset of function start * 1 flags * n 0 terminated name string */ Outbuffer *buf = currentfuncdata.f1buf; buf->reserve(2 + 2 + 4 * 7 + 6 + 1 + len + 1); buf->writeWordn( 2 + 4 * 7 + 6 + 1 + len + 1); buf->writeWordn(sfunc->Sclass == SCstatic ? S_LPROC_V3 : S_GPROC_V3); buf->write32(0); // parent buf->write32(0); // pend buf->write32(0); // pnext buf->write32(currentfuncdata.section_length); // size of function buf->write32(startoffset); // size of prolog buf->write32(retoffset); // offset to epilog buf->write32(typidx); F1_Fixups f1f; f1f.s = sfunc; f1f.offset = buf->size(); currentfuncdata.f1fixup->write(&f1f, sizeof(f1f)); buf->write32(0); buf->writeWordn(0); buf->writeByte(0); buf->writen(id, len); buf->writeByte(0); // Write local symbol table bool endarg = false; for (SYMIDX si = 0; si < globsym.top; si++) { //printf("globsym.tab[%d] = %p\n",si,globsym.tab[si]); symbol *sa = globsym.tab[si]; if (endarg == false && sa->Sclass != SCparameter && sa->Sclass != SCfastpar && sa->Sclass != SCshadowreg) { buf->writeWord(2); buf->writeWord(S_ENDARG); endarg = true; } cv8_outsym(sa); } /* Put out function return record S_RETURN * (VC doesn't, so we won't bother, either.) */ // Write function end symbol buf->writeWord(2); buf->writeWord(S_END); currentfuncdata.f1buf = F1_buf; currentfuncdata.f1fixup = F1fixup; }
void outdata(symbol *s) { #if HTOD return; #endif int seg; targ_size_t offset; int flags; const int codeseg = cseg; symbol_debug(s); #ifdef DEBUG debugy && dbg_printf("outdata('%s')\n",s->Sident); #endif //printf("outdata('%s', ty=x%x)\n",s->Sident,s->Stype->Tty); //symbol_print(s); // Data segment variables are always live on exit from a function s->Sflags |= SFLlivexit; dt_t *dtstart = s->Sdt; s->Sdt = NULL; // it will be free'd targ_size_t datasize = 0; tym_t ty = s->ty(); #if SCPP && TARGET_WINDOS if (eecontext.EEcompile) { s->Sfl = (s->ty() & mTYfar) ? FLfardata : FLextern; s->Sseg = UNKNOWN; goto Lret; // don't output any data } #endif if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic) objmod->export_symbol(s,0); // export data definition for (dt_t *dt = dtstart; dt; dt = dt->DTnext) { //printf("\tdt = %p, dt = %d\n",dt,dt->dt); switch (dt->dt) { case DT_abytes: { // Put out the data for the string, and // reserve a spot for a pointer to that string datasize += size(dt->Dty); // reserve spot for pointer to string #if TARGET_SEGMENTED if (tybasic(dt->Dty) == TYcptr) { dt->DTseg = codeseg; dt->DTabytes += Offset(codeseg); goto L1; } else if (tybasic(dt->Dty) == TYfptr && dt->DTnbytes > config.threshold) { targ_size_t foffset; dt->DTseg = objmod->fardata(s->Sident,dt->DTnbytes,&foffset); dt->DTabytes += foffset; L1: objmod->write_bytes(SegData[dt->DTseg],dt->DTnbytes,dt->DTpbytes); break; } else #endif { dt->DTabytes += objmod->data_readonly(dt->DTpbytes,dt->DTnbytes,&dt->DTseg); } break; } case DT_ibytes: datasize += dt->DTn; break; case DT_nbytes: //printf("DT_nbytes %d\n", dt->DTnbytes); datasize += dt->DTnbytes; break; case DT_azeros: /* A block of zeros */ //printf("DT_azeros %d\n", dt->DTazeros); case_azeros: datasize += dt->DTazeros; if (dt == dtstart && !dt->DTnext && s->Sclass != SCcomdat && (s->Sseg == UNKNOWN || s->Sseg <= UDATA)) { /* first and only, so put in BSS segment */ switch (ty & mTYLINK) { #if TARGET_SEGMENTED case mTYfar: // if far data s->Sseg = objmod->fardata(s->Sident,datasize,&s->Soffset); s->Sfl = FLfardata; break; case mTYcs: s->Sseg = codeseg; Offset(codeseg) = _align(datasize,Offset(codeseg)); s->Soffset = Offset(codeseg); Offset(codeseg) += datasize; s->Sfl = FLcsdata; break; #endif case mTYthreadData: assert(config.objfmt == OBJ_MACH && I64); case mTYthread: { seg_data *pseg = objmod->tlsseg_bss(); s->Sseg = pseg->SDseg; objmod->data_start(s, datasize, pseg->SDseg); if (config.objfmt == OBJ_OMF) pseg->SDoffset += datasize; else objmod->lidata(pseg->SDseg, pseg->SDoffset, datasize); s->Sfl = FLtlsdata; break; } default: s->Sseg = UDATA; objmod->data_start(s,datasize,UDATA); objmod->lidata(s->Sseg,s->Soffset,datasize); s->Sfl = FLudata; // uninitialized data break; } assert(s->Sseg && s->Sseg != UNKNOWN); if (s->Sclass == SCglobal || (s->Sclass == SCstatic && config.objfmt != OBJ_OMF)) // if a pubdef to be done objmod->pubdefsize(s->Sseg,s,s->Soffset,datasize); // do the definition searchfixlist(s); if (config.fulltypes && !(s->Sclass == SCstatic && funcsym_p)) // not local static cv_outsym(s); #if SCPP out_extdef(s); #endif goto Lret; } break; case DT_common: assert(!dt->DTnext); outcommon(s,dt->DTazeros); goto Lret; case DT_xoff: { symbol *sb = dt->DTsym; if (tyfunc(sb->ty())) #if SCPP nwc_mustwrite(sb); #else ; #endif else if (sb->Sdt) // if initializer for symbol { if (!s->Sseg) s->Sseg = DATA; outdata(sb); // write out data for symbol } } case DT_coff: datasize += size(dt->Dty); break; default: #ifdef DEBUG dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); #endif assert(0); } }
void outdata(symbol *s) { #if HTOD return; #endif dt_t *dtstart,*dt; targ_size_t datasize,a; int seg; targ_size_t offset; int flags; char *p; tym_t ty; int tls; symbol_debug(s); #ifdef DEBUG debugy && dbg_printf("outdata('%s')\n",s->Sident); #endif //printf("outdata('%s', ty=x%x)\n",s->Sident,s->Stype->Tty); //symbol_print(s); // Data segment variables are always live on exit from a function s->Sflags |= SFLlivexit; dtstart = s->Sdt; s->Sdt = NULL; // it will be free'd #if SCPP && TARGET_WINDOS if (eecontext.EEcompile) { s->Sfl = (s->ty() & mTYfar) ? FLfardata : FLextern; s->Sseg = UNKNOWN; goto Lret; // don't output any data } #endif datasize = 0; tls = 0; ty = s->ty(); if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic) obj_export(s,0); // export data definition for (dt = dtstart; dt; dt = dt->DTnext) { //printf("dt = %p, dt = %d\n",dt,dt->dt); switch (dt->dt) { case DT_abytes: { // Put out the data for the string, and // reserve a spot for a pointer to that string #if ELFOBJ || MACHOBJ datasize += size(dt->Dty); dt->DTabytes += elf_data_cdata(dt->DTpbytes,dt->DTnbytes,&dt->DTseg); #else targ_size_t *poffset; datasize += size(dt->Dty); if (tybasic(dt->Dty) == TYcptr) { seg = cseg; poffset = &Coffset; } #if SCPP else if (tybasic(dt->Dty) == TYfptr && dt->DTnbytes > config.threshold) { seg = obj_fardata(s->Sident,dt->DTnbytes,&offset); poffset = &offset; } #endif else { seg = DATA; poffset = &Doffset; } dt->DTseg = seg; dt->DTabytes += *poffset; obj_bytes(seg,*poffset,dt->DTnbytes,dt->DTpbytes); *poffset += dt->DTnbytes; #endif break; } case DT_ibytes: datasize += dt->DTn; break; case DT_nbytes: //printf("DT_nbytes %d\n", dt->DTnbytes); datasize += dt->DTnbytes; break; case DT_symsize: #if MARS assert(0); #else dt->DTazeros = type_size(s->Stype); #endif goto case_azeros; case DT_azeros: /* A block of zeros */ //printf("DT_azeros %d\n", dt->DTazeros); case_azeros: datasize += dt->DTazeros; if (dt == dtstart && !dt->DTnext && s->Sclass != SCcomdat) { /* first and only, so put in BSS segment */ switch (ty & mTYLINK) { #if OMFOBJ case mTYfar: // if far data seg = obj_fardata(s->Sident,datasize,&s->Soffset); s->Sfl = FLfardata; break; #endif case mTYcs: seg = cseg; Coffset = align(datasize,Coffset); s->Soffset = Coffset; Coffset += datasize; s->Sfl = FLcsdata; break; case mTYthread: { seg_data *pseg = obj_tlsseg_bss(); #if ELFOBJ || MACHOBJ s->Sseg = pseg->SDseg; elf_data_start(s, datasize, pseg->SDseg); obj_lidata(pseg->SDseg, pseg->SDoffset, datasize); #else targ_size_t TDoffset = pseg->SDoffset; TDoffset = align(datasize,TDoffset); s->Soffset = TDoffset; TDoffset += datasize; pseg->SDoffset = TDoffset; #endif seg = pseg->SDseg; s->Sfl = FLtlsdata; tls = 1; break; } default: #if ELFOBJ || MACHOBJ seg = elf_data_start(s,datasize,UDATA); obj_lidata(s->Sseg,s->Soffset,datasize); #else seg = UDATA; UDoffset = align(datasize,UDoffset); s->Soffset = UDoffset; UDoffset += datasize; #endif s->Sfl = FLudata; // uninitialized data break; } #if ELFOBJ || MACHOBJ assert(s->Sseg != UNKNOWN); if (s->Sclass == SCglobal || s->Sclass == SCstatic) objpubdef(s->Sseg,s,s->Soffset); /* do the definition */ /* if a pubdef to be done */ #else s->Sseg = seg; if (s->Sclass == SCglobal) /* if a pubdef to be done */ objpubdef(seg,s,s->Soffset); /* do the definition */ #endif searchfixlist(s); if (config.fulltypes && !(s->Sclass == SCstatic && funcsym_p)) // not local static cv_outsym(s); #if SCPP out_extdef(s); #endif goto Lret; } break; case DT_common: assert(!dt->DTnext); outcommon(s,dt->DTazeros); goto Lret; case DT_xoff: { symbol *sb = dt->DTsym; if (tyfunc(sb->ty())) #if SCPP nwc_mustwrite(sb); #else ; #endif else if (sb->Sdt) // if initializer for symbol outdata(sb); // write out data for symbol } case DT_coff: datasize += size(dt->Dty); break; case DT_1byte: datasize++; break; default: #ifdef DEBUG dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); #endif assert(0); } }
STATIC void cpp_basic_data_type(type *t) { char c; int i; //printf("cpp_basic_data_type(t)\n"); //type_print(t); switch (tybasic(t->Tty)) { case TYschar: c = 'C'; goto dochar; case TYchar: c = 'D'; goto dochar; case TYuchar: c = 'E'; goto dochar; case TYshort: c = 'F'; goto dochar; case TYushort: c = 'G'; goto dochar; case TYint: c = 'H'; goto dochar; case TYuint: c = 'I'; goto dochar; case TYlong: c = 'J'; goto dochar; case TYulong: c = 'K'; goto dochar; case TYfloat: c = 'M'; goto dochar; case TYdouble: c = 'N'; goto dochar; case TYdouble_alias: if (intsize == 4) { c = 'O'; goto dochar; } c = 'Z'; goto dochar2; case TYldouble: if (intsize == 2) { c = 'O'; goto dochar; } c = 'Z'; goto dochar2; dochar: CHAR(c); break; case TYllong: c = 'J'; goto dochar2; case TYullong: c = 'K'; goto dochar2; case TYbool: c = 'N'; goto dochar2; // was 'X' prior to 8.1b8 case TYwchar_t: if (config.flags4 & CFG4nowchar_t) { c = 'G'; goto dochar; // same as TYushort } else { pstate.STflags |= PFLmfc; c = 'Y'; goto dochar2; } // Digital Mars extensions case TYifloat: c = 'R'; goto dochar2; case TYidouble: c = 'S'; goto dochar2; case TYildouble: c = 'T'; goto dochar2; case TYcfloat: c = 'U'; goto dochar2; case TYcdouble: c = 'V'; goto dochar2; case TYcldouble: c = 'W'; goto dochar2; case TYchar16: c = 'X'; goto dochar2; case TYdchar: c = 'Y'; goto dochar2; case TYnullptr: c = 'Z'; goto dochar2; dochar2: CHAR('_'); goto dochar; #if TARGET_SEGMENTED case TYsptr: case TYcptr: case TYf16ptr: case TYfptr: case TYhptr: case TYvptr: #endif #if !MARS case TYmemptr: #endif case TYnptr: c = 'P' + cpp_cvidx(t->Tty); CHAR(c); if(I64) CHAR('E'); // __ptr64 modifier cpp_pointer_type(t); break; case TYstruct: case TYenum: cpp_ecsu_data_type(t); break; case TYarray: i = cpp_cvidx(t->Tty); i |= 1; // always const CHAR('P' + i); cpp_pointer_type(t); break; case TYvoid: c = 'X'; goto dochar; #if !MARS case TYident: if (pstate.STintemplate) { CHAR('V'); // pretend to be a class name cpp_zname(t->Tident); } else { #if SCPP cpperr(EM_no_type,t->Tident); // no type for argument #endif c = 'X'; goto dochar; } break; case TYtemplate: if (pstate.STintemplate) { CHAR('V'); // pretend to be a class name cpp_zname(((typetemp_t *)t)->Tsym->Sident); } else goto Ldefault; break; #endif default: Ldefault: if (tyfunc(t->Tty)) cpp_function_type(t); else { #if SCPP #ifdef DEBUG if (!errcnt) type_print(t); #endif assert(errcnt); #endif } } }
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); }
STATIC void cpp_type_encoding(symbol *s) { char c; //printf("cpp_type_encoding()\n"); if (tyfunc(s->Stype->Tty)) { int farfunc; farfunc = tyfarfunc(s->Stype->Tty) != 0; #if SCPP || MARS if (isclassmember(s)) { // Member function int protection; int ftype; protection = cpp_protection(s); if (s->Sfunc->Fthunk && !(s->Sfunc->Fflags & Finstance)) ftype = 3; else switch (s->Sfunc->Fflags & (Fvirtual | Fstatic)) { case Fvirtual: ftype = 2; break; case Fstatic: ftype = 1; break; case 0: ftype = 0; break; default: assert(0); } CHAR('A' + farfunc + protection * 8 + ftype * 2); switch (ftype) { case 0: cpp_member_function_type(s); break; case 1: cpp_static_member_function_type(s); break; case 2: cpp_member_function_type(s); break; case 3: cpp_adjustor_thunk_type(s); break; } } else #endif { // Non-member function CHAR('Y' + farfunc); cpp_external_function_type(s); } } else { #if SCPP || MARS if (isclassmember(s)) { { // Static data member CHAR(cpp_protection(s) + '0'); cpp_static_member_data_type(s); } } else #endif { if (s->Sclass == SCstatic #if SCPP || MARS || (s->Sscope && s->Sscope->Sclass != SCstruct && s->Sscope->Sclass != SCnamespace) #endif ) { CHAR('4'); cpp_local_static_data_type(s); } else { CHAR('3'); cpp_external_data_type(s); } } } }