/*
 *      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;
}
Exemple #2
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;
}