X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=40e1fed661ed02d3e1d3172c0342813453db5a8c;hb=998bc7b7fc11e191943ed839f790fff34b78df3b;hp=7d10d227f6a86fc61038ab1e9638a600d368004c;hpb=e18eec8c87d6b50be0e894469ec64651b31e2b07;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 7d10d227..40e1fed6 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -328,20 +328,6 @@ newStruct (char *tag) 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 */ @@ -810,7 +796,7 @@ newBoolLink () } /*------------------------------------------------------------------*/ -/* getSize - returns size of a type chain in bits */ +/* getSize - returns size of a type chain in bytes */ /*------------------------------------------------------------------*/ unsigned int getSize (sym_link * p) @@ -874,29 +860,41 @@ 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; } /*------------------------------------------------------------------*/ @@ -1282,12 +1280,24 @@ compStructSize (int su, structdef * sdef) 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; @@ -1306,6 +1316,21 @@ compStructSize (int su, structdef * sdef) 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; @@ -1639,13 +1664,12 @@ copyLinkChain (sym_link * p) { 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 (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; @@ -1868,28 +1892,34 @@ computeType (sym_link * type1, sym_link * type2, } 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; @@ -2550,6 +2580,22 @@ void cdbStructBlock (int block) } } +/*-----------------------------------------------------------------*/ +/* 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 */ /*-----------------------------------------------------------------*/