unsigned cv4_memfunctypidx(FuncDeclaration *fd) { type *t; debtyp_t *d; unsigned char *p; AggregateDeclaration *ad; //printf("cv4_memfunctypidx(fd = '%s')\n", fd->toChars()); t = fd->type->toCtype(); ad = fd->isMember2(); if (ad) { unsigned nparam; idx_t paramidx; idx_t thisidx; unsigned u; unsigned char call; // It's a member function, which gets a special type record if (fd->isStatic()) thisidx = dttab4[TYvoid]; else { assert(ad->handle); thisidx = cv4_typidx(ad->handle->toCtype()); } paramidx = cv4_arglist(t,&nparam); call = cv4_callconv(t); d = debtyp_alloc(18); p = d->data; TOWORD(p,LF_MFUNCTION); TOWORD(p + 2,cv4_typidx(t->Tnext)); TOWORD(p + 4,cv4_typidx(ad->type->toCtype())); TOWORD(p + 6,thisidx); p[8] = call; p[9] = 0; // reserved TOWORD(p + 10,nparam); TOWORD(p + 12,paramidx); TOLONG(p + 14,0); // thisadjust return cv_debtyp(d); } return cv4_typidx(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; }
unsigned cv4_memfunctypidx(FuncDeclaration *fd) { //printf("cv4_memfunctypidx(fd = '%s')\n", fd->toChars()); type *t = fd->type->toCtype(); AggregateDeclaration *ad = fd->isMember2(); if (ad) { // It's a member function, which gets a special type record idx_t thisidx; if (fd->isStatic()) thisidx = dttab4[TYvoid]; else { assert(ad->handle); thisidx = cv4_typidx(ad->handle->toCtype()); } unsigned nparam; idx_t paramidx = cv4_arglist(t,&nparam); unsigned char call = cv4_callconv(t); debtyp_t *d; switch (config.fulltypes) { case CV4: { d = debtyp_alloc(18); unsigned char *p = d->data; TOWORD(p,LF_MFUNCTION); TOWORD(p + 2,cv4_typidx(t->Tnext)); TOWORD(p + 4,cv4_typidx(ad->type->toCtype())); TOWORD(p + 6,thisidx); p[8] = call; p[9] = 0; // reserved TOWORD(p + 10,nparam); TOWORD(p + 12,paramidx); TOLONG(p + 14,0); // thisadjust break; } case CV8: { d = debtyp_alloc(26); unsigned char *p = d->data; TOWORD(p,0x1009); TOLONG(p + 2,cv4_typidx(t->Tnext)); TOLONG(p + 6,cv4_typidx(ad->type->toCtype())); TOLONG(p + 10,thisidx); p[14] = call; p[15] = 0; // reserved TOWORD(p + 16,nparam); TOLONG(p + 18,paramidx); TOLONG(p + 22,0); // thisadjust break; } default: assert(0); } return cv_debtyp(d); } return cv4_typidx(t); }