/*-----------------------------------------------------------------*/ int allocVariables (symbol * symChain) { symbol *sym; symbol *csym; int stack = 0; int saveLevel = 0; /* go thru the symbol chain */ for (sym = symChain; sym; sym = sym->next) { /* if this is a typedef then add it */ /* to the typedef table */ if (IS_TYPEDEF (sym->etype)) { /* check if the typedef already exists */ csym = findSym (TypedefTab, NULL, sym->name); if (csym && csym->level == sym->level) werror (E_DUPLICATE_TYPEDEF, sym->name); SPEC_EXTR (sym->etype) = 0; addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0); continue; /* go to the next one */ } /* make sure it already exists */ csym = findSymWithLevel (SymbolTab, sym); if (!csym || (csym && csym->level != sym->level)) csym = sym; /* check the declaration */ checkDecl (csym,0); /* if this is a function or a pointer to a */ /* function then do args processing */ if (funcInChain (csym->type)) { processFuncArgs (csym); } /* if this is a extern variable then change the */ /* level to zero temporarily */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) { saveLevel = csym->level; csym->level = 0; } /* if this is a literal then it is an enumerated */ /* type so need not allocate it space for it */ if (IS_LITERAL (sym->etype)) continue; /* generate the actual declaration */ if (csym->level) { allocLocal (csym); if (csym->onStack) stack += getSize (csym->type); } else allocGlobal (csym); /* restore the level */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) csym->level = saveLevel; } return stack; }
/*-----------------------------------------------------------------*/ void allocParms (value * val) { value *lval; int pNum = 1; for (lval = val; lval; lval = lval->next, pNum++) { /* check the declaration */ checkDecl (lval->sym, 0); /* if this a register parm then allocate it as a local variable by adding it to the first block we see in the body */ if (IS_REGPARM (lval->etype)) continue; /* mark it as my parameter */ lval->sym->ismyparm = 1; lval->sym->localof = currFunc; /* if automatic variables r 2b stacked */ if (options.stackAuto || IFFUNC_ISREENT (currFunc->type)) { if (lval->sym) lval->sym->onStack = 1; /* choose which stack 2 use */ /* use xternal stack */ if (options.useXstack) { /* PENDING: stack direction support */ SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack; SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = xstackPtr - getSize (lval->type); xstackPtr -= getSize (lval->type); } else { /* use internal stack */ SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack; if (port->stack.direction > 0) { SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) - getSize (lval->type) - (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0); stackPtr -= getSize (lval->type); } else { /* This looks like the wrong order but it turns out OK... */ /* PENDING: isr, bank overhead, ... */ SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = stackPtr + (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) + 0; stackPtr += getSize (lval->type); } } allocIntoSeg (lval->sym); } else { /* allocate them in the automatic space */ /* generate a unique name */ SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname), "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum); strncpyz (lval->name, lval->sym->rname, sizeof(lval->name)); /* if declared in specific storage */ if (allocDefault (lval->sym)) { SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype); continue; } /* otherwise depending on the memory model */ SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = port->mem.default_local_map; if (options.model == MODEL_SMALL) { /* note here that we put it into the overlay segment first, we will remove it from the overlay segment after the overlay determination has been done */ if (!options.noOverlay) { SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = overlay; } } else if (options.model == MODEL_MEDIUM) { SPEC_SCLS (lval->etype) = S_PDATA; } else { SPEC_SCLS (lval->etype) = S_XDATA; } allocIntoSeg (lval->sym); } } return; }
void travVardecl(astree* root) { astree* node = root->children[0]; astree* node1 = root->children[1]; root->block = blockcount; int sym = node->symbol; int otherSym = getReturnType(node1); switch(sym) { case TOK_INT: checkDecl(node); if(otherSym==TOK_INTCON || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_int); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if(otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_CHAR: checkDecl(node); if(otherSym==TOK_CHARCON || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_char); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if(otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_BOOL: checkDecl(node); if(otherSym==TOK_TRUE || otherSym==TOK_FALSE || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_bool); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if (otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_STRING: checkDecl(node); if(otherSym == TOK_NEWSTRING) { if(node1->children[0]->symbol == TOK_INTCON || otherSym==TOK_NULL) { symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_string); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0] ->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else { errprintf("%zu.%zu.%zu String size allocator not of " "type int.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } } else if (otherSym == TOK_STRINGCON || otherSym==TOK_NULL) { if(otherSym!=TOK_NULL) strvec.push_back(node1->lexinfo); symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_string); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else if(otherSym == TOK_NEWARRAY) { insertArr(node, node1); } break; case TOK_TYPEID: if(otherSym == TOK_TYPEID || otherSym==TOK_NULL || otherSym == TOK_STRUCT) { if(node1->symbol != TOK_CALL) { string leftStr = *node->lexinfo; string rightStr = *node1->children[0]->lexinfo; if(leftStr != rightStr) { errprintf("%zu.%zu.%zu Type mismatch between constructor " "and declaration.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } } else { if(lookup(node1->children[0]->lexinfo)) { symbol* funcSym = lookupSym(node1->children[0]->lexinfo); string leftStr = *node->lexinfo; string rightStr = funcSym->type_id; if(leftStr != rightStr) { errprintf("%zu.%zu.%zu Type mismatch between constructor " "and declaration.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } } } symbol *newSym = create_symbol(node->children[0]); newSym->attributes.set(ATTR_struct); newSym->attributes.set(ATTR_lval); newSym->attributes.set(ATTR_variable); newSym->type_id = *node->lexinfo; if(symbol_stack.back() == nullptr || symbol_stack.empty()) { symbol_table* tab = new symbol_table(); tab->insert(symbol_entry(node->children[0]->lexinfo,newSym)); symbol_stack.pop_back(); symbol_stack.push_back(tab); } else { symbol_stack.back()->insert(symbol_entry(node->children[0]-> lexinfo,newSym)); } dumpToFile(file_sym, newSym, node->children[0]); } else { errprintf("%zu.%zu.%zu Variable not allocated correctly.\n", node1->children[1]->filenr, node1->children[1]->linenr, node1->children[1]->offset); } break; case TOK_IDENT: if(lookup(node->lexinfo)) { symbol* newSym = lookupSym(node->lexinfo); int type = getIdentReturn(newSym); if(type==TOK_STRUCT&&otherSym==TOK_TYPEID) { if(newSym->type_id!=*node1->children[0]->lexinfo) { errprintf("%zu.%zu.%zu Variable being reassigned wrong " "type",node->filenr,node->linenr,node->offset); } } } else { errprintf("%zu.%zu.%zu" " Variable being referenced is undefined\n",node->filenr, node->linenr,node->offset); } } }