Exemplo n.º 1
0
void ParseEnumerationList(TABLE *table)
{
	int     evalue;
    SYM     *sp;
    evalue = 0;
    while(lastst == id) {
        sp = allocSYM();
        sp->SetName(*(new std::string(lastid)));
        sp->storage_class = sc_const;
        sp->tp = &stdconst;
        table->insert(sp);
        NextToken();
		if (lastst==assign) {
			NextToken();
			sp->value.i = GetIntegerExpression((ENODE **)NULL);
			evalue = (int)sp->value.i+1;
		}
		else
			sp->value.i = evalue++;
        if( lastst == comma)
                NextToken();
        else if(lastst != end)
                break;
    }
    needpunc(end,48);
}
Exemplo n.º 2
0
Statement *ParseFirstcallStatement() 
{
	Statement *snp; 
	SYM *sp;
	int st;

  dfs.puts("<ParseFirstcall>");
  snp = NewStatement(st_firstcall, TRUE); 
  sp = allocSYM();
//	sp->SetName(*(new std::string(snp->fcname)));
  sp->storage_class = sc_static;
  sp->value.i = nextlabel++;
  sp->tp = &stdbyte;
  st = lastst;
  lastst = kw_firstcall;       // fake out doinit()
  doinit(sp);
  lastst = st;
  // doinit should set realname
  snp->fcname = my_strdup(sp->realname);
  snp->s1 = ParseStatement(); 
	// Empty statements return NULL
	if (snp->s1)
		snp->s1->outer = snp;
  dfs.puts("</ParseFirstcall>");
  return snp; 
} 
Exemplo n.º 3
0
void ParseEnumerationList(TABLE *table)
{
	int     evalue;
    SYM     *sp;
    evalue = 0;
    while(lastst == id) {
        sp = allocSYM();
        sp->name = litlate(lastid);
        sp->storage_class = sc_const;
        sp->tp = &stdconst;
        insert(sp,table);
        NextToken();
		if (lastst==assign) {
			NextToken();
			sp->value.i = GetIntegerExpression((ENODE **)NULL);
			evalue = sp->value.i+1;
		}
		else
			sp->value.i = evalue++;
        if( lastst == comma)
                NextToken();
        else if(lastst != end)
                break;
    }
    needpunc(end);
}
Exemplo n.º 4
0
Statement *ParseLabelStatement()
{      
	Statement *snp;
    SYM *sp;

    snp = NewStatement(st_label, FALSE); 
    if( (sp = search(lastid,&lsyms)) == NULL ) { 
        sp = allocSYM(); 
        sp->name = litlate(lastid); 
        sp->storage_class = sc_label; 
        sp->tp = 0; 
        sp->value.i = nextlabel++; 
        insert(sp,&lsyms); 
    } 
    else { 
        if( sp->storage_class != sc_ulabel ) 
            error(ERR_LABEL); 
        else 
            sp->storage_class = sc_label; 
    } 
    NextToken();       /* get past id */ 
    needpunc(colon); 
    if( sp->storage_class == sc_label ) { 
        snp->label = sp->value.i; 
        snp->next = NULL; 
        return snp; 
    } 
    return 0; 
} 
Exemplo n.º 5
0
Statement *ParseGotoStatement() 
{       
	Statement *snp; 
    SYM *sp;

    NextToken(); 
    if( lastst != id ) { 
        error(ERR_IDEXPECT); 
        return NULL;
    } 
    snp = NewStatement(st_goto, FALSE);
    if( (sp = search(lastid,&lsyms)) == NULL ) { 
        sp = allocSYM(); 
        sp->name = litlate(lastid); 
        sp->value.i = nextlabel++; 
        sp->storage_class = sc_ulabel; 
        sp->tp = 0; 
        insert(sp,&lsyms); 
    }
    NextToken();       /* get past label name */
    if( lastst != end )
        needpunc( semicolon );
    if( sp->storage_class != sc_label && sp->storage_class != sc_ulabel)
        error( ERR_LABEL );
    else { 
        snp->stype = st_goto;
        snp->label = sp->value.i;
        snp->next = NULL;
        return snp; 
    } 
    return NULL;
} 
Exemplo n.º 6
0
//struct snode    *interrupt_stmt()
//{       struct snode    *snp; 
//        SYM             *sp; 
//	       TYP     *temp1;
//
//	   NextToken(); 
//		if( lastst != id ) { 
//			error(ERR_IDEXPECT); 
//			return 0; 
//        } 
//        sp = allocSYM(); 
//        sp->name = litlate(lastid); 
//        sp->value.i = nextlabel++; 
//        sp->storage_class = sc_global;
//        sp->tp = temp1; 
//        temp1 = maketype(bt_long,0);
//        temp1->val_flag = 1;
//        insert(sp,&lsyms); 
//        NextToken();       /* get past label name */ 
//        needpunc( colon );
//		snp = (struct snode *)xalloc(sizeof(struct snode)); 
//        snp->stype = st_interrupt; 
//        snp->label = sp->name;
//        snp->next = 0; 
//		snp->s1 = statement(); 
//        return snp; 
//} 
//  
struct snode    *vortex_stmt()
{       struct snode    *snp; 
        SYM             *sp; 
	       TYP     *temp1;

	   NextToken(); 
		if( lastst != id ) { 
			error(ERR_IDEXPECT); 
			return 0; 
        } 
        temp1 = maketype(bt_long,0);
        temp1->val_flag = 1;
        sp = allocSYM(); 
        sp->name = litlate(lastid); 
        sp->value.i = nextlabel++; 
        sp->storage_class = sc_global;
        sp->tp = temp1; 
        insert(sp,&lsyms); 
        NextToken();       /* get past label name */ 
        needpunc( colon );
		snp = (struct snode *)xalloc(sizeof(struct snode)); 
        snp->stype = st_vortex; 
        snp->label = sp->name;
        snp->next = 0; 
		snp->s1 = ParseStatement(); 
        return snp; 
} 
Exemplo n.º 7
0
Statement *vortex_stmt()
{       Statement *snp; 
        SYM             *sp; 
	       TYP     *temp1;

	   NextToken(); 
		if( lastst != id ) { 
			error(ERR_IDEXPECT); 
			return 0; 
        } 
        temp1 = TYP::Make(bt_long,0);
        temp1->val_flag = 1;
        sp = allocSYM(); 
        sp->SetName(*(new std::string(lastid))); 
        sp->value.i = nextlabel++; 
        sp->storage_class = sc_global;
        sp->SetType(temp1); 
        currentFn->lsyms.insert(sp); 
        NextToken();       /* get past label name */ 
        needpunc( colon,30 );
		snp = (struct snode *)xalloc(sizeof(struct snode)); 
        snp->stype = st_vortex; 
        snp->label = (int64_t *)my_strdup((char *)sp->name->c_str());
        snp->next = 0; 
		snp->s1 = ParseStatement(); 
        return snp; 
} 
Exemplo n.º 8
0
int dodefine()
{   
	SYM     *sp;
    NextToken();               /* get past #define */
    if( lastst != id ) {
            error(ERR_DEFINE);
            return getline(incldepth == 0);
            }
    ++global_flag;          /* always do #define as globals */
    sp = allocSYM();
    sp->name = litlate(lastid);
    sp->value.s = litlate(lptr-1);
    insert(sp,&defsyms);
    --global_flag;
    return getline(incldepth == 0);
}
Exemplo n.º 9
0
SYM *makeint(char *name)
{  
  SYM     *sp;
  TYP     *tp;

  sp = allocSYM();
  tp = TYP::Make(bt_long,8);
  tp->sname = new std::string("");
	tp->isUnsigned = FALSE;
	tp->isVolatile = FALSE;
  sp->SetName(name);
  sp->storage_class = sc_auto;
  sp->SetType(tp);
	sp->IsPrototype = FALSE;
  currentFn->lsyms.insert(sp);
  return sp;
}
Exemplo n.º 10
0
SYM     *makeint(char *name)
{       SYM     *sp;
        TYP     *tp;
        sp = allocSYM();
        tp = allocTYP();
        tp->type = bt_long;
        tp->size = 8;
        tp->btp = 0;
		tp->lst.head = 0;
        tp->sname = 0;
        sp->name = name;
        sp->storage_class = sc_auto;
        sp->tp = tp;
		sp->IsPrototype = FALSE;
        insert(sp,&lsyms);
        return sp;
}
Exemplo n.º 11
0
void ParseEnumDeclaration(TABLE *table)
{   
	SYM *sp;
    TYP     *tp;
    if( lastst == id) {
        if((sp = search(lastid,&tagtable)) == NULL) {
            sp = allocSYM();
            sp->tp = allocTYP();
            sp->tp->type = bt_enum;
            sp->tp->size = 2;
            sp->tp->lst.head = 0;
			sp->tp->btp = 0;
            sp->storage_class = sc_type;
            sp->name = litlate(lastid);
            sp->tp->sname = sp->name;
            NextToken();
            if( lastst != begin)
                    error(ERR_INCOMPLETE);
            else {
				insert(sp,&tagtable);
				NextToken();
				ParseEnumerationList(table);
            }
        }
        else
            NextToken();
        head = sp->tp;
    }
    else {
        tp = allocTYP();	// fix here
        tp->type = bt_enum;
		tp->size = 2;
        if( lastst != begin)
            error(ERR_INCOMPLETE);
        else {
            NextToken();
            ParseEnumerationList(table);
        }
    head = tp;
    }
}
Exemplo n.º 12
0
void ParseEnumDeclaration(TABLE *table)
{   
	SYM *sp;
    TYP     *tp;
    if( lastst == id) {
        if((sp = search(lastid,&tagtable)) == NULL) {
            sp = allocSYM();
            sp->tp = TYP::Make(bt_enum,1);
            sp->storage_class = sc_type;
            sp->SetName(*(new std::string(lastid)));
            sp->tp->sname = new std::string(*sp->name);
            NextToken();
            if( lastst != begin)
                    error(ERR_INCOMPLETE);
            else {
				tagtable.insert(sp);
				NextToken();
				ParseEnumerationList(table);
            }
        }
        else
            NextToken();
        head = sp->tp;
    }
    else {
        tp = allocTYP();	// fix here
        tp->type = bt_enum;
		tp->size = 1;
        if( lastst != begin)
            error(ERR_INCOMPLETE);
        else {
            NextToken();
            ParseEnumerationList(table);
        }
    head = tp;
    }
}
Exemplo n.º 13
0
int ParseStructDeclaration(int ztype)
{
    SYM     *sp;
    TYP     *tp;
    int gblflag;
    int ret;
    int psd;
    ENODE nd;
    ENODE *pnd = &nd;

    psd = isStructDecl;
    isStructDecl = TRUE;
    ret = 0;
    bit_offset = 0;
    bit_next = 0;
    bit_width = -1;
    if(lastst == id) {
        if((sp = search(lastid,&tagtable)) == NULL) {
            // If we encounted an unknown struct in a parameter list, we want
            // it to go into the global memory pool, not a local one.
            if (parsingParameterList) {
                gblflag = global_flag;
                global_flag++;
                sp = allocSYM();
                sp->name = litlate(lastid);
                global_flag = gblflag;
            }
            else {
                sp = allocSYM();
                sp->name = litlate(lastid);
            }
            sp->tp = allocTYP();
            sp->tp->type = ztype;
            sp->tp->typeno = typeno++;
            sp->tp->lst.head = 0;
            sp->storage_class = sc_type;
            sp->tp->sname = sp->name;
            sp->tp->alignment = 0;
            NextToken();

            if (lastst == kw_align) {
                NextToken();
                sp->tp->alignment = GetIntegerExpression(&pnd);
            }

            // Could be a forward structure declaration like:
            // struct buf;
            if (lastst==semicolon) {
                ret = 1;
                insert(sp,&tagtable);
                NextToken();
            }
            // Defining a pointer to an unknown struct ?
            else if (lastst == star) {
                insert(sp,&tagtable);
            }
            else if(lastst != begin)
                error(ERR_INCOMPLETE);
            else    {
                insert(sp,&tagtable);
                NextToken();
                ParseStructMembers(sp->tp,ztype);
            }
        }
        else {
            NextToken();
            if (lastst==kw_align) {
                NextToken();
                sp->tp->alignment = GetIntegerExpression(&pnd);
            }
            if (lastst==begin) {
                NextToken();
                ParseStructMembers(sp->tp,ztype);
            }
        }
        head = sp->tp;
    }
    else {
        tp = allocTYP();
        tp->type = ztype;
        tp->sname = 0;
        tp->lst.head = 0;

        if (lastst==kw_align) {
            NextToken();
            tp->alignment = GetIntegerExpression(&pnd);
        }

        if( lastst != begin)
            error(ERR_INCOMPLETE);
        else {
            NextToken();
            ParseStructMembers(tp,ztype);
        }
        head = tp;
    }
    isStructDecl = psd;
    return ret;
}
Exemplo n.º 14
0
void ClassDeclaration::ParseMembers(SYM *sym, int ztype)
{
	int slc;
	TYP *tp = sym->tp;
	int ist;
  SYM *hsym;
  std::string *name;

	isPrivate = true;
	if (sym->tp->size)
     slc = roundSize(sym->tp);
  else
     slc = 0;

//	slc = 0;
  tp->val_flag = 1;
//	tp->val_flag = FALSE;
	ist = isTypedef;
	isTypedef = false;

	// First add a hidden member that indicates the class number. The type
	// number is used during virtual function calls to determine which
	// method to call. This is the first field in the class so it can be
	// refeerenced as 0[r25].
	hsym = allocSYM();
	name = new std::string("_typeno");
  hsym->SetName(*name);
	hsym->storage_class = sc_member;
	hsym->value.i = sym->tp->typeno;
	hsym->tp = TYP::Make(bt_char,2);
  hsym->tp->sname = new std::string("_typeno");
  hsym->tp->alignment = 2;
	tp->lst.insert(hsym);
  slc += 2;

  while( lastst != end) {
		if (lastst==kw_public)
			isPrivate = false;
		if (lastst==kw_private)
			isPrivate = true;
		if (lastst==kw_public || lastst==kw_private) {
			NextToken();
			if (lastst==colon)
				NextToken();
		}
		if (lastst==kw_unique || lastst==kw_static) {
			NextToken();
      declare(sym,&(tp->lst),sc_static,slc,ztype);
		}
		else {
			if(ztype == bt_struct || ztype==bt_class)
				slc += declare(sym,&(tp->lst),sc_member,slc,ztype);
			else
				slc = imax(slc,declare(sym,&(tp->lst),sc_member,0,ztype));
		}
  }
	bit_offset = 0;
	bit_next = 0;
	bit_width = -1;
  tp->size = tp->alignment ? tp->alignment : slc;
  NextToken();
	isTypedef = ist;
}
Exemplo n.º 15
0
// Class declarations have the form:
//
//	class identifier [: base class]
//  {
//		class members
//	}
//
// We could also have a forward reference:
//
//	class identifier;
//
// Or a pointer to a class:
//
//	class *identifier;
//
int ClassDeclaration::Parse(int ztype)
{
    SYM *sp, *bcsp;
	int ret;
	int psd;
	ENODE nd;
	ENODE *pnd = &nd;
	char *idsave;
	int alignment;
  SYM *cls;

  cls = currentClass;
	dfs.puts("<ParseClassDeclaration>\n");
	alignment = 0;
	isTypedef = TRUE;
	NextToken();
	if (lastst != id) {
		error(ERR_SYNTAX);
		goto lxit;
	}
//	ws = allocSYM();
	idsave = my_strdup(lastid);
//	ws->name = idsave;
//	ws->storage_class = sc_typedef;
	// Passes lastid onto struct parsing

	psd = isStructDecl;
	isStructDecl++;
	ret = 0;
	bit_offset = 0;
	bit_next = 0;
	bit_width = -1;

  dfs.printf("---------------------------------");
  dfs.printf("Class decl:%s\n", lastid);
  dfs.printf("---------------------------------");
	if((sp = tagtable.Find(std::string(lastid),false)) == NULL) {
    sp = allocSYM();
    sp->SetName(*(new std::string(lastid)));
		sp->tp = nullptr;
    NextToken();
    dfs.printf("A");
		if (lastst == kw_align) {
      NextToken();
      alignment = GetIntegerExpression(&pnd);
    }
    else
      alignment = AL_STRUCT;

		// Could be a forward structure declaration like:
		// struct buf;
		if (lastst==semicolon) {
      dfs.printf("B");
			ret = 1;
			printf("classdecl insert1\r\n");
      tagtable.insert(sp);
      NextToken();
		}
		// Defining a pointer to an unknown struct ?
		else if (lastst == star) {
      dfs.printf("C");
			printf("classdecl insert2\r\n");
      tagtable.insert(sp);
		}
		else if (lastst==colon) {
      dfs.printf("D");
			NextToken();
			// Absorb and ignore public/private keywords
			if (lastst == kw_public || lastst==kw_private)
				NextToken();
			if (lastst != id) {
				error(ERR_SYNTAX);
				goto lxit;
			}
			bcsp = tagtable.Find(std::string(lastid),false);
			if (bcsp==nullptr) {
				error(ERR_UNDEFINED);
				goto lxit;
			}
      dfs.printf("E");
			// Copy the type chain of base class
			//sp->tp = TYP::Copy(bcsp->tp);
			// Start off at the size of the base.
			sp->tp = allocTYP();
			sp->tp->lst.SetBase(bcsp->GetIndex());
			dfs.printf("Set base class: %d\n", sp->tp->lst.base);
			sp->tp->size = bcsp->tp->size;
			sp->tp->type = (e_bt)ztype;
			sp->tp->typeno = typeno++;
      sp->tp->sname = new std::string(*sp->name);
      sp->tp->alignment = alignment;
	    sp->storage_class = sc_type;
			NextToken();
			if (lastst != begin) {
        error(ERR_INCOMPLETE);
				goto lxit;
			}
			/*
			sp->tp = allocTYP();
			sp->tp->typeno = typeno++;
      sp->tp->sname =  new std::string(*sp->name);
      sp->tp->alignment = alignment;
			sp->tp->type = (e_bt)ztype;
			sp->tp->lst.SetBase(bcsp->GetIndex());
	    sp->storage_class = sc_type;
	    */
      tagtable.insert(sp);
      NextToken();
      currentClass = sp;
      dfs.printf("f");
      ParseMembers(sp,ztype);
      dfs.printf("G");
		}
    else if(lastst != begin)
      error(ERR_INCOMPLETE);
    else {
			if (sp->tp == nullptr) {
				sp->tp = allocTYP();
			}
			sp->tp->size = 0;
			sp->tp->typeno = typeno++;
      sp->tp->sname = new std::string(*sp->name);
      sp->tp->alignment = alignment;
			sp->tp->type = (e_bt)ztype;
			sp->tp->lst.SetBase(0);
	    sp->storage_class = sc_type;
      tagtable.insert(sp);
      NextToken();
      currentClass = sp;
      ParseMembers(sp,ztype);
    }
  }
  // Else the class was found in the tag table.
	else {
    NextToken();
    if (lastst==kw_align) {
	    NextToken();
      sp->tp->alignment = GetIntegerExpression(&pnd);
    }
		if (lastst==begin) {
        NextToken();
        currentClass = sp;
        ParseMembers(sp,ztype);
		}
	}
  head = sp->tp;
	isStructDecl = psd;
lxit:
	isTypedef = TRUE;
	if (classname) delete classname;
	classname = new std::string(idsave);
	currentClass = cls;
	dfs.puts("</ParseClassDeclaration>\n");
	return ret;
}
Exemplo n.º 16
0
int StructDeclaration::Parse(int ztype)
{
  SYM *sp;
  TYP *tp;
	int ret;
	int psd;
	ENODE nd;
	ENODE *pnd = &nd;

  sp = nullptr;
	psd = isStructDecl;
	isStructDecl++;
	ret = 0;
	bit_offset = 0;
	bit_next = 0;
	bit_width = -1;
  if(lastst == id) {
    if((sp = tagtable.Find(lastid,false)) == NULL) {
      sp = allocSYM();
  		sp->SetName(*(new std::string(lastid)));
      sp->tp = allocTYP();
      sp->tp->type = (e_bt)ztype;
		  sp->tp->typeno = typeno++;
      sp->tp->lst.Clear();
      sp->storage_class = sc_type;
      sp->tp->sname = new std::string(*sp->name);
      sp->tp->alignment = 0;
      NextToken();

			if (lastst == kw_align) {
        NextToken();
        sp->tp->alignment = GetIntegerExpression(&pnd);
      }

			// Could be a forward structure declaration like:
			// struct buf;
			if (lastst==semicolon) {
				ret = 1;
        tagtable.insert(sp);
        NextToken();
			}
			// Defining a pointer to an unknown struct ?
			else if (lastst == star) {
        tagtable.insert(sp);
			}
      else if(lastst != begin)
        error(ERR_INCOMPLETE);
      else {
        tagtable.insert(sp);
        NextToken();
        ParseMembers(sp, sp->tp,ztype);
      }
    }
    // Else it is a known structure
		else {
      NextToken();
      if (lastst==kw_align) {
        NextToken();
        sp->tp->alignment = GetIntegerExpression(&pnd);
      }
			if (lastst==begin) {
        NextToken();
        ParseMembers(sp,sp->tp,ztype);
			}
		}
    head = sp->tp;
  }
  // Else there was no tag identifier
  else {
    tp = allocTYP();
    tp->type = (e_bt)ztype;
	  tp->typeno = typeno++;
    tp->sname = new std::string("");

    if (lastst==kw_align) {
      NextToken();
      tp->alignment = GetIntegerExpression(&pnd);
    }

    if( lastst != begin)
      error(ERR_INCOMPLETE);
    else {
			NextToken();
			ParseMembers(sp,tp,ztype);
    }
    head = tp;
  }
	isStructDecl = psd;
	return ret;
}
Exemplo n.º 17
0
/*
 *      process declarations of the form:
 *
 *              <type>  <specifier>, <specifier>...;
 *
 *      leaves the declarations in the symbol table pointed to by
 *      table and returns the number of bytes declared. al is the
 *      allocation type to assign, ilc is the initial location
 *      counter. if al is sc_member then no initialization will
 *      be processed. ztype should be bt_struct for normal and in
 *      structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations.
 */
int declare(TABLE *table,int al,int ilc,int ztype)
{ 
	SYM *sp, *sp1, *sp2;
    TYP *dhead, *tp1, *tp2;
	ENODE *ep1, *ep2;
	char stnm[200];
	int op;
	int fd;
	int fn_doneinit = 0;
	int bcnt;

    static long old_nbytes;
    int nbytes;

	nbytes = 0;
    if (ParseSpecifier(table))
		return nbytes;
    dhead = head;
    for(;;) {
        declid = (char *)NULL;
		bit_width = -1;
        ParseDeclarationPrefix(ztype==bt_union);
		// If a function declaration is taking place and just the type is
		// specified without a parameter name, assign an internal compiler
		// generated name.
		if (funcdecl>0 && funcdecl != 10 && declid==(char *)NULL) {
			sprintf(lastid, "_p%d", nparms);
			declid = litlate(lastid);
			names[nparms++] = declid;
			missingArgumentName = TRUE;
		}
        if( declid != NULL) {      /* otherwise just struct tag... */
            sp = allocSYM();
			sp->name = declid;
            sp->storage_class = al;
            sp->isConst = isConst;
			if (bit_width > 0 && bit_offset > 0) {
				// share the storage word with the previously defined field
				nbytes = old_nbytes - ilc;
			}
			old_nbytes = ilc + nbytes;
			if (al != sc_member) {
//							sp->isTypedef = isTypedef;
				if (isTypedef)
					sp->storage_class = sc_typedef;
				isTypedef = FALSE;
			}
			if ((ilc + nbytes) % roundAlignment(head)) {
				if (al==sc_thread)
					tseg();
				else
					dseg();
            }
            bcnt = 0;
            while( (ilc + nbytes) % roundAlignment(head)) {
                ++nbytes;
                bcnt++;
            }
            if( al != sc_member && al != sc_external && al != sc_auto) {
                if (bcnt > 0)
                    genstorage(bcnt);
            }

			// Set the struct member storage offset.
			if( al == sc_static || al==sc_thread) {
				sp->value.i = nextlabel++;
			}
			else if( ztype == bt_union)
                sp->value.i = ilc;
            else if( al != sc_auto )
                sp->value.i = ilc + nbytes;
			// Auto variables are referenced negative to the base pointer
			// Structs need to be aligned on the boundary of the largest
			// struct element. If a struct is all chars this will be 2.
			// If a struct contains a pointer this will be 8. It has to
			// be the worst case alignment.
			else {
                sp->value.i = -(ilc + nbytes + roundSize(head));
			}

			if (bit_width == -1)
				sp->tp = head;
			else {
				sp->tp = allocTYP();
				*(sp->tp) = *head;
				sp->tp->type = bt_bitfield;
				sp->tp->size = head->size;//tp_int.size;
				sp->tp->bit_width = bit_width;
				sp->tp->bit_offset = bit_offset;
			}
			if (isConst)
				sp->tp->isConst = TRUE;
            if((sp->tp->type == bt_func) && sp->storage_class == sc_global )
                sp->storage_class = sc_external;

			// Increase the storage allocation by the type size.
            if(ztype == bt_union)
                nbytes = imax(nbytes,roundSize(sp->tp));
			else if(al != sc_external) {
				// If a pointer to a function is defined in a struct.
				if (isStructDecl && (sp->tp->type==bt_func || sp->tp->type==bt_ifunc))
					nbytes += 8;
				else
					nbytes += roundSize(sp->tp);
			}
            
			if (sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 && sp1->tp->type == bt_func )
            {
				sp1->tp = sp->tp;
				sp1->storage_class = sp->storage_class;
	            sp1->value.i = sp->value.i;
				sp1->IsPrototype = sp->IsPrototype;
				sp = sp1;
            }
			else {
				sp2 = search(sp->name,table);
				if (sp2 == NULL)
					insert(sp,table);
				else {
					if (funcdecl==2)
						sp2->tp = sp->tp;
					//else if (!sp2->IsPrototype)
					//	insert(sp,table);
				}
			}
			if (needParseFunction) {
				needParseFunction = FALSE;
				fn_doneinit = ParseFunction(sp);
				if (sp->tp->type != bt_pointer)
					return nbytes;
			}
   //         if(sp->tp->type == bt_ifunc) { /* function body follows */
   //             ParseFunction(sp);
   //             return nbytes;
   //         }
            if( (al == sc_global || al == sc_static || al==sc_thread) && !fn_doneinit &&
                    sp->tp->type != bt_func && sp->tp->type != bt_ifunc && sp->storage_class!=sc_typedef)
                    doinit(sp);
        }
		if (funcdecl>0) {
			if (lastst==comma || lastst==semicolon)
				break;
			if (lastst==closepa)
				goto xit1;
		}
		else if (catchdecl==TRUE) {
			if (lastst==closepa)
				goto xit1;
		}
		else if (lastst == semicolon)
			break;
		else if (lastst == assign) {
			tp1 = nameref(&ep1);
            op = en_assign;
//            NextToken();
            tp2 = asnop(&ep2);
            if( tp2 == 0 || !IsLValue(ep1) )
                  error(ERR_LVALUE);
            else    {
                    tp1 = forcefit(&ep1,tp1,&ep2,tp2);
                    ep1 = makenode(op,ep1,ep2);
                    }
			sp->initexp = ep1;
			if (lastst==semicolon)
				break;
		}

        needpunc(comma);
        if(declbegin(lastst) == 0)
                break;
        head = dhead;
    }
    NextToken();
xit1:
    return nbytes;
}
Exemplo n.º 18
0
/*
 *      process ParseSpecifierarations of the form:
 *
 *              <type>  <ParseSpecifier>, <ParseSpecifier>...;
 *
 *      leaves the ParseSpecifierarations in the symbol table pointed to by
 *      table and returns the number of bytes declared. al is the
 *      allocation type to assign, ilc is the initial location
 *      counter. if al is sc_member then no initialization will
 *      be processed. ztype should be bt_struct for normal and in
 *      structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations.
 */
int declare(TABLE *table,int al,int ilc,int ztype)
{ 
	SYM *sp, *sp1, *sp2;
    TYP *dhead;
	char stnm[200];

    static long old_nbytes;
    int nbytes;

	nbytes = 0;
    ParseSpecifier(table);
    dhead = head;
    for(;;) {
        declid = 0;
		bit_width = -1;
        ParseDeclarationPrefix(ztype==bt_union);
        if( declid != 0) {      /* otherwise just struct tag... */
            sp = allocSYM();
			sp->name = declid;
            sp->storage_class = al;
			if (bit_width > 0 && bit_offset > 0) {
				// share the storage word with the previously defined field
				nbytes = old_nbytes - ilc;
			}
			old_nbytes = ilc + nbytes;
			if (al != sc_member) {
//							sp->isTypedef = isTypedef;
				if (isTypedef)
					sp->storage_class = sc_typedef;
				isTypedef = FALSE;
			}
            while( (ilc + nbytes) % alignment(head)) {
                if( al != sc_member && al != sc_external && al != sc_auto) {
					dseg();
					GenerateByte(0);
                }
                ++nbytes;
            }
			if( al == sc_static) {
				sp->value.i = nextlabel++;
			}
			else if( ztype == bt_union)
                sp->value.i = ilc;
            else if( al != sc_auto )
                sp->value.i = ilc + nbytes;
            else
                sp->value.i = -(ilc + nbytes + head->size);

			if (bit_width == -1)
				sp->tp = head;
			else {
				sp->tp = allocTYP();
				*(sp->tp) = *head;
				sp->tp->type = bt_bitfield;
				sp->tp->size = head->size;//tp_int.size;
				sp->tp->bit_width = bit_width;
				sp->tp->bit_offset = bit_offset;
			}

            if( 
				(sp->tp->type == bt_func) && 
                    sp->storage_class == sc_global )
                    sp->storage_class = sc_external;
            if(ztype == bt_union)
                    nbytes = imax(nbytes,sp->tp->size);
            else if(al != sc_external)
                    nbytes += sp->tp->size;
            if( sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 &&
                    sp1->tp->type == bt_func )
                    {
                    sp1->tp = sp->tp;
                    sp1->storage_class = sp->storage_class;
//                                sp1->value.i = sp->value.i;
					sp1->IsPrototype = sp->IsPrototype;
                    sp = sp1;
                    }
			else {
				sp2 = search(sp->name,table);
				if (sp2 == NULL)
					insert(sp,table);
				else {
					if (funcdecl==2)
						sp2->tp = sp->tp;
					//else if (!sp2->IsPrototype)
					//	insert(sp,table);
				}
			}
            if( sp->tp->type == bt_ifunc) { /* function body follows */
                ParseFunction(sp);
                return nbytes;
            }
            if( (al == sc_global || al == sc_static) &&
                    sp->tp->type != bt_func && sp->storage_class!=sc_typedef)
                    doinit(sp);
        }
		if (funcdecl==TRUE) {
			if (lastst==comma || lastst==semicolon)
				break;
			if (lastst==closepa)
				goto xit1;
		}
		else if (catchdecl==TRUE) {
			if (lastst==closepa)
				goto xit1;
		}
		else if (lastst == semicolon)
			break;

        needpunc(comma);
        if(declbegin(lastst) == 0)
                break;
        head = dhead;
    }
    NextToken();
xit1:
    return nbytes;
}