type *TypeFunction::toCtype() { type *t; if (ctype) return ctype; if (1) { param_t *paramtypes = NULL; size_t nparams = Parameter::dim(parameters); for (size_t i = 0; i < nparams; i++) { Parameter *arg = Parameter::getNth(parameters, i); type *tp = arg->type->toCtype(); if (arg->storageClass & (STCout | STCref)) { // C doesn't have reference types, so it's really a pointer // to the parameter type tp = type_allocn(TYref, tp); } param_append_type(¶mtypes,tp); } tym_t tyf = totym(); t = type_alloc(tyf); t->Tflags |= TFprototype; if (varargs != 1) t->Tflags |= TFfixed; ctype = t; assert(next); // function return type should exist t->Tnext = next->toCtype(); t->Tnext->Tcount++; t->Tparamtypes = paramtypes; } ctype = t; return t; }
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; }
type *type_function(tym_t tyf, type **ptypes, size_t nparams, bool variadic, type *tret) { param_t *paramtypes = NULL; for (size_t i = 0; i < nparams; i++) { param_append_type(¶mtypes, ptypes[i]); } type *t = type_allocn(tyf, tret); t->Tflags |= TFprototype; if (!variadic) t->Tflags |= TFfixed; t->Tparamtypes = paramtypes; t->Tcount++; return t; }