SYMBOL *gen_mp_virtual_thunk(SYMBOL *vsp) { QUAD *oi = intermed_head, *ot = intermed_tail; LIST *v = mpthunklist; SYMBOL *sp; IMODE *ap1, *ap2; char buf[256]; while (v) { sp = (SYMBOL*)v->data; if (sp->value.i == vsp->value.classdata.vtabindex) if (isstructured(vsp->tp->btp) == isstructured(sp->tp->btp)) return sp; v = v->link; } intermed_head = intermed_tail = NULL; blockMax = 0; blockCount = tempCount = 0; exitBlock = 0; IncGlobalFlag(); sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_static; sp->tp = vsp->tp; sp->value.i = vsp->value.classdata.vtabindex; //sprintf(buf, "@$mpt$%d$%d", sp->value.i, isstructured(sp->tp->btp)); sp->name = sp->decoratedName = litlate(buf); sp->errname = sp->decoratedName; sp->staticlabel = FALSE; sp->gennedvirtfunc = TRUE; v = (LIST *)Alloc(sizeof(LIST)); v->data = sp; v->link = mpthunklist; mpthunklist = v; DecGlobalFlag(); gen_virtual(sp, FALSE); addblock(i_goto); gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL); gen_icode(i_add, ap2, ap2 , make_immed(ISZ_NONE, isstructured(sp->tp->btp) ? ISZ_ADDR * 2 : ISZ_ADDR)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0); if (sp->value.classdata.baseofs) gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.classdata.baseofs)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0); gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.i)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_directbranch, 0, ap1, 0); addblock(i_ret); optimize(); rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(intermed_head); gen_endvirtual(sp); intermed_head = oi; intermed_tail = ot; return sp; }
LEXEME *concatStrings(LEXEME *lex, EXPRESSION **expr, enum e_lexType *tp, int *elems) { STRING *data; lex = concatStringsInternal(lex, &data, elems); IncGlobalFlag(); *expr = stringlit(data); DecGlobalFlag(); *tp = data->strtype; return lex; }
LEXEME *concatStringsInternal(LEXEME *lex, STRING **str, int *elems) { SLCHAR **list; char *suffix = NULL; int count = 3; int pos = 0 ; enum e_lexType type = l_astr; STRING *string; IncGlobalFlag(); list = (SLCHAR **)Alloc(sizeof(SLCHAR *) * count); while (lex && (lex->type == l_astr || lex->type == l_wstr || lex->type == l_ustr || lex->type == l_Ustr)) { if (lex->type == l_Ustr) type = l_Ustr; else if (type != l_Ustr && lex->type == l_ustr) type = l_ustr; else if (type != l_Ustr && type != l_ustr && lex->type == l_wstr) type = l_wstr; if (lex->suffix) { if (suffix) { if (strcmp(lex->suffix, suffix) != 0) error(ERR_LITERAL_SUFFIX_MISMATCH); } else { suffix = lex->suffix; } } if (pos >= count) { SLCHAR **h = (SLCHAR **)Alloc(sizeof(SLCHAR *) * (count + 10)); memcpy(h, list, sizeof(SLCHAR *) * count); list = h; count += 10; } if (elems) *elems += ((SLCHAR *)lex->value.s.w)->count; list[pos++] = (SLCHAR *)lex->value.s.w; lex = getsym(); } string = (STRING *)Alloc(sizeof(STRING)); string->strtype = type; string->size = pos; string->pointers = Alloc(pos * sizeof(SLCHAR * )); string->suffix = suffix; memcpy(string->pointers, list, pos * sizeof(SLCHAR *)); *str = string; DecGlobalFlag(); return lex; }
/*-------------------------------------------------------------------------*/ void gather_cases(CASEDATA *cd, struct cases *cs) { int pos = 0; if (!cs->ptrs) { IncGlobalFlag(); cs->ptrs = (struct caseptrs *)Alloc((cs->count) * sizeof(struct caseptrs)); DecGlobalFlag(); } while (cd) { cs->ptrs[pos].label = cd->label; cs->ptrs[pos++].id = cd->val; cd = cd->next; } }
LCHAR *wlitlate(LCHAR *name) { LCHAR *p = name; int count=0; LCHAR *rv; while (*p) p++, count++; IncGlobalFlag(); rv = (LCHAR *)Alloc((count + 1) * sizeof(LCHAR)); DecGlobalFlag(); p = name; count = 0; while (*p) rv[count++] = *p++; rv[count] = 0; return rv; }
SYMBOL *gen_vsn_virtual_thunk(SYMBOL *func, int ofs) { QUAD *oi = intermed_head, *ot = intermed_tail; SYMBOL *sp; IMODE *ap1, *ap2; char buf[256]; //sprintf(buf, "@$vsn%s$%d", func->decoratedName, ofs); sp = search(buf, gsyms); if (sp) return sp; intermed_head = intermed_tail = NULL; blockMax = 0; blockCount = tempCount = 0; exitBlock = 0; IncGlobalFlag(); sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_static; sp->value.i = ofs; sp->name = sp->decoratedName = litlate(buf); sp->errname = sp->decoratedName; sp->staticlabel = FALSE; sp->tp = func->tp; sp->gennedvirtfunc = TRUE; insert(sp, gsyms); DecGlobalFlag(); gen_virtual(sp, FALSE); addblock(i_goto); gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL ); gen_icode(i_add, ap1 = tempreg(ISZ_ADDR, 0), ap2, make_immed(ISZ_NONE, getSize(bt_pointer))); ap1 = indnode(ap1, ISZ_ADDR); gen_icode(i_add, ap1, ap1 , make_immed(ISZ_NONE, - ofs)); ap1 = make_imaddress(varNode(en_napccon, func), ISZ_ADDR); gen_icode(i_directbranch, 0, ap1, 0); addblock(i_ret); optimize(); rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(intermed_head); gen_endvirtual(sp); intermed_head = oi; intermed_tail = ot; return sp; }
IMODE *set_symbol(char *name, int isproc) /* * generate a call to a library routine. */ { SYMBOL *sp; IMODE *result; (void) isproc; sp = gsearch(name); if (sp == 0) { LIST *l1; IncGlobalFlag(); sp = (SYMBOL *)Alloc(sizeof(SYMBOL)); sp->storage_class = sc_external; sp->name = sp->errname = sp->decoratedName = litlate(name); sp->genreffed = TRUE; sp->tp = (TYPE *)Alloc(sizeof(TYPE)); sp->tp->type = isproc ? bt_func : bt_int; sp->safefunc = TRUE; insert(sp, globalNameSpace->syms); InsertExtern(sp); DecGlobalFlag(); } else { if (sp->storage_class == sc_overloads) sp = (SYMBOL *)(sp->tp->syms->table[0]->p); } result = (IMODE *)Alloc(sizeof(IMODE)); result->offset = varNode(en_global, sp); result->mode = i_direct; if (isproc) { result->offset->type = en_pc; if (chosenAssembler->arch->libsasimports) result->mode = i_direct; else result->mode = i_immed; } return result; }
LCHAR *wlitlate(LCHAR *name) { #ifndef BORLAND extern int wcslen(short *); #endif LCHAR *p = name; int count; LCHAR *rv; count = wcslen(name); while (*p) p++, count++; IncGlobalFlag(); rv = (LCHAR *)Alloc((count + 1) * sizeof(LCHAR)); DecGlobalFlag(); p = name; count = 0; while (*p) rv[count++] = *p++; rv[count] = 0; return rv; }
LEXEME *expression_lambda(LEXEME *lex, SYMBOL *funcsp, TYPE *atp, TYPE **tp, EXPRESSION **exp, int flags) { LAMBDA *self; SYMBOL *vpl, *ths; HASHREC *hrl; TYPE *ltp; STRUCTSYM ssl; if (funcsp) funcsp->noinline = TRUE; IncGlobalFlag(); self = Alloc(sizeof(LAMBDA)); ltp = Alloc(sizeof(TYPE)); ltp->type = bt_struct; ltp->syms = CreateHashTable(1); ltp->tags = CreateHashTable(1); ltp->size = 0; self->captured = CreateHashTable(1); self->oldSyms = localNameSpace->syms; self->oldTags = localNameSpace->tags; self->index = lambdaIndex; self->captureMode = cmNone; self->isMutable = FALSE; self->captureThis = FALSE; self->cls = makeID(sc_type, ltp, NULL, LambdaName()); ltp->sp = self->cls; SetLinkerNames(self->cls, lk_cdecl); self->cls->islambda = TRUE; self->cls->structAlign = getAlign(sc_global, &stdpointer); self->func = makeID(sc_member, ltp, NULL, "$internalFunc"); self->func->parentClass = self->cls; self->functp = &stdauto; self->enclosingFunc = theCurrentFunc; if (lambdas) lambdas->prev = self; self->next = lambdas; lambdas = self; localNameSpace->syms = CreateHashTable(1); localNameSpace->tags = CreateHashTable(1); if (lambdas->next) { self->lthis = lambdas->next->lthis; } else if (funcsp && funcsp->parentClass) { self->lthis = ((SYMBOL *)funcsp->tp->syms->table[0]->p); } lex = getsym(); // past [ if (funcsp) { // can have a capture list; if (MATCHKW(lex, assign)) { lex = getsym(); if (MATCHKW(lex, comma) || MATCHKW(lex, closebr)) { self->captureMode = cmValue; skip(&lex, comma); } else { lex = backupsym(); } } else if (MATCHKW(lex, and)) { lex = getsym(); if (MATCHKW(lex, comma) || MATCHKW(lex, closebr)) { self->captureMode = cmRef; skip(&lex, comma); } else { lex = backupsym(); } } if (!MATCHKW(lex, comma) && !MATCHKW(lex, closebr)) { do { enum e_cm localMode = self->captureMode; if (MATCHKW(lex, comma)) skip(&lex, comma); if (MATCHKW(lex, kw_this)) { lex = getsym(); if (localMode == cmValue || !self->lthis) { error(ERR_CANNOT_CAPTURE_THIS); } else { if (self->captureThis) { error(ERR_CAPTURE_ITEM_LISTED_MULTIPLE_TIMES); } self->captureThis = TRUE; lambda_capture(NULL, cmThis, TRUE); } continue; } else if (MATCHKW(lex, and)) { if (localMode == cmRef) { error(ERR_INVALID_LAMBDA_CAPTURE_MODE); } localMode = cmRef; lex = getsym(); } else { if (localMode == cmValue) { error(ERR_INVALID_LAMBDA_CAPTURE_MODE); } localMode = cmValue; } if (ISID(lex)) { SYMBOL *sp = search(lex->value.s.a, localNameSpace->syms); LAMBDA *current = lambdas; while (current && !sp) { sp = search(lex->value.s.a, current->oldSyms); current = current->next; } lex = getsym(); if (sp) { if (sp->packed) { if (!MATCHKW(lex, ellipse)) error(ERR_PACK_SPECIFIER_REQUIRED_HERE); else lex = getsym(); } if (sp->packed) { int n; TEMPLATEPARAMLIST * templateParam = sp->tp->templateParam->p->byPack.pack; HASHREC *hr; for (n=0; templateParam; templateParam = templateParam->next, n++); hr = funcsp->tp->syms->table[0]; while (hr && ((SYMBOL *)hr->p) != sp) hr = hr->next; while (hr && n) { lambda_capture((SYMBOL *)hr->p, localMode, TRUE); hr = hr->next; n--; } } else { lambda_capture(sp, localMode, TRUE); } } else errorstr(ERR_UNDEFINED_IDENTIFIER, lex->value.s.a); } else { error(ERR_INVALID_LAMBDA_CAPTURE_MODE); } } while (MATCHKW(lex, comma)); } needkw(&lex, closebr); } else { if (!MATCHKW(lex, closebr)) { error(ERR_LAMBDA_CANNOT_CAPTURE); } else { lex = getsym(); } } if (MATCHKW(lex, openpa)) { TYPE *tpx = &stdvoid; HASHREC *hr; lex = getFunctionParams(lex, NULL, &self->func, &tpx, FALSE, sc_auto); self->funcargs = self->func->tp->syms->table[0]; hr = self->func->tp->syms->table[0]; while (hr) { SYMBOL *sym = (SYMBOL *)hr->p; if (sym->init) { error(ERR_CANNOT_DEFAULT_PARAMETERS_WITH_LAMBDA); } hr = hr->next; } if (MATCHKW(lex, kw_mutable)) { HASHREC *hr = self->captured->table[0]; while (hr) { LAMBDASP *lsp = (LAMBDASP *)hr->p; if (lsp->sym->lambdaMode == cmValue) { lsp->sym->tp = basetype(lsp->sym->tp); } hr = hr->next; } self->isMutable = TRUE; lex = getsym(); } ParseAttributeSpecifiers(&lex, funcsp, TRUE); if (MATCHKW(lex, pointsto)) { lex = getsym(); lex = get_type_id(lex, &self->functp, funcsp, sc_cast, FALSE, TRUE); } } else { TYPE *tp1 = Alloc(sizeof(TYPE)); SYMBOL *spi; tp1->type = bt_func; tp1->size = getSize(bt_pointer); tp1->btp = &stdvoid; tp1->sp = self->func; self->func->tp = tp1; spi = makeID(sc_parameter, tp1, NULL, AnonymousName()); spi->anonymous = TRUE; spi->tp = Alloc(sizeof(TYPE)); spi->tp->type = bt_void; insert(spi, localNameSpace->syms); SetLinkerNames(spi, lk_cpp); self->func->tp->syms = localNameSpace->syms; self->funcargs = self->func->tp->syms->table[0]; self->func->tp->syms->table[0] = NULL; } vpl = makeID(sc_parameter, &stdpointer, NULL, AnonymousName()); vpl->assigned = vpl->used = TRUE; SetLinkerNames(vpl, lk_cdecl); hrl = Alloc(sizeof(HASHREC)); hrl->p = (struct _hrintern_ *)vpl; hrl->next = lambdas->func->tp->syms->table[0]; lambdas->func->tp->syms->table[0] = hrl; vpl = makeID(sc_parameter, &stdpointer, NULL, AnonymousName()); vpl->assigned = vpl->used = TRUE; SetLinkerNames(vpl, lk_cdecl); hrl = Alloc(sizeof(HASHREC)); hrl->p = (struct _hrintern_ *)vpl; hrl->next = lambdas->func->tp->syms->table[0]; lambdas->func->tp->syms->table[0] = hrl; SetLinkerNames(lambdas->func, lk_cdecl); injectThisPtr(lambdas->func, basetype(lambdas->func->tp)->syms); lambdas->func->tp->btp = self->functp; lambdas->func->linkage = lk_virtual; lambdas->func->isInline = TRUE; ssl.str = self->cls; ssl.tmpl = NULL; addStructureDeclaration(&ssl); ths = makeID(sc_member, &stdpointer, NULL, "$this"); lambda_insert(ths, lambdas); if (MATCHKW(lex, begin)) { lex = body(lex, self->func); } else { error(ERR_LAMBDA_FUNCTION_BODY_EXPECTED); } dropStructureDeclaration(); localNameSpace->syms = self->oldSyms; localNameSpace->tags = self->oldTags; inferType(); finishClass(); *exp = createLambda(0); *tp = lambdas->cls->tp; lambdas = lambdas->next; if (lambdas) lambdas->prev = NULL; DecGlobalFlag(); return lex; }
SYMBOL *lambda_capture(SYMBOL *sym, enum e_cm mode, BOOLEAN isExplicit) { if (lambdas) { if (mode == cmThis) { if (!sym || (lambdas->lthis && sym->parentClass == basetype(lambdas->lthis->tp)->btp->sp)) { if (lambdas->captureThis) { BOOLEAN errorflg = FALSE; LAMBDA *check = lambdas; // have to try to replicate the symbol into the current context while (check && !error) { if (check->captureMode == cmNone) { if (isExplicit) { if (lambdas->prev) { errorflg = TRUE; errorstr(ERR_EXPLICIT_CAPTURE_BLOCKED, "this"); } } else { errorflg = TRUE; errorstr(ERR_IMPLICIT_CAPTURE_BLOCKED, "this"); } } else if (check->captureMode == cmValue && isExplicit) { errorflg = TRUE; errorstr(ERR_EXPLICIT_CAPTURE_BLOCKED, "this"); } check = check->next; } if (!errorflg) { check = lambdas; while (check) { check->captureThis = TRUE; check = check->next; } } } else { errorstr(ERR_IMPLICIT_CAPTURE_BLOCKED, "this"); } } } else { if (sym->parent != lambdas->func) { if (sym->storage_class != sc_auto && sym->storage_class != sc_parameter) { error(ERR_MUST_CAPTURE_AUTO_VARIABLE); } else { LAMBDA *current = lambdas; SYMBOL *sym2 = NULL; LAMBDA *check; while (current) { LAMBDASP *lsp = (LAMBDASP *)search(sym->name, current->captured); if (lsp) { sym2 = lsp->sym; break; } current = current->next; } if (sym2) { if (lambdas == current && isExplicit) { error(ERR_CAPTURE_ITEM_LISTED_MULTIPLE_TIMES); } sym = sym2; current = current->prev; } else { current = lambdas; while (current->next) current = current->next; } check = current; // have to try to replicate the symbol into the current context while (check) { if (check->captureMode == cmNone) { if (isExplicit) { if (check->prev) { check = NULL; errorsym(ERR_EXPLICIT_CAPTURE_BLOCKED, sym); } } else { check = NULL; errorsym(ERR_IMPLICIT_CAPTURE_BLOCKED, sym); } } if (check) check = check->prev; } IncGlobalFlag(); while (current) { // we are replicating captures through intermediate lambdas // to make it easier to handle inner lambda creation. LAMBDASP *ins = Alloc(sizeof(LAMBDASP)); ins->name = sym->name; ins->parent = sym; sym = clonesym(sym); sym->lambdaMode = mode == cmNone ? current->captureMode : mode; sym->tp = lambda_type(sym->tp, sym->lambdaMode); sym->storage_class = sc_member; sym->parent = current->func; sym->init = NULL; lambda_insert(sym, current); ins->sym = sym; ins->enclosing = current; insert((SYMBOL *)ins, current->captured); current = current->prev; } DecGlobalFlag(); } } } } return sym; }
EXPRESSION *convertInitToExpression(TYPE *tp, SYMBOL *sp, SYMBOL *funcsp, INITIALIZER *init, EXPRESSION *thisptr, BOOLEAN isdest) { EXPRESSION *rv = NULL, **pos = &rv; EXPRESSION *exp = NULL, **expp; EXPRESSION *expsym; BOOLEAN noClear = FALSE; if (sp) sp->destructed = FALSE; if (isstructured(tp) || isarray(tp)) { INITIALIZER **i2 = &init; while (*i2) i2 = &(*i2)->next; initInsert(i2, NULL, NULL, tp->size, FALSE); } if (!sp) { if (thisptr) expsym = thisptr; else if (funcsp) { SYMBOL *sp = (SYMBOL *)basetype(funcsp->tp)->syms->table[0] ? (SYMBOL *)basetype(funcsp->tp)->syms->table[0]->p : NULL; if (sp && sp->thisPtr) expsym = varNode(en_auto, sp ); // this ptr else expsym = anonymousVar(sc_auto, tp); } else { expsym = intNode(en_c_i, 0); diag("convertInitToExpression: no this ptr"); } } else switch (sp->storage_class) { case sc_auto: case sc_register: case sc_parameter: expsym = varNode(en_auto, sp); break; case sc_localstatic: if (sp->linkage3 == lk_threadlocal) { expsym = exprNode(en_add, thisptr, intNode(en_c_i, sp->offset)); } else { expsym = varNode(en_label, sp); } break; case sc_static: case sc_global: if (sp->linkage3 == lk_threadlocal) { expsym = exprNode(en_add, thisptr, intNode(en_c_i, sp->offset)); } else { expsym = varNode(en_global, sp); } break; case sc_member: case sc_mutable: if (thisptr) expsym = thisptr; else if (funcsp) expsym = varNode(en_auto, (SYMBOL *)basetype(funcsp->tp)->syms->table[0]->p); // this ptr else { expsym = intNode(en_c_i, 0); diag("convertInitToExpression: no this ptr"); } expsym = exprNode(en_add, expsym, intNode(en_c_i, sp->offset)); break; case sc_external: /* expsym = varNode(en_global, sp); break; */ default: diag("convertInitToExpression: unknown sym type"); expsym = intNode(en_c_i, 0); break; } while (init) { exp = NULL; if (init->basetp) { if (init->noassign) { exp = init->exp; if (exp->type == en_thisref) exp = exp->left; if (thisptr && exp->type == en_func) { EXPRESSION *exp1 = init->offset ? exprNode(en_add, expsym, intNode(en_c_i, init->offset)) : expsym; if (isarray(tp)) { exp->v.func->arguments->exp = exp1; } else { exp->v.func->thisptr = exp1; } } exp = init->exp; } else if (!init->exp) { // usually empty braces, coudl be an error though exp = exprNode(en_blockclear, expsym, NULL); exp->size = init->offset; } else if (isstructured(init->basetp) || isarray(init->basetp)) { INITIALIZER *temp = init; if (isstructured(temp->basetp)) { EXPRESSION *exp2 = init->exp; while(exp2->type == en_not_lvalue) exp2 = exp2->left; if (exp2->type == en_func && exp2->v.func->returnSP) { exp2->v.func->returnSP->allocate = FALSE; exp2->v.func->returnEXP = expsym; exp = exp2; noClear = TRUE; } else if (exp2->type == en_thisref && exp2->left->v.func->returnSP) { exp2->left->v.func->returnSP->allocate = FALSE; exp2->left->v.func->returnEXP = expsym; exp = exp2; noClear = TRUE; } else if (cparams.prm_cplusplus) { TYPE *ctype = init->basetp; FUNCTIONCALL *funcparams = Alloc(sizeof(FUNCTIONCALL)); funcparams->arguments = Alloc(sizeof(INITLIST)); funcparams->arguments->tp = ctype; funcparams->arguments->exp = exp2; callConstructor(&ctype, &expsym, funcparams, FALSE, NULL, TRUE, FALSE, FALSE, FALSE, FALSE); exp = expsym; } else { exp = exprNode(en_blockassign, expsym, exp2); exp->size = init->basetp->size; } } else { TYPE *btp = init->basetp; while(isarray(btp)) btp = basetype(btp)->btp; btp = basetype(btp); while (temp) { if (temp->exp) if (!isarithmeticconst(temp->exp) && !isconstaddress(temp->exp)) break; temp = temp->next; } if (temp) { /* some members are non-constant expressions */ if (!cparams.prm_c99 && !cparams.prm_cplusplus) error(ERR_C99_NON_CONSTANT_INITIALIZATION); if (!sp) { expsym = anonymousVar(sc_auto, init->basetp); sp = expsym->v.sp; } if (!isstructured(btp) || btp->sp->trivialCons) { exp = exprNode(en_blockclear, expsym, NULL); exp->size = init->basetp->size; exp = exprNode(en_void, exp, NULL); expp = &exp->right; } else { expp = &exp; } { EXPRESSION *right = init->exp; if (!isstructured(btp)) { EXPRESSION *asn = exprNode(en_add, expsym, intNode(en_c_i, init->offset)); deref(init->basetp, &asn); cast(init->basetp, &right); right = exprNode(en_assign, asn, right); } if (*expp) *expp = exprNode(en_void, *expp, right); else *expp = right; expp = &(*expp)->right; } } else { /* constant expression */ SYMBOL *spc ; IncGlobalFlag(); exp = anonymousVar(sc_localstatic, init->basetp); spc = exp->v.sp; spc->init = init ; insertInitSym(spc); insert(spc, localNameSpace->syms); DecGlobalFlag(); spc->label =nextLabel++; if (expsym) { if (cparams.prm_cplusplus && isstructured(init->basetp) && !init->basetp->sp->trivialCons) { TYPE *ctype = init->basetp; FUNCTIONCALL *funcparams = Alloc(sizeof(FUNCTIONCALL)); funcparams->arguments = Alloc(sizeof(INITLIST)); funcparams->arguments->tp = ctype; funcparams->arguments->exp = exp; callConstructor(&ctype, &expsym, funcparams, FALSE, NULL, TRUE, FALSE, FALSE, FALSE, FALSE); exp = expsym; } else { exp = exprNode(en_blockassign, expsym, exp); exp->size = init->basetp->size; } } } } } else if (basetype(init->basetp)->type == bt_memberptr) { EXPRESSION *exp2 = init->exp;; while(exp2->type == en_not_lvalue) exp2 = exp2->left; if (exp2->type == en_func && exp2->v.func->returnSP) { exp2->v.func->returnSP->allocate = FALSE; exp2->v.func->returnEXP = expsym; exp = exp2; } else { if (exp2->type == en_memberptr) { int lab = dumpMemberPtr(exp2->v.sp, init->basetp, TRUE); exp2 = intNode(en_labcon, lab); } exp = exprNode(en_blockassign, expsym, exp2); exp->size = init->basetp->size; } } else { EXPRESSION *exps = expsym; if (init->offset) exps = exprNode(en_add, exps, intNode(en_c_i, init->offset)); deref(init->basetp, &exps); exp = init->exp; if (exp->type == en_void) { cast(init->basetp, &exp->right); if (expsym) exp->right = exprNode(en_assign, exps, exp->right); } else { cast(init->basetp, &exp); if (exps) exp = exprNode(en_assign, exps, exp); } } if (sp && sp->init && isatomic(init->basetp) && needsAtomicLockFromType(init->basetp)) { EXPRESSION *p1 = exprNode(en_add, expsym->left, intNode(en_c_i, init->basetp->size - ATOMIC_FLAG_SPACE)); deref(&stdint, &p1); p1 = exprNode(en_assign, p1, intNode(en_c_i, 0)); exp = exprNode(en_void, exp, p1); } } if (exp) { if (*pos) { *pos = exprNode(en_void, *pos, exp); pos = &(*pos)->right; } else { *pos = exp; } } init = init->next; } if (sp && sp->storage_class == sc_localstatic) { if (isdest) { rv = exprNode(en_voidnz, exprNode(en_void, sp->localInitGuard, rv), intNode(en_c_i, 0)); } else { EXPRESSION *guard = anonymousVar(sc_static, &stdint); insertInitSym(guard->v.sp); deref(&stdpointer, &guard); optimize_for_constants(&rv); rv = exprNode(en_voidnz, exprNode(en_void, exprNode(en_not, guard, NULL), exprNode(en_void, rv, exprNode(en_autoinc, guard, intNode(en_c_i, 1)))), intNode(en_c_i, 0)); sp->localInitGuard = guard; } } // plop in a clear block if necessary if (sp && !noClear && !isdest && (isarray(tp) || isstructured(tp) && (!cparams.prm_cplusplus || basetype(tp)->sp->trivialCons))) { EXPRESSION *fexp = expsym; EXPRESSION *exp; if (fexp->type == en_thisref) fexp = fexp->left->v.func->thisptr; exp = exprNode(en_blockclear, fexp, NULL); exp->size = sp->tp->size; rv = exprNode(en_void, exp, rv); } if (isstructured(tp) && !cparams.prm_cplusplus) { if (*pos) { *pos = exprNode(en_void, *pos, expsym); pos = &(*pos)->right; } else { *pos = expsym; } } return rv; }
static void renameToTemps(SYMBOL *funcsp) { HASHTABLE *temp = funcsp->inlineFunc.syms; if (!cparams.prm_optimize || functionHasAssembly) return; /* if there is a setjmp in the function, no variable gets moved into a reg */ if (setjmp_used) return; while (temp) { HASHREC *hr = temp->table[0]; while (hr) { SYMBOL *sp = (SYMBOL *)hr->p; TYPE *tp; /* needed for pointer aliasing */ if (!sp->imvalue && basetype(sp->tp)->type != bt_memberptr && !isstructured(sp->tp) && sp->tp->type != bt_ellipse && sp->tp->type != bt_aggregate) { if (sp->storage_class != sc_auto && sp->storage_class != sc_register) { IncGlobalFlag(); } if (sp->imaddress) { IMODE *im = Alloc(sizeof(IMODE)); *im = *sp->imaddress; im->size = sizeFromType(sp->tp); im->mode = i_direct; sp->imvalue = im; } else if (sp->imind) { IMODE *im = Alloc(sizeof(IMODE)); *im = *sp->imind->im; im-> size = ISZ_ADDR; im->mode = i_direct; sp->imvalue = im; } else sp->imvalue = tempreg(sizeFromType(sp->tp), FALSE); if (sp->storage_class != sc_auto && sp->storage_class != sc_register) { DecGlobalFlag(); } } tp = sp->tp; if (tp->type == bt_typedef) tp = tp->btp; if (!sp->pushedtotemp && sp->storage_class != sc_parameter && !sp->imaddress && !sp->inasm && ((chosenAssembler->arch->hasFloatRegs || tp->type < bt_float) && tp->type < bt_void || basetype(tp)->type == bt_pointer && basetype(tp)->btp->type != bt_func || isref(tp)) && (sp->storage_class == sc_auto || sp->storage_class == sc_register) && !sp->usedasbit) { /* this works because all IMODES refering to the same * variable are the same, at least until this point * that will change when we start inserting temps */ EXPRESSION *ep = tempenode(); ep->v.sp->tp = sp->tp; ep->right = (EXPRESSION *)sp; /* marking both the orignal var and the new temp as pushed to temp*/ sp->pushedtotemp = TRUE ; ep->v.sp->pushedtotemp = TRUE; sp->allocate = FALSE; if (sp->imvalue) { ep->isvolatile = sp->imvalue->offset->isvolatile; ep->isrestrict = sp->imvalue->offset->isrestrict; sp->imvalue->offset = ep ; } if (sp->imind) { IMODELIST *iml = sp->imind; ep->isvolatile = sp->imind->im->offset->isvolatile; ep->isrestrict = sp->imind->im->offset->isrestrict; while (iml) { iml->im->offset = ep; iml = iml->next; } } ep->v.sp->imvalue = sp->imvalue; } hr = hr->next; } temp = temp->next; } }