return s;
}
-/*------------------------------------------------------------------*/
-/* copyStruct - copies a structdef including the fields-list */
-/*------------------------------------------------------------------*/
-static structdef *
-copyStruct (structdef *src)
-{
- structdef *dest;
-
- dest = newStruct ("");
- memcpy (dest, src, sizeof (structdef));
- dest->fields = copySymbolChain (src->fields);
- return dest;
-}
-
/*------------------------------------------------------------------*/
/* sclsFromPtr - Return the storage class a pointer points into. */
/* S_FIXED is returned for generic pointers or other */
}
/*------------------------------------------------------------------*/
-/* 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;
}
/*------------------------------------------------------------------*/
bitOffset += loop->bitVar;
}
else {
- /* does not fit; need to realign first */
- sum++;
- loop->offset = (su == UNION ? sum = 0 : sum);
- bitOffset = 0;
- SPEC_BSTR (loop->etype) = bitOffset;
- bitOffset += loop->bitVar;
+ if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
+ /* if PIC16 && enviroment variable is set, then
+ * tightly pack bitfields, this means that when a
+ * bitfield goes beyond byte alignment, do not
+ * automatically start allocatint from next byte,
+ * but also use the available bits first */
+ fprintf(stderr, ": packing bitfields in structures\n");
+ SPEC_BSTR (loop->etype) = bitOffset;
+ bitOffset += loop->bitVar;
+ loop->offset = (su == UNION ? sum = 0 : sum);
+ } else {
+ /* does not fit; need to realign first */
+ sum++;
+ loop->offset = (su == UNION ? sum = 0 : sum);
+ bitOffset = 0;
+ SPEC_BSTR (loop->etype) = bitOffset;
+ bitOffset += loop->bitVar;
+ }
}
while (bitOffset>8) {
bitOffset -= 8;
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;
{
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)
{
memcpy (loop, curr, sizeof (sym_link)); /* copy it */
-if (getenv ("SDCCCOPYSTRUCT")) // this breaks regression test bug-221220??
- if (IS_STRUCT (loop))
- SPEC_STRUCT (loop) = copyStruct (SPEC_STRUCT (loop));
loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
loop = loop->next;
curr = curr->next;
}
else if (IS_CHAR (reType))
{
- if (op == '|' || op == '^')
- return computeTypeOr (etype1, etype2, reType);
- else if ( op == '&'
- && SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
+ /* promotion of some special cases */
+ switch (op)
{
- SPEC_USIGN (reType) = 1;
- return rType;
- }
- else if (op == '*')
- {
- SPEC_NOUN (reType) = V_INT;
- SPEC_USIGN (reType) = 0;
- return rType;
- }
- /* TODO: should be in SDCCast.c */
- else if ( op == '/'
- && ( !SPEC_USIGN (etype1)
- || !SPEC_USIGN (etype2)))
- {
- SPEC_NOUN (reType) = V_INT;
- SPEC_USIGN (reType) = 0;
- return rType;
+ case '|':
+ case '^':
+ return computeTypeOr (etype1, etype2, reType);
+ case '&':
+ if (SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
+ {
+ SPEC_USIGN (reType) = 1;
+ return rType;
+ }
+ break;
+ case '*':
+ SPEC_NOUN (reType) = V_INT;
+ SPEC_USIGN (reType) = 0;
+ return rType;
+ case '/':
+ /* if both are unsigned char then no promotion required */
+ if (!(SPEC_USIGN (etype1) && SPEC_USIGN (etype2)))
+ {
+ SPEC_NOUN (reType) = V_INT;
+ SPEC_USIGN (reType) = 0;
+ return rType;
+ }
+ break;
+ default:
+ break;
}
}
break;
}
}
+/*-----------------------------------------------------------------*/
+/* processFuncPtrArgs - does some processing with args of func ptrs*/
+/*-----------------------------------------------------------------*/
+void
+processFuncPtrArgs (sym_link * funcType)
+{
+ value *val = FUNC_ARGS(funcType);
+
+ /* if it is void then remove parameters */
+ if (val && IS_VOID (val->type))
+ {
+ FUNC_ARGS(funcType) = NULL;
+ return;
+ }
+}
+
/*-----------------------------------------------------------------*/
/* processFuncArgs - does some processing with function args */
/*-----------------------------------------------------------------*/