예제 #1
0
/*-----------------------------------------------------------------*/
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;
}
예제 #2
0
파일: SDCCmem.c 프로젝트: doniexun/kcc
/*-----------------------------------------------------------------*/
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;
}
예제 #3
0
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);
        }
    }
}