* 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
+2004-03-05 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * 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 <hjdorn AT users.sourceforge.net>
* src/pic16/gen.c (gencjne): fixed for right=REG / left=LIT
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);
}
}
}
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;
else
$1->bitVar = bitsize;
}
+ | { $$ = newSymbol ("", NestLevel) ; }
+
;
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;
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 ;
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))
if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
fprintf (stderr, "'\n");
+ #endif
continue;
}
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 */
/*------------------------------------------------------------------*/
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 */
"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" },
};
/*
#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.
#endif
#ifdef TEST7
-enum tag
+enum tag /* IGNORE */
{
first,
second,
#ifdef TEST2
struct tag {
int good1;
- int bad;
+ int bad; /* IGNORE */
int bad; /* ERROR */
int good2;
} badstruct;
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
#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
#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