From 26c13c60e4326b4a0d3b026c42df0e2a195d8ad3 Mon Sep 17 00:00:00 2001 From: epetrich Date: Fri, 5 Mar 2004 07:15:07 +0000 Subject: [PATCH] * support/Util/SDCCerr.h, * support/Util/SDCCerr.c, * src/SDCC.y (struct_or_union_specifier, enum_specifier, enumerator_list), * src/SDCCsymt.c (addSymChain): show location of oriignal definition for symbol conflicts. * support/valdiags/tests/enum.c, * support/valdiags/tests/tentdecl.c, * support/valdiags/tests/struct.c: expect possible error messages referring to original symbol definitions. * src/SDCC.y (struct_or_union_specifier, struct_declarator), * src/SDCCsymt.h, * src/SDCCsymt.c (promoteAnonStructs): support anonymous struct/union git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3245 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 16 ++++++++ src/SDCC.y | 18 +++++++-- src/SDCCsymt.c | 68 ++++++++++++++++++++++++++++++++ src/SDCCsymt.h | 1 + support/Util/SDCCerr.c | 2 + support/Util/SDCCerr.h | 1 + support/valdiag/tests/enum.c | 2 +- support/valdiag/tests/struct.c | 30 +++++++++++++- support/valdiag/tests/tentdecl.c | 10 ++--- 9 files changed, 137 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47c6e48e..ee52289c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2004-03-05 Erik Petrich + + * support/Util/SDCCerr.h, + * support/Util/SDCCerr.c, + * src/SDCC.y (struct_or_union_specifier, enum_specifier, + enumerator_list), + * src/SDCCsymt.c (addSymChain): show location of oriignal definition + for symbol conflicts. + * support/valdiags/tests/enum.c, + * support/valdiags/tests/tentdecl.c, + * support/valdiags/tests/struct.c: expect possible error messages + referring to original symbol definitions. + * src/SDCC.y (struct_or_union_specifier, struct_declarator), + * src/SDCCsymt.h, + * src/SDCCsymt.c (promoteAnonStructs): support anonymous struct/union + 2004-03-03 Hans Dorn * src/pic16/gen.c (gencjne): fixed for right=REG / left=LIT diff --git a/src/SDCC.y b/src/SDCC.y index 71f238c0..c6660523 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -757,9 +757,10 @@ struct_or_union_specifier SPEC_SCLS(sym->etype) = 0; } for (dsym=sym->next; dsym; dsym=dsym->next) { - if (strcmp(sym->name, dsym->name)==0) { + if (*dsym->name && strcmp(sym->name, dsym->name)==0) { werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER, $1==STRUCT ? "struct" : "union", sym->name); + werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF); } } } @@ -768,7 +769,8 @@ struct_or_union_specifier sdef = $2 ; sdef->fields = reverseSyms($5) ; /* link the fields */ sdef->size = compStructSize($1,sdef); /* update size of */ - + promoteAnonStructs ($1, sdef); + /* Create the specifier */ $$ = newLink (SPECIFIER) ; SPEC_NOUN($$) = V_STRUCT; @@ -895,6 +897,8 @@ struct_declarator else $1->bitVar = bitsize; } + | { $$ = newSymbol ("", NestLevel) ; } + ; enum_specifier @@ -909,7 +913,10 @@ enum_specifier csym=findSym(enumTab,$2,$2->name); if ((csym && csym->level == $2->level)) - werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name); + { + werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name); + werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF); + } enumtype = newEnumType ($4); //copyLinkChain(cenum->type); SPEC_SCLS(getSpec(enumtype)) = 0; @@ -944,7 +951,10 @@ enumerator_list for (dsym=$1; dsym; dsym=dsym->next) { if (strcmp($3->name, dsym->name)==0) - werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name); + { + werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name); + werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF); + } } $3->next = $1 ; diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 43996bf3..c1c8a8ce 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1030,6 +1030,8 @@ addSymChain (symbol * symHead) werror (E_EXTERN_MISMATCH, sym->name); else werror (E_DUPLICATE, sym->name); + werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF); + #if 0 fprintf (stderr, "from type '"); printTypeChain (csym->type, stderr); if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype)) @@ -1039,6 +1041,7 @@ addSymChain (symbol * symHead) if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype)) fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype)); fprintf (stderr, "'\n"); + #endif continue; } @@ -1227,6 +1230,71 @@ compStructSize (int su, structdef * sdef) return (su == UNION ? usum : sum); } +/*-------------------------------------------------------------------*/ +/* promoteAnonStructs - promote anonymous struct/union's fields into */ +/* an enclosing struct/union */ +/*-------------------------------------------------------------------*/ +void +promoteAnonStructs (int su, structdef * sdef) +{ + symbol *field; + symbol *subfield; + symbol **tofield; + symbol *nextfield; + symbol *dupfield; + int base; + + tofield = &sdef->fields; + field = sdef->fields; + while (field) + { + nextfield = field->next; + if (!*field->name && IS_STRUCT (field->type)) + { + /* Found an anonymous struct/union. Replace it */ + /* with the fields it contains and adjust all */ + /* the offsets */ + + base = field->offset; + subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields); + if (!subfield) + continue; /* just in case it's empty */ + + *tofield = subfield; + for (;;) + { + /* check for field name conflicts resulting from promotion */ + dupfield = sdef->fields; + while (dupfield && dupfield != subfield) + { + if (*subfield->name && !strcmp (dupfield->name, subfield->name)) + { + werrorfl (subfield->fileDef, subfield->lineDef, + E_DUPLICATE_MEMBER, + su==STRUCT ? "struct" : "union", + subfield->name); + werrorfl (dupfield->fileDef, dupfield->lineDef, + E_PREVIOUS_DEF); + } + dupfield = dupfield->next; + } + + subfield->offset += base; + if (subfield->next) + subfield = subfield->next; + else + break; + } + subfield->next = nextfield; + tofield = &subfield->next; + } + else + tofield = &field->next; + field = nextfield; + } +} + + /*------------------------------------------------------------------*/ /* checkSClass - check the storage class specification */ /*------------------------------------------------------------------*/ diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 0ac55f77..49ed5eb8 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -563,6 +563,7 @@ void checkTypeSanity(sym_link *etype, char *name); sym_link *typeFromStr (char *) ; STORAGE_CLASS sclsFromPtr(sym_link *ptr); sym_link *newEnumType (symbol *); +void promoteAnonStructs (int, structdef *); extern char *nounName(sym_link *); /* noun strings */ diff --git a/support/Util/SDCCerr.c b/support/Util/SDCCerr.c index b5a92ec4..7f3b8a76 100644 --- a/support/Util/SDCCerr.c +++ b/support/Util/SDCCerr.c @@ -409,6 +409,8 @@ struct "pragma %s is deprecated, please see documentation for details" }, { E_SIZEOF_INCOMPLETE_TYPE, ERROR_LEVEL_ERROR, "sizeof applied to an incomplete type" }, +{ E_PREVIOUS_DEF, ERROR_LEVEL_ERROR, + "previously defined here" }, }; /* diff --git a/support/Util/SDCCerr.h b/support/Util/SDCCerr.h index 0565f37f..f1c3a140 100644 --- a/support/Util/SDCCerr.h +++ b/support/Util/SDCCerr.h @@ -192,6 +192,7 @@ SDCCERR - SDCC Standard error handler #define E_ENUM_NON_INTEGER 174 /* enumeration constant not an integer */ #define W_DEPRECATED_PRAGMA 175 /* deprecated pragma */ #define E_SIZEOF_INCOMPLETE_TYPE 176 /* sizeof applied to an incomplete type */ +#define E_PREVIOUS_DEF 177 /* previously defined here */ /** Describes the maximum error level that will be logged. Any level * includes all of the levels listed after it. diff --git a/support/valdiag/tests/enum.c b/support/valdiag/tests/enum.c index 78eeb00d..9ed4f6fa 100644 --- a/support/valdiag/tests/enum.c +++ b/support/valdiag/tests/enum.c @@ -63,7 +63,7 @@ enum tag #endif #ifdef TEST7 -enum tag +enum tag /* IGNORE */ { first, second, diff --git a/support/valdiag/tests/struct.c b/support/valdiag/tests/struct.c index 615024df..3e15e51a 100644 --- a/support/valdiag/tests/struct.c +++ b/support/valdiag/tests/struct.c @@ -10,7 +10,7 @@ struct tag { #ifdef TEST2 struct tag { int good1; - int bad; + int bad; /* IGNORE */ int bad; /* ERROR */ int good2; } badstruct; @@ -74,3 +74,31 @@ struct tag { int x; } ll; #endif + +#ifdef TEST8a +struct tag { + int a; /* IGNORE */ + struct { + int a; /* ERROR(SDCC) */ /* IGNORE(GCC) */ + int b; + }; +} ll; +#endif + +#ifdef TEST8b +struct tag { + int a; + struct { + int b; + int c; + }; +} ll; + +void test(void) +{ + ll.a = 1; + ll.b = 2; + ll.c = 3; +} + +#endif diff --git a/support/valdiag/tests/tentdecl.c b/support/valdiag/tests/tentdecl.c index 90bc17fd..60d29862 100644 --- a/support/valdiag/tests/tentdecl.c +++ b/support/valdiag/tests/tentdecl.c @@ -71,14 +71,14 @@ int a=1; /* ERROR */ #ifdef TEST9 #ifdef SDCC -XDATA int a; +XDATA int a; /* IGNORE */ DATA int a; /* ERROR(SDCC && !(__z80 || __gbz80)) */ #endif #endif #ifdef TEST9b #ifdef SDCC -DATA int a; +DATA int a; /* IGNORE */ XDATA int a; /* ERROR(SDCC && !(__z80 || __gbz80)) */ #endif #endif @@ -99,21 +99,21 @@ XDATA int a; #ifdef TEST9e #ifdef SDCC -extern XDATA int a; +extern XDATA int a; /* IGNORE */ DATA int a; /* ERROR(SDCC && !(__z80 || __gbz80)) */ #endif #endif #ifdef TEST9f #ifdef SDCC -extern DATA int a; +extern DATA int a; /* IGNORE */ XDATA int a; /* ERROR(SDCC && !(__z80 || __gbz80)) */ #endif #endif #ifdef TEST10 #if defined(SDCC) && !(defined(__z80) || defined(__gbz80)) -extern volatile XDATA at 0 int a; +extern volatile XDATA at 0 int a; /* IGNORE */ volatile XDATA int a; /* ERROR(SDCC && !(__z80 || __gbz80)) */ #endif #endif -- 2.47.2