#include "flags.h"
#include "function.h"
#include "output.h"
-#include "expr.h"
#include "c-tree.h"
#include "toplev.h"
-#include "ggc.h"
#include "tm_p.h"
#include "cpplib.h"
#include "target.h"
#include "c-lang.h"
#include "langhooks.h"
#include "tree-mudflap.h"
-#include "gimple.h"
#include "tree-iterator.h"
#include "diagnostic.h"
#include "tree-dump.h"
#include "cgraph.h"
#include "hashtab.h"
-#include "libfuncs.h"
-#include "except.h"
#include "langhooks-def.h"
#include "pointer-set.h"
-#include "gimple.h"
#include "plugin.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
- gimple_set_body (newdecl, gimple_body (olddecl));
DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl));
for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t))
DECL_CONTEXT (t) = newdecl;
switch (TREE_CODE (olddecl))
{
case FUNCTION_DECL:
- gimple_set_body (olddecl, gimple_body (newdecl));
- /* fall through */
-
case FIELD_DECL:
case VAR_DECL:
case PARM_DECL:
Otherwise this is a forward declaration of a structure tag.
If this is something of the form "foo;" and foo is a TYPE_DECL, then
+ If foo names a structure or union without a tag, then this
+ is an anonymous struct (this is permitted by C1X).
If MS extensions are enabled and foo names a structure, then
again this is an anonymous struct.
Otherwise this is an error.
|| TREE_CODE (type) == UNION_TYPE);
bool ok = false;
- if (type_ok
- && (flag_ms_extensions || !declspecs->typedef_p))
+ if (type_ok)
{
if (flag_ms_extensions)
ok = true;
- else if (flag_iso)
- ok = false;
- else if (TYPE_NAME (type) == NULL)
+ else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL)
ok = true;
else
ok = false;
pedwarn (loc, 0, "declaration does not declare anything");
return NULL_TREE;
}
- pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions");
+ if (!flag_isoc1x)
+ {
+ if (flag_isoc99)
+ pedwarn (loc, OPT_pedantic,
+ "ISO C99 doesn%'t support unnamed structs/unions");
+ else
+ pedwarn (loc, OPT_pedantic,
+ "ISO C90 doesn%'t support unnamed structs/unions");
+ }
}
value = grokdeclarator (declarator, declspecs, FIELD, false,
return value;
}
\f
+/* Subroutine of detect_field_duplicates: add the fields of FIELDLIST
+ to HTAB, giving errors for any duplicates. */
+
+static void
+detect_field_duplicates_hash (tree fieldlist, htab_t htab)
+{
+ tree x, y;
+ void **slot;
+
+ for (x = fieldlist; x ; x = TREE_CHAIN (x))
+ if ((y = DECL_NAME (x)) != 0)
+ {
+ slot = htab_find_slot (htab, y, INSERT);
+ if (*slot)
+ {
+ error ("duplicate member %q+D", x);
+ DECL_NAME (x) = NULL_TREE;
+ }
+ *slot = y;
+ }
+ else if (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+ detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab);
+}
+
/* Generate an error for any duplicate field names in FIELDLIST. Munge
the list such that this does not present a problem later. */
return;
do {
timeout--;
+ if (DECL_NAME (x) == NULL_TREE
+ && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
+ timeout = 0;
x = TREE_CHAIN (x);
} while (timeout > 0 && x);
- /* If there were "few" fields, avoid the overhead of allocating
- a hash table. Instead just do the nested traversal thing. */
+ /* If there were "few" fields and no anonymous structures or unions,
+ avoid the overhead of allocating a hash table. Instead just do
+ the nested traversal thing. */
if (timeout > 0)
{
for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x))
else
{
htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
- void **slot;
-
- for (x = fieldlist; x ; x = TREE_CHAIN (x))
- if ((y = DECL_NAME (x)) != 0)
- {
- slot = htab_find_slot (htab, y, INSERT);
- if (*slot)
- {
- error ("duplicate member %q+D", x);
- DECL_NAME (x) = NULL_TREE;
- }
- *slot = y;
- }
+ detect_field_duplicates_hash (fieldlist, htab);
htab_delete (htab);
}
}
if (pedantic)
{
for (x = fieldlist; x; x = TREE_CHAIN (x))
- if (DECL_NAME (x) != 0)
- break;
+ {
+ if (DECL_NAME (x) != 0)
+ break;
+ if (flag_isoc1x
+ && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
+ break;
+ }
if (x == 0)
{
pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic,
"invalid use of structure with flexible array member");
- if (DECL_NAME (x))
+ if (DECL_NAME (x)
+ || TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
saw_named_field = 1;
}