Commit dc491a25 by Ian Lance Taylor Committed by Ian Lance Taylor

dse.c (struct store_info): Rename bitmap field to bmap.

./:	* dse.c (struct store_info): Rename bitmap field to bmap.  Change
	all uses.

	* c-decl.c (in_struct, struct_types): Remove.
	(struct c_binding): Add in_struct field.
	(c_binding_ptr): Define type, along with VEC.
	(struct c_struct_parse_info): Define.
	(struct_parse_info): New static variable.
	(bind): Initialize in_struct field.
	(start_struct): Remove enclosing_in_struct and
	enclosing_struct_types parameters.  Add
	enclosing_struct_parse_info parameter.  Change all callers.  Set
	struct_parse_info rather than in_struct and struct_types.
	(grokfield): If -Wc++-compat and there is a symbol binding for the
	field name, set the in_struct flag and push it on the
	struct_parse_info->fields vector.
	(warn_cxx_compat_finish_struct): New static function.
	(finish_struct): Remove enclosing_in_struct and
	enclosing_struct_types parameters.  Add
	enclosing_struct_parse_info parameter.  Change all callers.  Don't
	set C_TYPE_DEFINED_IN_STRUCT here.  Call
	warn_cxx_compat_finish_struct.  Free struct_parse_info and set to
	parameter.  Only push on struct_types if warn_cxx_compat.
	(finish_enum): Only push on struct_types if warn_cxx_compat.
	(declspecs_add_type): Add loc parameter.  Change all callers.
	Change all error calls to error_at.  Pass loc, not input_location,
	to pedwarn calls.  Warn if -Wc++-compat and a typedef name is
	defined in a struct.  If -Wc++-compat and parsing a struct, record
	that a typedef name was used.
	* c-parser.c (c_parser_declspecs): Get location to pass to
	declspecs_add_type.
	(c_parser_struct_or_union_specifier): Update calls to start_struct
	and finish_struct.
	* c-tree.h (struct c_struct_parse_info): Declare.
	(finish_struct, start_struct): Update declarations.
	(declspecs_add_type): Update declaration.
objc/:
	* objc-act.c (objc_in_struct, objc_struct_types): Remove.
	(objc_struct_info): New static variable.
	(objc_start_struct): Pass &objc_struct_info, not &objc_in_struct
	and &objc_struct_types, to start_struct.
	(objc_finish_struct): Likewise for finish_struct.
objcp/:
	* objcp-decl.h (start_struct): Remove in_struct and struct_types
	parameters.  Add struct_info parameter.
	(finish_struct): Likewise.
testsuite/:
	* gcc.dg/Wcxx-compat-15.c: New testcase.

From-SVN: r148709
parent 88eeff6f
2009-06-19 Ian Lance Taylor <iant@google.com> 2009-06-19 Ian Lance Taylor <iant@google.com>
* dse.c (struct store_info): Rename bitmap field to bmap. Change
all uses.
* c-decl.c (in_struct, struct_types): Remove.
(struct c_binding): Add in_struct field.
(c_binding_ptr): Define type, along with VEC.
(struct c_struct_parse_info): Define.
(struct_parse_info): New static variable.
(bind): Initialize in_struct field.
(start_struct): Remove enclosing_in_struct and
enclosing_struct_types parameters. Add
enclosing_struct_parse_info parameter. Change all callers. Set
struct_parse_info rather than in_struct and struct_types.
(grokfield): If -Wc++-compat and there is a symbol binding for the
field name, set the in_struct flag and push it on the
struct_parse_info->fields vector.
(warn_cxx_compat_finish_struct): New static function.
(finish_struct): Remove enclosing_in_struct and
enclosing_struct_types parameters. Add
enclosing_struct_parse_info parameter. Change all callers. Don't
set C_TYPE_DEFINED_IN_STRUCT here. Call
warn_cxx_compat_finish_struct. Free struct_parse_info and set to
parameter. Only push on struct_types if warn_cxx_compat.
(finish_enum): Only push on struct_types if warn_cxx_compat.
(declspecs_add_type): Add loc parameter. Change all callers.
Change all error calls to error_at. Pass loc, not input_location,
to pedwarn calls. Warn if -Wc++-compat and a typedef name is
defined in a struct. If -Wc++-compat and parsing a struct, record
that a typedef name was used.
* c-parser.c (c_parser_declspecs): Get location to pass to
declspecs_add_type.
(c_parser_struct_or_union_specifier): Update calls to start_struct
and finish_struct.
* c-tree.h (struct c_struct_parse_info): Declare.
(finish_struct, start_struct): Update declarations.
(declspecs_add_type): Update declaration.
2009-06-19 Ian Lance Taylor <iant@google.com>
* c-decl.c (grokdeclarator): If -Wc++-compat, warn about a global * c-decl.c (grokdeclarator): If -Wc++-compat, warn about a global
variable with an anonymous type. variable with an anonymous type.
......
...@@ -126,15 +126,6 @@ static GTY(()) struct stmt_tree_s c_stmt_tree; ...@@ -126,15 +126,6 @@ static GTY(()) struct stmt_tree_s c_stmt_tree;
tree c_break_label; tree c_break_label;
tree c_cont_label; tree c_cont_label;
/* True if we are currently parsing the fields of a struct or
union. */
static bool in_struct;
/* A list of types defined in the current struct or union. */
static VEC(tree,heap) *struct_types;
/* Linked list of TRANSLATION_UNIT_DECLS for the translation units /* Linked list of TRANSLATION_UNIT_DECLS for the translation units
included in this invocation. Note that the current translation included in this invocation. Note that the current translation
unit is not included in this list. */ unit is not included in this list. */
...@@ -223,7 +214,7 @@ struct GTY((chain_next ("%h.prev"))) c_binding { ...@@ -223,7 +214,7 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
BOOL_BITFIELD invisible : 1; /* normal lookup should ignore this binding */ BOOL_BITFIELD invisible : 1; /* normal lookup should ignore this binding */
BOOL_BITFIELD nested : 1; /* do not set DECL_CONTEXT when popping */ BOOL_BITFIELD nested : 1; /* do not set DECL_CONTEXT when popping */
BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */ BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */
/* one free bit */ BOOL_BITFIELD in_struct : 1; /* currently defined as struct field */
location_t locus; /* location for nested bindings */ location_t locus; /* location for nested bindings */
}; };
#define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth) #define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
...@@ -513,6 +504,34 @@ static bool keep_next_level_flag; ...@@ -513,6 +504,34 @@ static bool keep_next_level_flag;
static bool next_is_function_body; static bool next_is_function_body;
/* A VEC of pointers to c_binding structures. */
typedef struct c_binding *c_binding_ptr;
DEF_VEC_P(c_binding_ptr);
DEF_VEC_ALLOC_P(c_binding_ptr,heap);
/* Information that we keep for a struct or union while it is being
parsed. */
struct c_struct_parse_info
{
/* If warn_cxx_compat, a list of types defined within this
struct. */
VEC(tree,heap) *struct_types;
/* If warn_cxx_compat, a list of field names which have bindings,
and which are defined in this struct, but which are not defined
in any enclosing struct. This is used to clear the in_struct
field of the c_bindings structure. */
VEC(c_binding_ptr,heap) *fields;
/* If warn_cxx_compat, a list of typedef names used when defining
fields in this struct. */
VEC(tree,heap) *typedefs_seen;
};
/* Information for the struct or union currently being parsed, or
NULL if not parsing a struct or union. */
static struct c_struct_parse_info *struct_parse_info;
/* Forward declarations. */ /* Forward declarations. */
static tree lookup_name_in_scope (tree, struct c_scope *); static tree lookup_name_in_scope (tree, struct c_scope *);
static tree c_make_fname_decl (location_t, tree, int); static tree c_make_fname_decl (location_t, tree, int);
...@@ -588,6 +607,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, ...@@ -588,6 +607,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
b->invisible = invisible; b->invisible = invisible;
b->nested = nested; b->nested = nested;
b->inner_comp = 0; b->inner_comp = 0;
b->in_struct = 0;
b->locus = locus; b->locus = locus;
b->u.type = NULL; b->u.type = NULL;
...@@ -6289,16 +6309,14 @@ xref_tag (enum tree_code code, tree name) ...@@ -6289,16 +6309,14 @@ xref_tag (enum tree_code code, tree name)
LOC is the location of the struct's definition. LOC is the location of the struct's definition.
CODE says which kind of tag NAME ought to be. CODE says which kind of tag NAME ought to be.
This stores the current value of the file static IN_STRUCT in This stores the current value of the file static STRUCT_PARSE_INFO
*ENCLOSING_IN_STRUCT, and sets IN_STRUCT to true. Similarly, this in *ENCLOSING_STRUCT_PARSE_INFO, and points STRUCT_PARSE_INFO at a
sets STRUCT_TYPES in *ENCLOSING_STRUCT_TYPES, and sets STRUCT_TYPES new c_struct_parse_info structure. The old value of
to an empty vector. The old values are restored in STRUCT_PARSE_INFO is restored in finish_struct. */
finish_struct. */
tree tree
start_struct (location_t loc, enum tree_code code, tree name, start_struct (location_t loc, enum tree_code code, tree name,
bool *enclosing_in_struct, struct c_struct_parse_info **enclosing_struct_parse_info)
VEC(tree,heap) **enclosing_struct_types)
{ {
/* If there is already a tag defined at this scope /* If there is already a tag defined at this scope
(as a forward reference), just return it. */ (as a forward reference), just return it. */
...@@ -6346,10 +6364,11 @@ start_struct (location_t loc, enum tree_code code, tree name, ...@@ -6346,10 +6364,11 @@ start_struct (location_t loc, enum tree_code code, tree name,
C_TYPE_BEING_DEFINED (ref) = 1; C_TYPE_BEING_DEFINED (ref) = 1;
TYPE_PACKED (ref) = flag_pack_struct; TYPE_PACKED (ref) = flag_pack_struct;
*enclosing_in_struct = in_struct; *enclosing_struct_parse_info = struct_parse_info;
*enclosing_struct_types = struct_types; struct_parse_info = XNEW (struct c_struct_parse_info);
in_struct = true; struct_parse_info->struct_types = VEC_alloc (tree, heap, 0);
struct_types = VEC_alloc(tree, heap, 0); struct_parse_info->fields = VEC_alloc (c_binding_ptr, heap, 0);
struct_parse_info->typedefs_seen = VEC_alloc (tree, heap, 0);
/* FIXME: This will issue a warning for a use of a type defined /* FIXME: This will issue a warning for a use of a type defined
within a statement expr used within sizeof, et. al. This is not within a statement expr used within sizeof, et. al. This is not
...@@ -6437,6 +6456,25 @@ grokfield (location_t loc, ...@@ -6437,6 +6456,25 @@ grokfield (location_t loc,
finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE); finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width; DECL_INITIAL (value) = width;
if (warn_cxx_compat && DECL_NAME (value) != NULL_TREE)
{
/* If we currently have a binding for this field, set the
in_struct field in the binding, so that we warn about lookups
which find it. */
struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (value));
if (b != NULL)
{
/* If the in_struct field is not yet set, push it on a list
to be cleared when this struct is finished. */
if (!b->in_struct)
{
VEC_safe_push (c_binding_ptr, heap,
struct_parse_info->fields, b);
b->in_struct = 1;
}
}
}
return value; return value;
} }
...@@ -6497,25 +6535,80 @@ detect_field_duplicates (tree fieldlist) ...@@ -6497,25 +6535,80 @@ detect_field_duplicates (tree fieldlist)
} }
} }
/* Finish up struct info used by -Wc++-compat. */
static void
warn_cxx_compat_finish_struct (tree fieldlist)
{
unsigned int ix;
tree x;
struct c_binding *b;
/* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
the current struct. We do this now at the end of the struct
because the flag is used to issue visibility warnings, and we
only want to issue those warnings if the type is referenced
outside of the struct declaration. */
for (ix = 0; VEC_iterate (tree, struct_parse_info->struct_types, ix, x); ++ix)
C_TYPE_DEFINED_IN_STRUCT (x) = 1;
/* The TYPEDEFS_SEEN field of STRUCT_PARSE_INFO is a list of
typedefs used when declaring fields in this struct. If the name
of any of the fields is also a typedef name then the struct would
not parse in C++, because the C++ lookup rules say that the
typedef name would be looked up in the context of the struct, and
would thus be the field rather than the typedef. */
if (!VEC_empty (tree, struct_parse_info->typedefs_seen)
&& fieldlist != NULL_TREE)
{
/* Use a pointer_set using the name of the typedef. We can use
a pointer_set because identifiers are interned. */
struct pointer_set_t *tset = pointer_set_create ();
for (ix = 0;
VEC_iterate (tree, struct_parse_info->typedefs_seen, ix, x);
++ix)
pointer_set_insert (tset, DECL_NAME (x));
for (x = fieldlist; x != NULL_TREE; x = TREE_CHAIN (x))
{
if (pointer_set_contains (tset, DECL_NAME (x)))
{
warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
("using %qD as both field and typedef name is "
"invalid in C++"),
x);
/* FIXME: It would be nice to report the location where
the typedef name is used. */
}
}
pointer_set_destroy (tset);
}
/* For each field which has a binding and which was not defined in
an enclosing struct, clear the in_struct field. */
for (ix = 0;
VEC_iterate (c_binding_ptr, struct_parse_info->fields, ix, b);
++ix)
b->in_struct = 0;
}
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
LOC is the location of the RECORD_TYPE or UNION_TYPE's definition. LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
FIELDLIST is a chain of FIELD_DECL nodes for the fields. FIELDLIST is a chain of FIELD_DECL nodes for the fields.
ATTRIBUTES are attributes to be applied to the structure. ATTRIBUTES are attributes to be applied to the structure.
ENCLOSING_IN_STRUCT is the value of IN_STRUCT, and ENCLOSING_STRUCT_PARSE_INFO is the value of STRUCT_PARSE_INFO when
ENCLOSING_STRUCT_TYPES is the value of STRUCT_TYPES, when the the struct was started. */
struct was started. This sets the C_TYPE_DEFINED_IN_STRUCT flag
for any type defined in the current struct. */
tree tree
finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
bool enclosing_in_struct, struct c_struct_parse_info *enclosing_struct_parse_info)
VEC(tree,heap) *enclosing_struct_types)
{ {
tree x; tree x;
bool toplevel = file_scope == current_scope; bool toplevel = file_scope == current_scope;
int saw_named_field; int saw_named_field;
unsigned int ix;
/* If this type was previously laid out as a forward reference, /* If this type was previously laid out as a forward reference,
make sure we lay it out again. */ make sure we lay it out again. */
...@@ -6773,23 +6866,22 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, ...@@ -6773,23 +6866,22 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
add_stmt (build_stmt (loc, add_stmt (build_stmt (loc,
DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t))); DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
/* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in if (warn_cxx_compat)
the current struct. We do this now at the end of the struct warn_cxx_compat_finish_struct (fieldlist);
because the flag is used to issue visibility warnings when using
-Wc++-compat, and we only want to issue those warnings if the
type is referenced outside of the struct declaration. */
for (ix = 0; VEC_iterate (tree, struct_types, ix, x); ++ix)
C_TYPE_DEFINED_IN_STRUCT (x) = 1;
VEC_free (tree, heap, struct_types); VEC_free (tree, heap, struct_parse_info->struct_types);
VEC_free (c_binding_ptr, heap, struct_parse_info->fields);
VEC_free (tree, heap, struct_parse_info->typedefs_seen);
XDELETE (struct_parse_info);
in_struct = enclosing_in_struct; struct_parse_info = enclosing_struct_parse_info;
struct_types = enclosing_struct_types;
/* If this struct is defined inside a struct, add it to /* If this struct is defined inside a struct, add it to
STRUCT_TYPES. */ struct_types. */
if (in_struct && !in_sizeof && !in_typeof && !in_alignof) if (warn_cxx_compat
VEC_safe_push (tree, heap, struct_types, t); && struct_parse_info != NULL
&& !in_sizeof && !in_typeof && !in_alignof)
VEC_safe_push (tree, heap, struct_parse_info->struct_types, t);
return t; return t;
} }
...@@ -7003,9 +7095,11 @@ finish_enum (tree enumtype, tree values, tree attributes) ...@@ -7003,9 +7095,11 @@ finish_enum (tree enumtype, tree values, tree attributes)
rest_of_type_compilation (enumtype, toplevel); rest_of_type_compilation (enumtype, toplevel);
/* If this enum is defined inside a struct, add it to /* If this enum is defined inside a struct, add it to
STRUCT_TYPES. */ struct_types. */
if (in_struct && !in_sizeof && !in_typeof && !in_alignof) if (warn_cxx_compat
VEC_safe_push (tree, heap, struct_types, enumtype); && struct_parse_info != NULL
&& !in_sizeof && !in_typeof && !in_alignof)
VEC_safe_push (tree, heap, struct_parse_info->struct_types, enumtype);
return enumtype; return enumtype;
} }
...@@ -8267,7 +8361,8 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual) ...@@ -8267,7 +8361,8 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
returning SPECS. */ returning SPECS. */
struct c_declspecs * struct c_declspecs *
declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) declspecs_add_type (location_t loc, struct c_declspecs *specs,
struct c_typespec spec)
{ {
tree type = spec.spec; tree type = spec.spec;
specs->non_sc_seen_p = true; specs->non_sc_seen_p = true;
...@@ -8284,7 +8379,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8284,7 +8379,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
enum rid i = C_RID_CODE (type); enum rid i = C_RID_CODE (type);
if (specs->type) if (specs->type)
{ {
error ("two or more data types in declaration specifiers"); error_at (loc, "two or more data types in declaration specifiers");
return specs; return specs;
} }
if ((int) i <= (int) RID_LAST_MODIFIER) if ((int) i <= (int) RID_LAST_MODIFIER)
...@@ -8296,203 +8391,257 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8296,203 +8391,257 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
case RID_LONG: case RID_LONG:
if (specs->long_long_p) if (specs->long_long_p)
{ {
error ("%<long long long%> is too long for GCC"); error_at (loc, "%<long long long%> is too long for GCC");
break; break;
} }
if (specs->long_p) if (specs->long_p)
{ {
if (specs->typespec_word == cts_double) if (specs->typespec_word == cts_double)
{ {
error ("both %<long long%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<long long%> and %<double%> in "
"declaration specifiers"));
break; break;
} }
pedwarn_c90 (input_location, OPT_Wlong_long, pedwarn_c90 (loc, OPT_Wlong_long,
"ISO C90 does not support %<long long%>"); "ISO C90 does not support %<long long%>");
specs->long_long_p = 1; specs->long_long_p = 1;
break; break;
} }
if (specs->short_p) if (specs->short_p)
error ("both %<long%> and %<short%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<short%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void) else if (specs->typespec_word == cts_void)
error ("both %<long%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_bool) else if (specs->typespec_word == cts_bool)
error ("both %<long%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_char) else if (specs->typespec_word == cts_char)
error ("both %<long%> and %<char%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<char%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_float) else if (specs->typespec_word == cts_float)
error ("both %<long%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<float%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32) else if (specs->typespec_word == cts_dfloat32)
error ("both %<long%> and %<_Decimal32%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<_Decimal32%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64) else if (specs->typespec_word == cts_dfloat64)
error ("both %<long%> and %<_Decimal64%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<_Decimal64%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128) else if (specs->typespec_word == cts_dfloat128)
error ("both %<long%> and %<_Decimal128%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<_Decimal128%> in "
"declaration specifiers"));
else else
specs->long_p = true; specs->long_p = true;
break; break;
case RID_SHORT: case RID_SHORT:
dupe = specs->short_p; dupe = specs->short_p;
if (specs->long_p) if (specs->long_p)
error ("both %<long%> and %<short%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<short%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void) else if (specs->typespec_word == cts_void)
error ("both %<short%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_bool) else if (specs->typespec_word == cts_bool)
error ("both %<short%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_char) else if (specs->typespec_word == cts_char)
error ("both %<short%> and %<char%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<char%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_float) else if (specs->typespec_word == cts_float)
error ("both %<short%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<float%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_double) else if (specs->typespec_word == cts_double)
error ("both %<short%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<double%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32) else if (specs->typespec_word == cts_dfloat32)
error ("both %<short%> and %<_Decimal32%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<_Decimal32%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64) else if (specs->typespec_word == cts_dfloat64)
error ("both %<short%> and %<_Decimal64%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<_Decimal64%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128) else if (specs->typespec_word == cts_dfloat128)
error ("both %<short%> and %<_Decimal128%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<_Decimal128%> in "
"declaration specifiers"));
else else
specs->short_p = true; specs->short_p = true;
break; break;
case RID_SIGNED: case RID_SIGNED:
dupe = specs->signed_p; dupe = specs->signed_p;
if (specs->unsigned_p) if (specs->unsigned_p)
error ("both %<signed%> and %<unsigned%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<unsigned%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void) else if (specs->typespec_word == cts_void)
error ("both %<signed%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_bool) else if (specs->typespec_word == cts_bool)
error ("both %<signed%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_float) else if (specs->typespec_word == cts_float)
error ("both %<signed%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<float%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_double) else if (specs->typespec_word == cts_double)
error ("both %<signed%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<double%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32) else if (specs->typespec_word == cts_dfloat32)
error ("both %<signed%> and %<_Decimal32%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<_Decimal32%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64) else if (specs->typespec_word == cts_dfloat64)
error ("both %<signed%> and %<_Decimal64%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<_Decimal64%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128) else if (specs->typespec_word == cts_dfloat128)
error ("both %<signed%> and %<_Decimal128%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<_Decimal128%> in "
"declaration specifiers"));
else else
specs->signed_p = true; specs->signed_p = true;
break; break;
case RID_UNSIGNED: case RID_UNSIGNED:
dupe = specs->unsigned_p; dupe = specs->unsigned_p;
if (specs->signed_p) if (specs->signed_p)
error ("both %<signed%> and %<unsigned%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<unsigned%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void) else if (specs->typespec_word == cts_void)
error ("both %<unsigned%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_bool) else if (specs->typespec_word == cts_bool)
error ("both %<unsigned%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_float) else if (specs->typespec_word == cts_float)
error ("both %<unsigned%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<float%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_double) else if (specs->typespec_word == cts_double)
error ("both %<unsigned%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<double%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32) else if (specs->typespec_word == cts_dfloat32)
error ("both %<unsigned%> and %<_Decimal32%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<_Decimal32%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64) else if (specs->typespec_word == cts_dfloat64)
error ("both %<unsigned%> and %<_Decimal64%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<_Decimal64%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128) else if (specs->typespec_word == cts_dfloat128)
error ("both %<unsigned%> and %<_Decimal128%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<_Decimal128%> in "
"declaration specifiers"));
else else
specs->unsigned_p = true; specs->unsigned_p = true;
break; break;
case RID_COMPLEX: case RID_COMPLEX:
dupe = specs->complex_p; dupe = specs->complex_p;
if (!flag_isoc99 && !in_system_header) if (!flag_isoc99 && !in_system_header)
pedwarn (input_location, OPT_pedantic, "ISO C90 does not support complex types"); pedwarn (loc, OPT_pedantic,
"ISO C90 does not support complex types");
if (specs->typespec_word == cts_void) if (specs->typespec_word == cts_void)
error ("both %<complex%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_bool) else if (specs->typespec_word == cts_bool)
error ("both %<complex%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32) else if (specs->typespec_word == cts_dfloat32)
error ("both %<complex%> and %<_Decimal32%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Decimal32%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64) else if (specs->typespec_word == cts_dfloat64)
error ("both %<complex%> and %<_Decimal64%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Decimal64%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128) else if (specs->typespec_word == cts_dfloat128)
error ("both %<complex%> and %<_Decimal128%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Decimal128%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_fract) else if (specs->typespec_word == cts_fract)
error ("both %<complex%> and %<_Fract%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Fract%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_accum) else if (specs->typespec_word == cts_accum)
error ("both %<complex%> and %<_Accum%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Accum%> in "
"declaration specifiers"));
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<complex%> and %<_Sat%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Sat%> in "
"declaration specifiers"));
else else
specs->complex_p = true; specs->complex_p = true;
break; break;
case RID_SAT: case RID_SAT:
dupe = specs->saturating_p; dupe = specs->saturating_p;
pedwarn (input_location, OPT_pedantic, "ISO C does not support saturating types"); pedwarn (loc, OPT_pedantic,
"ISO C does not support saturating types");
if (specs->typespec_word == cts_void) if (specs->typespec_word == cts_void)
error ("both %<_Sat%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_bool) else if (specs->typespec_word == cts_bool)
error ("both %<_Sat%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_char) else if (specs->typespec_word == cts_char)
error ("both %<_Sat%> and %<char%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<char%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_int) else if (specs->typespec_word == cts_int)
error ("both %<_Sat%> and %<int%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<int%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_float) else if (specs->typespec_word == cts_float)
error ("both %<_Sat%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<float%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_double) else if (specs->typespec_word == cts_double)
error ("both %<_Sat%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<double%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32) else if (specs->typespec_word == cts_dfloat32)
error ("both %<_Sat%> and %<_Decimal32%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<_Decimal32%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat64) else if (specs->typespec_word == cts_dfloat64)
error ("both %<_Sat%> and %<_Decimal64%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<_Decimal64%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_dfloat128) else if (specs->typespec_word == cts_dfloat128)
error ("both %<_Sat%> and %<_Decimal128%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<_Decimal128%> in "
"declaration specifiers"));
else if (specs->complex_p) else if (specs->complex_p)
error ("both %<_Sat%> and %<complex%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<complex%> in "
"declaration specifiers"));
else else
specs->saturating_p = true; specs->saturating_p = true;
break; break;
...@@ -8501,7 +8650,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8501,7 +8650,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
} }
if (dupe) if (dupe)
error ("duplicate %qE", type); error_at (loc, "duplicate %qE", type);
return specs; return specs;
} }
...@@ -8511,110 +8660,137 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8511,110 +8660,137 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
"_Decimal64", "_Decimal128", "_Fract" or "_Accum". */ "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */
if (specs->typespec_word != cts_none) if (specs->typespec_word != cts_none)
{ {
error ("two or more data types in declaration specifiers"); error_at (loc,
"two or more data types in declaration specifiers");
return specs; return specs;
} }
switch (i) switch (i)
{ {
case RID_VOID: case RID_VOID:
if (specs->long_p) if (specs->long_p)
error ("both %<long%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<void%> in "
"declaration specifiers"));
else if (specs->short_p) else if (specs->short_p)
error ("both %<short%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<void%> in "
"declaration specifiers"));
else if (specs->signed_p) else if (specs->signed_p)
error ("both %<signed%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<void%> in "
"declaration specifiers"));
else if (specs->unsigned_p) else if (specs->unsigned_p)
error ("both %<unsigned%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<void%> in "
"declaration specifiers"));
else if (specs->complex_p) else if (specs->complex_p)
error ("both %<complex%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<void%> in "
"declaration specifiers"));
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<_Sat%> and %<void%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<void%> in "
"declaration specifiers"));
else else
specs->typespec_word = cts_void; specs->typespec_word = cts_void;
return specs; return specs;
case RID_BOOL: case RID_BOOL:
if (specs->long_p) if (specs->long_p)
error ("both %<long%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->short_p) else if (specs->short_p)
error ("both %<short%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->signed_p) else if (specs->signed_p)
error ("both %<signed%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->unsigned_p) else if (specs->unsigned_p)
error ("both %<unsigned%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->complex_p) else if (specs->complex_p)
error ("both %<complex%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<complex%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<_Sat%> and %<_Bool%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<_Bool%> in "
"declaration specifiers"));
else else
specs->typespec_word = cts_bool; specs->typespec_word = cts_bool;
return specs; return specs;
case RID_CHAR: case RID_CHAR:
if (specs->long_p) if (specs->long_p)
error ("both %<long%> and %<char%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<char%> in "
"declaration specifiers"));
else if (specs->short_p) else if (specs->short_p)
error ("both %<short%> and %<char%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<char%> in "
"declaration specifiers"));
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<_Sat%> and %<char%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<char%> in "
"declaration specifiers"));
else else
specs->typespec_word = cts_char; specs->typespec_word = cts_char;
return specs; return specs;
case RID_INT: case RID_INT:
if (specs->saturating_p) if (specs->saturating_p)
error ("both %<_Sat%> and %<int%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<int%> in "
"declaration specifiers"));
else else
specs->typespec_word = cts_int; specs->typespec_word = cts_int;
return specs; return specs;
case RID_FLOAT: case RID_FLOAT:
if (specs->long_p) if (specs->long_p)
error ("both %<long%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<long%> and %<float%> in "
"declaration specifiers"));
else if (specs->short_p) else if (specs->short_p)
error ("both %<short%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<float%> in "
"declaration specifiers"));
else if (specs->signed_p) else if (specs->signed_p)
error ("both %<signed%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<float%> in "
"declaration specifiers"));
else if (specs->unsigned_p) else if (specs->unsigned_p)
error ("both %<unsigned%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<float%> in "
"declaration specifiers"));
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<_Sat%> and %<float%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<float%> in "
"declaration specifiers"));
else else
specs->typespec_word = cts_float; specs->typespec_word = cts_float;
return specs; return specs;
case RID_DOUBLE: case RID_DOUBLE:
if (specs->long_long_p) if (specs->long_long_p)
error ("both %<long long%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<long long%> and %<double%> in "
"declaration specifiers"));
else if (specs->short_p) else if (specs->short_p)
error ("both %<short%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<short%> and %<double%> in "
"declaration specifiers"));
else if (specs->signed_p) else if (specs->signed_p)
error ("both %<signed%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<signed%> and %<double%> in "
"declaration specifiers"));
else if (specs->unsigned_p) else if (specs->unsigned_p)
error ("both %<unsigned%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<unsigned%> and %<double%> in "
"declaration specifiers"));
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<_Sat%> and %<double%> in " error_at (loc,
"declaration specifiers"); ("both %<_Sat%> and %<double%> in "
"declaration specifiers"));
else else
specs->typespec_word = cts_double; specs->typespec_word = cts_double;
return specs; return specs;
...@@ -8630,26 +8806,40 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8630,26 +8806,40 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else else
str = "_Decimal128"; str = "_Decimal128";
if (specs->long_long_p) if (specs->long_long_p)
error ("both %<long long%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<long long%> and %<%s%> in "
"declaration specifiers"),
str);
if (specs->long_p) if (specs->long_p)
error ("both %<long%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<long%> and %<%s%> in "
"declaration specifiers"),
str);
else if (specs->short_p) else if (specs->short_p)
error ("both %<short%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<short%> and %<%s%> in "
"declaration specifiers"),
str);
else if (specs->signed_p) else if (specs->signed_p)
error ("both %<signed%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<signed%> and %<%s%> in "
"declaration specifiers"),
str);
else if (specs->unsigned_p) else if (specs->unsigned_p)
error ("both %<unsigned%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<unsigned%> and %<%s%> in "
"declaration specifiers"),
str);
else if (specs->complex_p) else if (specs->complex_p)
error ("both %<complex%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<complex%> and %<%s%> in "
"declaration specifiers"),
str);
else if (specs->saturating_p) else if (specs->saturating_p)
error ("both %<_Sat%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<_Sat%> and %<%s%> in "
"declaration specifiers"),
str);
else if (i == RID_DFLOAT32) else if (i == RID_DFLOAT32)
specs->typespec_word = cts_dfloat32; specs->typespec_word = cts_dfloat32;
else if (i == RID_DFLOAT64) else if (i == RID_DFLOAT64)
...@@ -8658,8 +8848,10 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8658,8 +8848,10 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
specs->typespec_word = cts_dfloat128; specs->typespec_word = cts_dfloat128;
} }
if (!targetm.decimal_float_supported_p ()) if (!targetm.decimal_float_supported_p ())
error ("decimal floating point not supported for this target"); error_at (loc,
pedwarn (input_location, OPT_pedantic, ("decimal floating point not supported "
"for this target"));
pedwarn (loc, OPT_pedantic,
"ISO C does not support decimal floating point"); "ISO C does not support decimal floating point");
return specs; return specs;
case RID_FRACT: case RID_FRACT:
...@@ -8671,16 +8863,19 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8671,16 +8863,19 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
else else
str = "_Accum"; str = "_Accum";
if (specs->complex_p) if (specs->complex_p)
error ("both %<complex%> and %<%s%> in " error_at (loc,
"declaration specifiers", str); ("both %<complex%> and %<%s%> in "
"declaration specifiers"),
str);
else if (i == RID_FRACT) else if (i == RID_FRACT)
specs->typespec_word = cts_fract; specs->typespec_word = cts_fract;
else else
specs->typespec_word = cts_accum; specs->typespec_word = cts_accum;
} }
if (!targetm.fixed_point_supported_p ()) if (!targetm.fixed_point_supported_p ())
error ("fixed-point types not supported for this target"); error_at (loc,
pedwarn (input_location, OPT_pedantic, "fixed-point types not supported for this target");
pedwarn (loc, OPT_pedantic,
"ISO C does not support fixed-point types"); "ISO C does not support fixed-point types");
return specs; return specs;
default: default:
...@@ -8698,7 +8893,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8698,7 +8893,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
if (specs->type || specs->typespec_word != cts_none if (specs->type || specs->typespec_word != cts_none
|| specs->long_p || specs->short_p || specs->signed_p || specs->long_p || specs->short_p || specs->signed_p
|| specs->unsigned_p || specs->complex_p) || specs->unsigned_p || specs->complex_p)
error ("two or more data types in declaration specifiers"); error_at (loc, "two or more data types in declaration specifiers");
else if (TREE_CODE (type) == TYPE_DECL) else if (TREE_CODE (type) == TYPE_DECL)
{ {
if (TREE_TYPE (type) == error_mark_node) if (TREE_TYPE (type) == error_mark_node)
...@@ -8709,13 +8904,26 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) ...@@ -8709,13 +8904,26 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
specs->decl_attr = DECL_ATTRIBUTES (type); specs->decl_attr = DECL_ATTRIBUTES (type);
specs->typedef_p = true; specs->typedef_p = true;
specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type); specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
/* If this typedef name is defined in a struct, then a C++
lookup would return a different value. */
if (warn_cxx_compat
&& I_SYMBOL_BINDING (DECL_NAME (type))->in_struct)
warning_at (loc, OPT_Wc___compat,
"C++ lookup of %qD would return a field, not a type",
type);
/* If we are parsing a struct, record that a struct field
used a typedef. */
if (warn_cxx_compat && struct_parse_info != NULL)
VEC_safe_push (tree, heap, struct_parse_info->typedefs_seen, type);
} }
} }
else if (TREE_CODE (type) == IDENTIFIER_NODE) else if (TREE_CODE (type) == IDENTIFIER_NODE)
{ {
tree t = lookup_name (type); tree t = lookup_name (type);
if (!t || TREE_CODE (t) != TYPE_DECL) if (!t || TREE_CODE (t) != TYPE_DECL)
error ("%qE fails to be a typedef or built in type", type); error_at (loc, "%qE fails to be a typedef or built in type", type);
else if (TREE_TYPE (t) == error_mark_node) else if (TREE_TYPE (t) == error_mark_node)
; ;
else else
......
...@@ -1447,6 +1447,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1447,6 +1447,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
{ {
struct c_typespec t; struct c_typespec t;
tree attrs; tree attrs;
location_t loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_NAME)) if (c_parser_next_token_is (parser, CPP_NAME))
{ {
tree value = c_parser_peek_token (parser)->value; tree value = c_parser_peek_token (parser)->value;
...@@ -1482,7 +1483,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1482,7 +1483,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t.expr = NULL_TREE; t.expr = NULL_TREE;
t.expr_const_operands = true; t.expr_const_operands = true;
} }
declspecs_add_type (specs, t); declspecs_add_type (loc, specs, t);
continue; continue;
} }
if (c_parser_next_token_is (parser, CPP_LESS)) if (c_parser_next_token_is (parser, CPP_LESS))
...@@ -1498,7 +1499,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1498,7 +1499,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
t.expr = NULL_TREE; t.expr = NULL_TREE;
t.expr_const_operands = true; t.expr_const_operands = true;
declspecs_add_type (specs, t); declspecs_add_type (loc, specs, t);
continue; continue;
} }
gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD)); gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
...@@ -1547,7 +1548,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1547,7 +1548,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t.spec = c_parser_peek_token (parser)->value; t.spec = c_parser_peek_token (parser)->value;
t.expr = NULL_TREE; t.expr = NULL_TREE;
t.expr_const_operands = true; t.expr_const_operands = true;
declspecs_add_type (specs, t); declspecs_add_type (loc, specs, t);
c_parser_consume_token (parser); c_parser_consume_token (parser);
break; break;
case RID_ENUM: case RID_ENUM:
...@@ -1556,7 +1557,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1556,7 +1557,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs_ok = true; attrs_ok = true;
seen_type = true; seen_type = true;
t = c_parser_enum_specifier (parser); t = c_parser_enum_specifier (parser);
declspecs_add_type (specs, t); declspecs_add_type (loc, specs, t);
break; break;
case RID_STRUCT: case RID_STRUCT:
case RID_UNION: case RID_UNION:
...@@ -1566,7 +1567,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1566,7 +1567,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
seen_type = true; seen_type = true;
t = c_parser_struct_or_union_specifier (parser); t = c_parser_struct_or_union_specifier (parser);
invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
declspecs_add_type (specs, t); declspecs_add_type (loc, specs, t);
break; break;
case RID_TYPEOF: case RID_TYPEOF:
/* ??? The old parser rejected typeof after other type /* ??? The old parser rejected typeof after other type
...@@ -1577,7 +1578,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, ...@@ -1577,7 +1578,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs_ok = true; attrs_ok = true;
seen_type = true; seen_type = true;
t = c_parser_typeof_specifier (parser); t = c_parser_typeof_specifier (parser);
declspecs_add_type (specs, t); declspecs_add_type (loc, specs, t);
break; break;
case RID_CONST: case RID_CONST:
case RID_VOLATILE: case RID_VOLATILE:
...@@ -1815,10 +1816,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) ...@@ -1815,10 +1816,8 @@ c_parser_struct_or_union_specifier (c_parser *parser)
{ {
/* Parse a struct or union definition. Start the scope of the /* Parse a struct or union definition. Start the scope of the
tag before parsing components. */ tag before parsing components. */
bool in_struct; struct c_struct_parse_info *struct_info;
VEC(tree,heap) *struct_types; tree type = start_struct (struct_loc, code, ident, &struct_info);
tree type = start_struct (struct_loc, code, ident,
&in_struct, &struct_types);
tree postfix_attrs; tree postfix_attrs;
/* We chain the components in reverse order, then put them in /* We chain the components in reverse order, then put them in
forward order at the end. Each struct-declaration may forward order at the end. Each struct-declaration may
...@@ -1908,8 +1907,7 @@ c_parser_struct_or_union_specifier (c_parser *parser) ...@@ -1908,8 +1907,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
} }
postfix_attrs = c_parser_attributes (parser); postfix_attrs = c_parser_attributes (parser);
ret.spec = finish_struct (struct_loc, type, nreverse (contents), ret.spec = finish_struct (struct_loc, type, nreverse (contents),
chainon (attrs, postfix_attrs), chainon (attrs, postfix_attrs), struct_info);
in_struct, struct_types);
ret.kind = ctsk_tagdef; ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE; ret.expr = NULL_TREE;
ret.expr_const_operands = true; ret.expr_const_operands = true;
......
...@@ -430,6 +430,7 @@ extern void gen_aux_info_record (tree, int, int, int); ...@@ -430,6 +430,7 @@ extern void gen_aux_info_record (tree, int, int, int);
/* in c-decl.c */ /* in c-decl.c */
struct c_spot_bindings; struct c_spot_bindings;
struct c_struct_parse_info;
extern struct obstack parser_obstack; extern struct obstack parser_obstack;
extern tree c_break_label; extern tree c_break_label;
extern tree c_cont_label; extern tree c_cont_label;
...@@ -465,7 +466,8 @@ extern void c_maybe_initialize_eh (void); ...@@ -465,7 +466,8 @@ extern void c_maybe_initialize_eh (void);
extern void finish_decl (tree, location_t, tree, tree, tree); extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree); extern tree finish_enum (tree, tree, tree);
extern void finish_function (void); extern void finish_function (void);
extern tree finish_struct (location_t, tree, tree, tree, bool, VEC(tree,heap) *); extern tree finish_struct (location_t, tree, tree, tree,
struct c_struct_parse_info *);
extern struct c_arg_info *get_parm_info (bool); extern struct c_arg_info *get_parm_info (bool);
extern tree grokfield (location_t, struct c_declarator *, extern tree grokfield (location_t, struct c_declarator *,
struct c_declspecs *, tree, tree *); struct c_declspecs *, tree, tree *);
...@@ -487,7 +489,8 @@ extern tree start_enum (location_t, struct c_enum_contents *, tree); ...@@ -487,7 +489,8 @@ extern tree start_enum (location_t, struct c_enum_contents *, tree);
extern int start_function (struct c_declspecs *, struct c_declarator *, tree); extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool, extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
tree); tree);
extern tree start_struct (location_t, enum tree_code, tree, bool *, VEC(tree,heap) **); extern tree start_struct (location_t, enum tree_code, tree,
struct c_struct_parse_info **);
extern void store_parm_decls (void); extern void store_parm_decls (void);
extern void store_parm_decls_from (struct c_arg_info *); extern void store_parm_decls_from (struct c_arg_info *);
extern tree xref_tag (enum tree_code, tree); extern tree xref_tag (enum tree_code, tree);
...@@ -504,7 +507,8 @@ extern struct c_declarator *make_pointer_declarator (struct c_declspecs *, ...@@ -504,7 +507,8 @@ extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
struct c_declarator *); struct c_declarator *);
extern struct c_declspecs *build_null_declspecs (void); extern struct c_declspecs *build_null_declspecs (void);
extern struct c_declspecs *declspecs_add_qual (struct c_declspecs *, tree); extern struct c_declspecs *declspecs_add_qual (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_type (struct c_declspecs *, extern struct c_declspecs *declspecs_add_type (location_t,
struct c_declspecs *,
struct c_typespec); struct c_typespec);
extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree); extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree); extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
......
...@@ -244,7 +244,7 @@ struct store_info ...@@ -244,7 +244,7 @@ struct store_info
{ {
/* A bitmap with one bit per byte. Cleared bit means the position /* A bitmap with one bit per byte. Cleared bit means the position
is needed. Used if IS_LARGE is false. */ is needed. Used if IS_LARGE is false. */
bitmap bitmap; bitmap bmap;
/* Number of set bits (i.e. unneeded bytes) in BITMAP. If it is /* Number of set bits (i.e. unneeded bytes) in BITMAP. If it is
equal to END - BEGIN, the whole store is unused. */ equal to END - BEGIN, the whole store is unused. */
...@@ -791,7 +791,7 @@ free_store_info (insn_info_t insn_info) ...@@ -791,7 +791,7 @@ free_store_info (insn_info_t insn_info)
{ {
store_info_t next = store_info->next; store_info_t next = store_info->next;
if (store_info->is_large) if (store_info->is_large)
BITMAP_FREE (store_info->positions_needed.large.bitmap); BITMAP_FREE (store_info->positions_needed.large.bmap);
if (store_info->cse_base) if (store_info->cse_base)
pool_free (cse_store_info_pool, store_info); pool_free (cse_store_info_pool, store_info);
else else
...@@ -1213,10 +1213,10 @@ set_position_unneeded (store_info_t s_info, int pos) ...@@ -1213,10 +1213,10 @@ set_position_unneeded (store_info_t s_info, int pos)
{ {
if (__builtin_expect (s_info->is_large, false)) if (__builtin_expect (s_info->is_large, false))
{ {
if (!bitmap_bit_p (s_info->positions_needed.large.bitmap, pos)) if (!bitmap_bit_p (s_info->positions_needed.large.bmap, pos))
{ {
s_info->positions_needed.large.count++; s_info->positions_needed.large.count++;
bitmap_set_bit (s_info->positions_needed.large.bitmap, pos); bitmap_set_bit (s_info->positions_needed.large.bmap, pos);
} }
} }
else else
...@@ -1233,7 +1233,7 @@ set_all_positions_unneeded (store_info_t s_info) ...@@ -1233,7 +1233,7 @@ set_all_positions_unneeded (store_info_t s_info)
{ {
int pos, end = s_info->end - s_info->begin; int pos, end = s_info->end - s_info->begin;
for (pos = 0; pos < end; pos++) for (pos = 0; pos < end; pos++)
bitmap_set_bit (s_info->positions_needed.large.bitmap, pos); bitmap_set_bit (s_info->positions_needed.large.bmap, pos);
s_info->positions_needed.large.count = end; s_info->positions_needed.large.count = end;
} }
else else
...@@ -1263,7 +1263,7 @@ all_positions_needed_p (store_info_t s_info, int start, int width) ...@@ -1263,7 +1263,7 @@ all_positions_needed_p (store_info_t s_info, int start, int width)
{ {
int end = start + width; int end = start + width;
while (start < end) while (start < end)
if (bitmap_bit_p (s_info->positions_needed.large.bitmap, start++)) if (bitmap_bit_p (s_info->positions_needed.large.bmap, start++))
return false; return false;
return true; return true;
} }
...@@ -1605,7 +1605,7 @@ record_store (rtx body, bb_info_t bb_info) ...@@ -1605,7 +1605,7 @@ record_store (rtx body, bb_info_t bb_info)
{ {
store_info->is_large = true; store_info->is_large = true;
store_info->positions_needed.large.count = 0; store_info->positions_needed.large.count = 0;
store_info->positions_needed.large.bitmap = BITMAP_ALLOC (NULL); store_info->positions_needed.large.bmap = BITMAP_ALLOC (NULL);
} }
else else
{ {
...@@ -2721,7 +2721,7 @@ dse_step1 (void) ...@@ -2721,7 +2721,7 @@ dse_step1 (void)
for (s_info = ptr->store_rec; s_info; s_info = s_info->next) for (s_info = ptr->store_rec; s_info; s_info = s_info->next)
if (s_info->is_large) if (s_info->is_large)
{ {
BITMAP_FREE (s_info->positions_needed.large.bitmap); BITMAP_FREE (s_info->positions_needed.large.bmap);
s_info->is_large = false; s_info->is_large = false;
} }
} }
......
2009-06-19 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_in_struct, objc_struct_types): Remove.
(objc_struct_info): New static variable.
(objc_start_struct): Pass &objc_struct_info, not &objc_in_struct
and &objc_struct_types, to start_struct.
(objc_finish_struct): Likewise for finish_struct.
2009-06-15 Ian Lance Taylor <iant@google.com> 2009-06-15 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_start_function): Don't set * objc-act.c (objc_start_function): Don't set
......
...@@ -420,8 +420,7 @@ static int generating_instance_variables = 0; ...@@ -420,8 +420,7 @@ static int generating_instance_variables = 0;
is compiled as part of obj-c++. */ is compiled as part of obj-c++. */
static bool objc_building_struct; static bool objc_building_struct;
static bool objc_in_struct ATTRIBUTE_UNUSED; static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
static VEC(tree,heap) *objc_struct_types ATTRIBUTE_UNUSED;
/* Start building a struct for objc. */ /* Start building a struct for objc. */
...@@ -430,8 +429,7 @@ objc_start_struct (tree name) ...@@ -430,8 +429,7 @@ objc_start_struct (tree name)
{ {
gcc_assert (!objc_building_struct); gcc_assert (!objc_building_struct);
objc_building_struct = true; objc_building_struct = true;
return start_struct (input_location, RECORD_TYPE, return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
name, &objc_in_struct, &objc_struct_types);
} }
/* Finish building a struct for objc. */ /* Finish building a struct for objc. */
...@@ -442,7 +440,7 @@ objc_finish_struct (tree type, tree fieldlist) ...@@ -442,7 +440,7 @@ objc_finish_struct (tree type, tree fieldlist)
gcc_assert (objc_building_struct); gcc_assert (objc_building_struct);
objc_building_struct = false; objc_building_struct = false;
return finish_struct (input_location, type, fieldlist, NULL_TREE, return finish_struct (input_location, type, fieldlist, NULL_TREE,
objc_in_struct, objc_struct_types); objc_struct_info);
} }
/* Some platforms pass small structures through registers versus /* Some platforms pass small structures through registers versus
......
2009-06-19 Ian Lance Taylor <iant@google.com>
* objcp-decl.h (start_struct): Remove in_struct and struct_types
parameters. Add struct_info parameter.
(finish_struct): Likewise.
2009-06-13 Aldy Hernandez <aldyh@redhat.com> 2009-06-13 Aldy Hernandez <aldyh@redhat.com>
* objcp-decl.h (start_struct): Add location argument. * objcp-decl.h (start_struct): Add location argument.
......
...@@ -37,9 +37,9 @@ extern tree objcp_end_compound_stmt (tree, int); ...@@ -37,9 +37,9 @@ extern tree objcp_end_compound_stmt (tree, int);
invoke the original C++ functions if needed). */ invoke the original C++ functions if needed). */
#ifdef OBJCP_REMAP_FUNCTIONS #ifdef OBJCP_REMAP_FUNCTIONS
#define start_struct(loc, code, name, in_struct, struct_types) \ #define start_struct(loc, code, name, struct_info) \
objcp_start_struct (loc, code, name) objcp_start_struct (loc, code, name)
#define finish_struct(loc, t, fieldlist, attributes, in_struct, struct_types) \ #define finish_struct(loc, t, fieldlist, attributes, struct_info) \
objcp_finish_struct (loc, t, fieldlist, attributes) objcp_finish_struct (loc, t, fieldlist, attributes)
#define finish_function() \ #define finish_function() \
objcp_finish_function () objcp_finish_function ()
......
2009-06-19 Ian Lance Taylor <iant@google.com> 2009-06-19 Ian Lance Taylor <iant@google.com>
* gcc.dg/Wcxx-compat-15.c: New testcase.
2009-06-19 Ian Lance Taylor <iant@google.com>
* gcc.dg/Wcxx-compat-16.c: New testcase. * gcc.dg/Wcxx-compat-16.c: New testcase.
2009-06-19 Uros Bizjak <ubizjak@gmail.com> 2009-06-19 Uros Bizjak <ubizjak@gmail.com>
......
/* { dg-do compile } */
/* { dg-options "-Wc++-compat" } */
typedef int myint1;
typedef int myint2;
typedef int myint3;
struct s1
{
myint1 myint1; /* { dg-warning "invalid in C\[+\]\[+\]" } */
myint2 *myint2; /* { dg-warning "invalid in C\[+\]\[+\]" } */
int myint3;
struct s2
{
myint3 f2; /* { dg-warning "C\[+\]\[+\]" } */
} f1;
};
struct s3
{
int myint1;
struct s4
{
int myint1;
} f1;
struct s5
{
int myint1;
struct s6
{
myint1 f4; /* { dg-warning "C\[+\]\[+\]" } */
} f3;
} f2;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment