}
/*------------------------------------------------------------------*/
-/* getSize - returns size of a type chain in bits */
+/* getSize - returns size of a type chain in bytes */
/*------------------------------------------------------------------*/
unsigned int
getSize (sym_link * p)
}
}
-/*---------------------------------------------------------------------*/
-/* getAllocSize - returns size of a type chain in bytes for allocation */
-/*---------------------------------------------------------------------*/
-unsigned int
-getAllocSize (sym_link *p)
+/*------------------------------------------------------------------*/
+/* checkStructFlexArray - check tree behind a struct */
+/*------------------------------------------------------------------*/
+static bool
+checkStructFlexArray (symbol *sym, sym_link *p)
{
- if (IS_STRUCT (p) && SPEC_STRUCT (p)->type == STRUCT)
- {
- /* if this is a struct specifier then */
- /* calculate the size as it could end */
- /* with an array of unspecified length */
- symbol *sflds = SPEC_STRUCT (p)->fields;
+ /* if nothing return FALSE */
+ if (!p)
+ return FALSE;
- while (sflds && sflds->next)
- sflds = sflds->next;
+ if (IS_SPEC (p))
+ {
+ /* (nested) struct with flexible array member? */
+ if (IS_STRUCT (p) && SPEC_STRUCT (p)->b_flexArrayMember)
+ {
+ werror (W_INVALID_FLEXARRAY);
+ return FALSE;
+ }
+ return FALSE;
+ }
- if (sflds && !IS_BITFIELD (sflds->type))
- return sflds->offset + getAllocSize (sflds->type);
- else
- return SPEC_STRUCT (p)->size;
+ /* this is a declarator */
+ if (IS_ARRAY (p))
+ {
+ /* flexible array member? */
+ if (!DCL_ELEM(p))
+ {
+ if (!options.std_c99)
+ werror (W_C89_NO_FLEXARRAY);
+ return TRUE;
+ }
+ /* walk tree */
+ return checkStructFlexArray (sym, p->next);
}
- else
- return getSize (p);
+ return FALSE;
}
/*------------------------------------------------------------------*/
/* change it to a unsigned bit */
SPEC_NOUN (loop->etype) = V_BITFIELD;
- SPEC_USIGN (loop->etype) = 1;
+ /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
+ /* a "plain" int bitfield is unsigned */
+ if (!loop->etype->select.s.b_signed)
+ SPEC_USIGN(loop->etype) = 1;
+
SPEC_BLEN (loop->etype) = loop->bitVar;
if (loop->bitVar == BITVAR_PAD) {
loop->offset = sum;
checkDecl (loop, 1);
sum += getSize (loop->type);
+
+ /* search for "flexibel array members" */
+ /* and do some syntax checks */
+ if ( su == STRUCT
+ && checkStructFlexArray (loop, loop->type))
+ {
+ /* found a "flexible array member" */
+ sdef->b_flexArrayMember = TRUE;
+ /* is another struct-member following? */
+ if (loop->next)
+ werror (E_FLEXARRAY_NOTATEND);
+ /* is it the first struct-member? */
+ else if (loop == sdef->fields)
+ werror (E_FLEXARRAY_INEMPTYSTRCT);
+ }
}
loop = loop->next;
/* arrays & pointers cannot be defined for bits */
/* SBITS or SFRs or BIT */
if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
+ !IS_FUNCPTR (sym->type) &&
(SPEC_NOUN (sym->etype) == V_BIT ||
SPEC_NOUN (sym->etype) == V_SBIT ||
SPEC_NOUN (sym->etype) == V_BITFIELD ||
{
sym_link *head, *curr, *loop;
+ /* note: v_struct and v_struct->fields are not copied! */
curr = p;
head = loop = (curr ? newLink (p->class) : (void *) NULL);
while (curr)
/* which ever is greater in size */
if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
rType = newFloatLink ();
- else
- /* if both are fixed16x16 then result is float */
- if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
+ /* if both are fixed16x16 then result is float */
+ else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
rType = newFixed16x16Link();
- else
- if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
+ else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
rType = newFloatLink ();
- if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
+ else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
rType = newFloatLink ();
- else
- /* if both are bitvars choose the larger one */
- if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
- {
- rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
- copyLinkChain (type1) : copyLinkChain (type1);
- }
- /* if only one of them is a bit variable
- then the other one prevails */
+
+ /* if both are bitvars choose the larger one */
+ else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
+ rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
+ copyLinkChain (type1) : copyLinkChain (type1);
+
+ /* if only one of them is a bit variable then the other one prevails */
else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
{
rType = copyLinkChain (type2);
if (getSize (etype2) > 1)
SPEC_NOUN (getSpec (rType)) = V_INT;
}
- else
- /* if one of them is a pointer or array then that
- prevails */
- if (IS_PTR (type1) || IS_ARRAY (type1))
+ /* if one of them is a pointer or array then that
+ prevails */
+ else if (IS_PTR (type1) || IS_ARRAY (type1))
rType = copyLinkChain (type1);
else if (IS_PTR (type2) || IS_ARRAY (type2))
rType = copyLinkChain (type2);
the function does not have VA_ARG
and as port dictates */
if (!IFFUNC_HASVARARGS(funcType) &&
- (argreg = (*port->reg_parm) (val->type)))
+ (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
{
SPEC_REGPARM (val->etype) = 1;
SPEC_ARGREG(val->etype) = argreg;
SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
else
SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
- (options.model != MODEL_SMALL ? xdata : data);
+ port->mem.default_local_map;
#if 0
/* ?? static functions shouldn't imply static parameters - EEP */
}
#endif
}
+ if (SPEC_OCLS (val->sym->etype) == pdata)
+ val->sym->iaccess = 1;
if (!isinSet(operKeyReset, val->sym)) {
addSet (&operKeyReset, val->sym);
applyToSet (operKeyReset, resetParmKey);
}
if (n1s > 1 || nshifts == 0)
- return 0;
+ return -1;
return nshifts - 1;
}