#define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
#define I_SYMBOL_BINDING(node) \
- (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->symbol_binding)
+ (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->symbol_binding)
#define I_SYMBOL_DECL(node) \
(I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
#define I_TAG_BINDING(node) \
- (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->tag_binding)
+ (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->tag_binding)
#define I_TAG_DECL(node) \
(I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
#define I_LABEL_BINDING(node) \
- (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->label_binding)
+ (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->label_binding)
#define I_LABEL_DECL(node) \
(I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
- chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *)TYPE_NEXT_VARIANT (&%h.generic) : (union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
+ chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : (union lang_tree_node *) TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("0"),
desc ("tree_node_structure (&%h)")))
tree type = TREE_TYPE (decl);
if (type != error_mark_node
&& TREE_CODE (type) == ARRAY_TYPE
- && ! DECL_EXTERNAL (decl)
+ && !DECL_EXTERNAL (decl)
&& TYPE_DOMAIN (type) == 0)
{
warning ("%Jarray %qD assumed to have one element", decl, decl);
case FUNCTION_DECL:
/* Propagate TREE_ADDRESSABLE from nested functions to their
containing functions. */
- if (! TREE_ASM_WRITTEN (p)
+ if (!TREE_ASM_WRITTEN (p)
&& DECL_INITIAL (p) != 0
&& TREE_ADDRESSABLE (p)
&& DECL_ABSTRACT_ORIGIN (p) != 0
&& !DECL_IN_SYSTEM_HEADER (p)
&& DECL_NAME (p)
&& !DECL_ARTIFICIAL (p)
- && (scope != file_scope
- || (TREE_STATIC (p) && !TREE_PUBLIC (p)
- && !TREE_THIS_VOLATILE (p)))
- && scope != external_scope)
+ && scope != file_scope
+ && scope != external_scope)
warning ("%Junused variable %qD", p, p);
if (b->inner_comp)
while (oldargs || newargs)
{
- if (! oldargs
- || ! newargs
- || ! TREE_VALUE (oldargs)
- || ! TREE_VALUE (newargs)
+ if (!oldargs
+ || !newargs
+ || !TREE_VALUE (oldargs)
+ || !TREE_VALUE (newargs)
|| TYPE_MODE (TREE_VALUE (oldargs))
!= TYPE_MODE (TREE_VALUE (newargs)))
return 0;
/* Type for passing arg must be consistent with that declared
for the arg. */
- else if (! comptypes (oldargtype, newargtype))
+ else if (!comptypes (oldargtype, newargtype))
{
error ("%Jprototype for %qD declares arg %d with incompatible type",
newdecl, newdecl, i);
return false;
}
+ /* Enumerators have no linkage, so may only be declared once in a
+ given scope. */
+ if (TREE_CODE (olddecl) == CONST_DECL)
+ {
+ error ("%Jredeclaration of enumerator %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+
if (!comptypes (oldtype, newtype))
{
if (TREE_CODE (olddecl) == FUNCTION_DECL
in its new location and clear TREE_ASM_WRITTEN (it's not a
forward decl anymore). */
if (TREE_CODE (newdecl) == PARM_DECL
- && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
+ && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
{
struct c_binding *b, **here;
= composite_type (newtype, oldtype);
/* Lay the type out, unless already done. */
- if (oldtype != TREE_TYPE (newdecl))
+ if (!comptypes (oldtype, TREE_TYPE (newdecl)))
{
if (TREE_TYPE (newdecl) != error_mark_node)
layout_type (TREE_TYPE (newdecl));
make_var_volatile (newdecl);
}
+ /* Merge deprecatedness. */
+ if (TREE_DEPRECATED (newdecl))
+ TREE_DEPRECATED (olddecl) = 1;
+
/* Keep source location of definition rather than declaration. */
if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
copy the attributes of NEWDECL into OLDDECL. */
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
/* If this clears `static', clear it in the identifier too. */
- if (! TREE_PUBLIC (olddecl))
+ if (!TREE_PUBLIC (olddecl))
TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
}
if (DECL_EXTERNAL (newdecl))
/* An extern decl does not override previous storage class. */
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
- if (! DECL_EXTERNAL (newdecl))
+ if (!DECL_EXTERNAL (newdecl))
{
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
}
/* Also preserve various other info from the definition. */
- if (! new_is_definition)
+ if (!new_is_definition)
{
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
/* Set DECL_INLINE on the declaration if we've got a body
from which to instantiate. */
- if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl))
+ if (DECL_INLINE (olddecl) && !DECL_UNINLINABLE (newdecl))
{
DECL_INLINE (newdecl) = 1;
DECL_ABSTRACT_ORIGIN (newdecl)
/* If a previous declaration said inline, mark the
definition as inlinable. */
if (DECL_DECLARED_INLINE_P (newdecl)
- && ! DECL_UNINLINABLE (newdecl))
+ && !DECL_UNINLINABLE (newdecl))
DECL_INLINE (newdecl) = 1;
}
}
new_decl, new_decl);
if (TREE_CODE (old_decl) != FUNCTION_DECL
- || ! DECL_BUILT_IN (old_decl))
+ || !DECL_BUILT_IN (old_decl))
warning ("%Jshadowed declaration is here", old_decl);
break;
bool nested = false;
/* Functions need the lang_decl data. */
- if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
+ if (TREE_CODE (x) == FUNCTION_DECL && !DECL_LANG_SPECIFIC (x))
DECL_LANG_SPECIFIC (x) = GGC_CNEW (struct lang_decl);
/* Must set DECL_CONTEXT for everything not at file scope or
just need to fall through to make the declaration in
this scope. */
nested = true;
+ x = visdecl;
}
else
{
{
struct c_binding *b;
tree decl = 0;
+ tree asmspec_tree;
+
for (b = I_SYMBOL_BINDING (functionid); b; b = b->shadowed)
{
if (B_IN_SCOPE (b, external_scope))
TREE_PUBLIC (decl) = 1;
C_DECL_IMPLICIT (decl) = 1;
implicit_decl_warning (functionid, 0);
+ asmspec_tree = maybe_apply_renaming_pragma (decl, /*asmname=*/NULL);
+ if (asmspec_tree)
+ set_user_assembler_name (decl, TREE_STRING_POINTER (asmspec_tree));
/* C89 says implicit declarations are in the innermost block.
So we record the decl in the standard fashion. */
{
error ("%qE undeclared (first use in this function)", id);
- if (! already)
+ if (!already)
{
error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)");
pending_invalid_xref = 0;
- if (declspecs->type && !declspecs->typedef_p)
+ if (declspecs->type && !declspecs->default_int_p && !declspecs->typedef_p)
{
tree value = declspecs->type;
enum tree_code code = TREE_CODE (value);
warned = 1;
}
- if (found_tag && (declspecs->specbits & ((1 << (int) RID_LONG)
- | (1 << (int) RID_SHORT)
- | (1 << (int) RID_UNSIGNED)
- | (1 << (int) RID_SIGNED)
- | (1 << (int) RID_COMPLEX))))
- {
- error ("long, short, signed, unsigned or complex used invalidly "
- "in empty declaration");
- warned = 1;
- }
-
if (declspecs->inline_p)
{
error ("%<inline%> in empty declaration");
warned = 2;
}
- if (!warned && !in_system_header && declspecs->specbits)
+ if (!warned && !in_system_header && (declspecs->const_p
+ || declspecs->volatile_p
+ || declspecs->restrict_p))
{
- warning ("useless keyword or type name in empty declaration");
+ warning ("useless type qualifier in empty declaration");
warned = 2;
}
}
}
\f
+
+/* Return the qualifiers from SPECS as a bitwise OR of TYPE_QUAL_*
+ bits. SPECS represents declaration specifiers that the grammar
+ only permits to contain type qualifiers and attributes. */
+
+int
+quals_from_declspecs (const struct c_declspecs *specs)
+{
+ int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0)
+ | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
+ | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0));
+ gcc_assert (!specs->type
+ && !specs->decl_attr
+ && specs->typespec_word == cts_none
+ && specs->storage_class == csc_none
+ && !specs->typedef_p
+ && !specs->explicit_signed_p
+ && !specs->deprecated_p
+ && !specs->long_p
+ && !specs->long_long_p
+ && !specs->short_p
+ && !specs->signed_p
+ && !specs->unsigned_p
+ && !specs->complex_p
+ && !specs->inline_p
+ && !specs->thread_p);
+ return quals;
+}
+
/* Construct an array declarator. EXPR is the expression inside [], or
NULL_TREE. QUALS are the type qualifiers inside the [] (to be applied
to the pointer to which a parameter array is converted). STATIC_P is
declarator->kind = cdk_array;
declarator->declarator = 0;
declarator->u.array.dimen = expr;
- declarator->u.array.quals = quals;
+ if (quals)
+ {
+ declarator->u.array.attrs = quals->attrs;
+ declarator->u.array.quals = quals_from_declspecs (quals);
+ }
+ else
+ {
+ declarator->u.array.attrs = NULL_TREE;
+ declarator->u.array.quals = 0;
+ }
declarator->u.array.static_p = static_p;
declarator->u.array.vla_unspec_p = vla_unspec_p;
if (pedantic && !flag_isoc99)
struct c_declarator *inner, bool abstract_p)
{
decl->declarator = inner;
- if (abstract_p && (decl->u.array.quals != NULL
+ if (abstract_p && (decl->u.array.quals != TYPE_UNQUALIFIED
+ || decl->u.array.attrs != NULL_TREE
|| decl->u.array.static_p))
error ("static or type qualifiers in abstract declarator");
return decl;
error ("elements of array %qD have incomplete type", decl);
initialized = 0;
}
+ else if (C_DECL_VARIABLE_SIZE (decl))
+ {
+ /* Although C99 is unclear about whether incomplete arrays
+ of VLAs themselves count as VLAs, it does not make
+ sense to permit them to be initialized given that
+ ordinary VLAs may not be initialized. */
+ error ("variable-sized object may not be initialized");
+ initialized = 0;
+ }
}
if (initialized)
TEM may equal DECL or it may be a previous decl of the same name. */
tem = pushdecl (decl);
- if (initialized)
- DECL_EXTERNAL (tem) = 0;
+ if (initialized && DECL_EXTERNAL (tem))
+ {
+ DECL_EXTERNAL (tem) = 0;
+ TREE_STATIC (tem) = 1;
+ }
return tem;
}
const char *asmspec = 0;
/* If a name was specified, get the string. */
- if (current_scope == file_scope)
+ if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
+ && DECL_FILE_SCOPE_P (decl))
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
If it is not `static', then do not mark extern;
finish_incomplete_decl will give it a default size
and it will get allocated. */
- else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl))
+ else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
}
ordinary, non-register local variable. Historically,
GCC has accepted -- but ignored -- the ASMSPEC in
this case. */
- if (! DECL_FILE_SCOPE_P (decl)
+ if (!DECL_FILE_SCOPE_P (decl)
&& TREE_CODE (decl) == VAR_DECL
&& !C_DECL_REGISTER (decl)
&& !TREE_STATIC (decl))
/* Recompute the RTL of a local array now
if it used to be an incomplete type. */
if (was_incomplete
- && ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
+ && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
{
/* If we used it already as memory, it must stay in memory. */
TREE_ADDRESSABLE (decl) = TREE_USED (decl);
/* We do not use start_decl here because we have a type, not a declarator;
and do not use finish_decl because the decl should be stored inside
the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR. */
- tree decl = build_decl (VAR_DECL, NULL_TREE, type);
+ tree decl;
tree complit;
tree stmt;
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ decl = build_decl (VAR_DECL, NULL_TREE, type);
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 0;
TREE_STATIC (decl) = (current_scope == file_scope);
struct c_declspecs *declspecs,
enum decl_context decl_context, bool initialized, tree *width)
{
- int specbits = declspecs->specbits;
tree type = declspecs->type;
bool threadp = declspecs->thread_p;
enum c_storage_class storage_class = declspecs->storage_class;
int restrictp;
int volatilep;
int type_quals = TYPE_UNQUALIFIED;
- int defaulted_int = 0;
const char *name, *orig_name;
tree typedef_type = 0;
int funcdef_flag = 0;
bool funcdef_syntax = false;
int size_varies = 0;
- tree decl_attr = NULL_TREE;
- struct c_declspecs *array_ptr_quals = 0;
+ tree decl_attr = declspecs->decl_attr;
+ int array_ptr_quals = TYPE_UNQUALIFIED;
+ tree array_ptr_attrs = NULL_TREE;
int array_parm_static = 0;
tree returned_attrs = NULL_TREE;
bool bitfield = width != NULL;
warn_deprecated_use (declspecs->type);
typedef_type = type;
- if (type)
- size_varies = C_TYPE_VARIABLE_SIZE (type);
-
- /* No type at all: default to `int', and set DEFAULTED_INT
- because it was not a user-defined typedef. */
-
- if (type == 0)
- {
- if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
- | (1 << (int) RID_SIGNED)
- | (1 << (int) RID_UNSIGNED)
- | (1 << (int) RID_COMPLEX))))
- /* Don't warn about typedef foo = bar. */
- && ! (storage_class == csc_typedef && initialized)
- && ! in_system_header)
- {
- /* Issue a warning if this is an ISO C 99 program or if -Wreturn-type
- and this is a function, or if -Wimplicit; prefer the former
- warning since it is more explicit. */
- if ((warn_implicit_int || warn_return_type || flag_isoc99)
- && funcdef_flag)
- warn_about_return_type = 1;
- else if (warn_implicit_int || flag_isoc99)
- pedwarn_c99 ("type defaults to %<int%> in declaration of %qs",
- name);
- }
+ size_varies = C_TYPE_VARIABLE_SIZE (type);
- defaulted_int = 1;
- type = integer_type_node;
- }
-
- /* Now process the modifiers that were specified
- and check for invalid combinations. */
-
- /* Long double is a special combination. */
+ /* Diagnose defaulting to "int". */
- if ((specbits & 1 << (int) RID_LONG) && ! declspecs->long_long_p
- && TYPE_MAIN_VARIANT (type) == double_type_node)
+ if (declspecs->default_int_p && !in_system_header)
{
- specbits &= ~(1 << (int) RID_LONG);
- type = long_double_type_node;
+ /* Issue a warning if this is an ISO C 99 program or if
+ -Wreturn-type and this is a function, or if -Wimplicit;
+ prefer the former warning since it is more explicit. */
+ if ((warn_implicit_int || warn_return_type || flag_isoc99)
+ && funcdef_flag)
+ warn_about_return_type = 1;
+ else if (warn_implicit_int || flag_isoc99)
+ pedwarn_c99 ("type defaults to %<int%> in declaration of %qs", name);
}
- /* Check all other uses of type modifiers. */
-
- if (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
- | (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED)))
- {
- int ok = 0;
-
- if ((specbits & 1 << (int) RID_LONG)
- && (specbits & 1 << (int) RID_SHORT))
- error ("both long and short specified for %qs", name);
- else if (((specbits & 1 << (int) RID_LONG)
- || (specbits & 1 << (int) RID_SHORT))
- && declspecs->explicit_char_p)
- error ("long or short specified with char for %qs", name);
- else if (((specbits & 1 << (int) RID_LONG)
- || (specbits & 1 << (int) RID_SHORT))
- && TREE_CODE (type) == REAL_TYPE)
- {
- static int already = 0;
-
- error ("long or short specified with floating type for %qs", name);
- if (! already && ! pedantic)
- {
- error ("the only valid combination is %<long double%>");
- already = 1;
- }
- }
- else if ((specbits & 1 << (int) RID_SIGNED)
- && (specbits & 1 << (int) RID_UNSIGNED))
- error ("both signed and unsigned specified for %qs", name);
- else if (TREE_CODE (type) != INTEGER_TYPE)
- error ("long, short, signed or unsigned invalid for %qs", name);
- else
- {
- ok = 1;
- if (!declspecs->explicit_int_p && !defaulted_int
- && !declspecs->explicit_char_p)
- {
- error ("long, short, signed or unsigned used invalidly for %qs",
- name);
- ok = 0;
- }
- }
-
- /* Discard the type modifiers if they are invalid. */
- if (! ok)
- {
- specbits &= ~((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
- | (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED));
- declspecs->long_long_p = 0;
- }
- }
-
- if ((specbits & (1 << (int) RID_COMPLEX))
- && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
- {
- error ("complex invalid for %qs", name);
- specbits &= ~(1 << (int) RID_COMPLEX);
- }
-
- /* Decide whether an integer type is signed or not.
- Optionally treat bit-fields as signed by default. */
- if (specbits & 1 << (int) RID_UNSIGNED
- || (bitfield && ! flag_signed_bitfields
- && (declspecs->explicit_int_p || defaulted_int
- || declspecs->explicit_char_p
- /* A typedef for plain `int' without `signed'
- can be controlled just like plain `int'. */
- || !declspecs->typedef_signed_p)
- && TREE_CODE (type) != ENUMERAL_TYPE
- && !(specbits & 1 << (int) RID_SIGNED)))
- {
- if (declspecs->long_long_p)
- type = long_long_unsigned_type_node;
- else if (specbits & 1 << (int) RID_LONG)
- type = long_unsigned_type_node;
- else if (specbits & 1 << (int) RID_SHORT)
- type = short_unsigned_type_node;
- else if (type == char_type_node)
- type = unsigned_char_type_node;
- else if (declspecs->typedef_p)
- type = c_common_unsigned_type (type);
- else
- type = unsigned_type_node;
- }
- else if ((specbits & 1 << (int) RID_SIGNED)
- && type == char_type_node)
- type = signed_char_type_node;
- else if (declspecs->long_long_p)
- type = long_long_integer_type_node;
- else if (specbits & 1 << (int) RID_LONG)
- type = long_integer_type_node;
- else if (specbits & 1 << (int) RID_SHORT)
- type = short_integer_type_node;
-
- if (specbits & 1 << (int) RID_COMPLEX)
- {
- if (pedantic && !flag_isoc99)
- pedwarn ("ISO C90 does not support complex types");
- /* If we just have "complex", it is equivalent to
- "complex double", but if any modifiers at all are specified it is
- the complex form of TYPE. E.g, "complex short" is
- "complex short int". */
-
- if (defaulted_int && ! declspecs->long_long_p
- && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
- | (1 << (int) RID_SIGNED)
- | (1 << (int) RID_UNSIGNED))))
- {
- if (pedantic)
- pedwarn ("ISO C does not support plain %<complex%> meaning "
- "%<double complex%>");
- type = complex_double_type_node;
- }
- else if (type == integer_type_node)
- {
- if (pedantic)
- pedwarn ("ISO C does not support complex integer types");
- type = complex_integer_type_node;
- }
- else if (type == float_type_node)
- type = complex_float_type_node;
- else if (type == double_type_node)
- type = complex_double_type_node;
- else if (type == long_double_type_node)
- type = complex_long_double_type_node;
- else
- {
- if (pedantic)
- pedwarn ("ISO C does not support complex integer types");
- type = build_complex_type (type);
- }
- }
+ /* Adjust the type if a bit-field is being declared,
+ -funsigned-bitfields applied and the type is not explicitly
+ "signed". */
+ if (bitfield && !flag_signed_bitfields && !declspecs->explicit_signed_p
+ && TREE_CODE (type) == INTEGER_TYPE)
+ type = c_common_unsigned_type (type);
/* Check the type and width of a bit-field. */
if (bitfield)
duplicate qualifiers should be diagnosed in this case, but it
seems most appropriate to do so). */
element_type = strip_array_types (type);
- constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (element_type);
- restrictp
- = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (element_type);
- volatilep
- = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (element_type);
+ constp = declspecs->const_p + TYPE_READONLY (element_type);
+ restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
+ volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
if (pedantic && !flag_isoc99)
{
if (constp > 1)
if (volatilep > 1)
pedwarn ("duplicate %<volatile%>");
}
- if (! flag_gen_aux_info && (TYPE_QUALS (type)))
+ if (!flag_gen_aux_info && (TYPE_QUALS (type)))
type = TYPE_MAIN_VARIANT (type);
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
array or function or pointer, and DECLARATOR has had its
outermost layer removed. */
- if (array_ptr_quals != NULL || array_parm_static)
+ if (array_ptr_quals != TYPE_UNQUALIFIED
+ || array_ptr_attrs != NULL_TREE
+ || array_parm_static)
{
/* Only the innermost declarator (making a parameter be of
array type which is converted to pointer type)
may have static or type qualifiers. */
error ("static or type qualifiers in non-parameter array declarator");
- array_ptr_quals = NULL;
+ array_ptr_quals = TYPE_UNQUALIFIED;
+ array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
}
tree index_type = c_common_signed_type (sizetype);
array_ptr_quals = declarator->u.array.quals;
+ array_ptr_attrs = declarator->u.array.attrs;
array_parm_static = declarator->u.array.static_p;
declarator = declarator->declarator;
lvalue. */
STRIP_TYPE_NOPS (size);
- if (! INTEGRAL_TYPE_P (TREE_TYPE (size)))
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
{
error ("size of array %qs has non-integer type", name);
size = integer_one_node;
layout_type (type);
if (decl_context != PARM
- && (array_ptr_quals != NULL || array_parm_static))
+ && (array_ptr_quals != TYPE_UNQUALIFIED
+ || array_ptr_attrs != NULL_TREE
+ || array_parm_static))
{
error ("static or type qualifiers in non-parameter array declarator");
- array_ptr_quals = NULL;
+ array_ptr_quals = TYPE_UNQUALIFIED;
+ array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
}
break;
pedwarn ("ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
- type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
-
+
type = build_pointer_type (type);
/* Process type qualifiers (such as const or volatile)
that were given inside the `*'. */
- if (declarator->u.pointer_quals)
- {
- int pbits = declarator->u.pointer_quals->specbits;
-
- /* The grammar should only permit qualifiers here. */
- gcc_assert (!declarator->u.pointer_quals->type
- && !(pbits & ~((1 << (int) RID_CONST)
- | (1 << (int) RID_VOLATILE)
- | (1 << (int) RID_RESTRICT))));
-
- constp = !!(pbits & (1 << (int) RID_CONST));
- volatilep = !!(pbits & (1 << (int) RID_VOLATILE));
- restrictp = !!(pbits & (1 << (int) RID_RESTRICT));
-
- type_quals = ((constp ? TYPE_QUAL_CONST : 0)
- | (restrictp ? TYPE_QUAL_RESTRICT : 0)
- | (volatilep ? TYPE_QUAL_VOLATILE : 0));
- }
+ type_quals = declarator->u.pointer_quals;
declarator = declarator->declarator;
break;
if (storage_class == csc_typedef)
{
tree decl;
- /* Note that the grammar rejects storage classes
- in typenames, fields or parameters */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
pedwarn ("ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
decl = build_decl (TYPE_DECL, declarator->u.id, type);
- if ((specbits & (1 << (int) RID_SIGNED))
- || declspecs->typedef_signed_p)
+ if (declspecs->explicit_signed_p)
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
decl_attributes (&decl, returned_attrs, 0);
+ if (declspecs->inline_p)
+ pedwarn ("%Jtypedef %qD declared %<inline%>", decl, decl);
return decl;
}
if (decl_context == TYPENAME)
{
- /* Note that the grammar rejects storage classes
- in typenames, fields or parameters */
+ /* Note that the grammar rejects storage classes in typenames
+ and fields. */
+ gcc_assert (storage_class == csc_none && !threadp
+ && !declspecs->inline_p);
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
pedwarn ("ISO C forbids const or volatile function types");
a better error message can be made later. */
if (VOID_TYPE_P (type) && decl_context != PARM
- && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
+ && !((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
&& (storage_class == csc_extern
|| (current_scope == file_scope
&& !(storage_class == csc_static
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
- type_quals = TYPE_UNQUALIFIED;
- if (array_ptr_quals)
- {
- int apqbits = array_ptr_quals->specbits;
+ type_quals = array_ptr_quals;
- /* We don't yet implement attributes in this context. */
- if (array_ptr_quals->attrs != NULL_TREE)
- warning ("attributes in parameter array declarator ignored");
+ /* We don't yet implement attributes in this context. */
+ if (array_ptr_attrs != NULL_TREE)
+ warning ("attributes in parameter array declarator ignored");
- /* The grammar should only permit qualifiers here. */
- gcc_assert (!array_ptr_quals->type
- && !(apqbits & ~((1 << (int) RID_CONST)
- | (1 << (int) RID_VOLATILE)
- | (1 << (int) RID_RESTRICT))));
-
- constp = !!(apqbits & (1 << (int) RID_CONST));
- volatilep = !!(apqbits & (1 << (int) RID_VOLATILE));
- restrictp = !!(apqbits & (1 << (int) RID_RESTRICT));
-
- type_quals = ((constp ? TYPE_QUAL_CONST : 0)
- | (restrictp ? TYPE_QUAL_RESTRICT : 0)
- | (volatilep ? TYPE_QUAL_VOLATILE : 0));
- }
size_varies = 0;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
DECL_ARG_TYPE (decl) = promoted_type;
DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written;
+ if (declspecs->inline_p)
+ pedwarn ("%Jparameter %qD declared %<inline%>", decl, decl);
}
else if (decl_context == FIELD)
{
+ /* Note that the grammar rejects storage classes in typenames
+ and fields. */
+ gcc_assert (storage_class == csc_none && !threadp
+ && !declspecs->inline_p);
+
/* Structure field. It may not be a function. */
if (TREE_CODE (type) == FUNCTION_TYPE)
DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
- if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
+ if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ISO C forbids qualified function types");
/* GNU C interprets a volatile-qualified function type to indicate
if (funcdef_flag)
current_function_arg_info = arg_info;
- if (defaulted_int)
+ if (declspecs->default_int_p)
C_FUNCTION_IMPLICIT_INT (decl) = 1;
/* Record presence of `inline', if it is reasonable. */
- if (MAIN_NAME_P (declarator->u.id))
+ if (flag_hosted && MAIN_NAME_P (declarator->u.id))
{
if (declspecs->inline_p)
- warning ("cannot inline function %<main%>");
+ pedwarn ("cannot inline function %<main%>");
}
else if (declspecs->inline_p)
{
else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
{
- if (! funcdef_flag)
+ if (!funcdef_flag)
pedwarn ("parameter names (without types) in function declaration");
arg_info->parms = arg_info->types;
tree parm, type, typelt;
unsigned int parmno;
- /* If the arg types are incomplete in a declaration, they must
- include undefined tags. These tags can never be defined in
- the scope of the declaration, so the types can never be
- completed, and no call can be compiled successfully. */
+ /* If there is a parameter of incomplete type in a definition,
+ this is an error. In a declaration this is valid, and a
+ struct or union type may be completed later, before any calls
+ or definition of the function. In the case where the tag was
+ first declared within the parameter list, a warning has
+ already been given. If a parameter has void type, then
+ however the function cannot be defined or called, so
+ warn. */
for (parm = arg_info->parms, typelt = arg_types, parmno = 1;
parm;
TREE_VALUE (typelt) = error_mark_node;
TREE_TYPE (parm) = error_mark_node;
}
- else
+ else if (VOID_TYPE_P (type))
{
if (DECL_NAME (parm))
- warning ("%Jparameter %u (%qD) has incomplete type",
+ warning ("%Jparameter %u (%qD) has void type",
parm, parmno, parm);
else
- warning ("%Jparameter %u has incomplete type",
+ warning ("%Jparameter %u has void type",
parm, parmno);
}
}
warning ("anonymous %s declared inside parameter list",
keyword);
- if (! explained_incomplete_types)
+ if (!explained_incomplete_types)
{
warning ("its scope is only this definition or declaration,"
" which is probably not what you want");
ref = lookup_tag (code, name, 1);
if (ref && TREE_CODE (ref) == code)
{
- if (TYPE_FIELDS (ref))
+ if (TYPE_SIZE (ref))
{
if (code == UNION_TYPE)
error ("redefinition of %<union %s%>", IDENTIFIER_POINTER (name));
else
error ("redefinition of %<struct %s%>", IDENTIFIER_POINTER (name));
}
+ else if (C_TYPE_BEING_DEFINED (ref))
+ {
+ if (code == UNION_TYPE)
+ error ("nested redefinition of %<union %s%>",
+ IDENTIFIER_POINTER (name));
+ else
+ error ("nested redefinition of %<struct %s%>",
+ IDENTIFIER_POINTER (name));
+ }
}
else
{
that took root before someone noticed the bug... */
tree type = declspecs->type;
+ bool type_ok = (TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE);
+ bool ok = false;
- if (type
- && (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
+ if (type_ok
&& (flag_ms_extensions || !declspecs->typedef_p))
{
if (flag_ms_extensions)
- ; /* ok */
+ ok = true;
else if (flag_iso)
- goto warn_unnamed_field;
+ ok = false;
else if (TYPE_NAME (type) == NULL)
- ; /* ok */
+ ok = true;
else
- goto warn_unnamed_field;
+ ok = false;
}
- else
+ if (!ok)
{
- warn_unnamed_field:
- warning ("declaration does not declare anything");
+ pedwarn ("declaration does not declare anything");
return NULL_TREE;
}
+ if (pedantic)
+ pedwarn ("ISO C doesn't support unnamed structs/unions");
}
value = grokdeclarator (declarator, declspecs, FIELD, false,
if (C_DECL_VARIABLE_SIZE (x))
C_TYPE_VARIABLE_SIZE (t) = 1;
- /* Detect invalid nested redefinition. */
- if (TREE_TYPE (x) == t)
- error ("nested redefinition of %qs",
- IDENTIFIER_POINTER (TYPE_NAME (t)));
-
if (DECL_INITIAL (x))
{
unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1);
error ("%Jflexible array member not at end of struct", x);
TREE_TYPE (x) = error_mark_node;
}
- else if (! saw_named_field)
+ else if (!saw_named_field)
{
error ("%Jflexible array member in otherwise empty struct", x);
TREE_TYPE (x) = error_mark_node;
if (c_dialect_objc ())
objc_check_decl (decl);
rest_of_decl_compilation (decl, toplevel, 0);
- if (! toplevel)
+ if (!toplevel)
expand_decl (decl);
}
}
pushtag (name, enumtype);
}
+ if (C_TYPE_BEING_DEFINED (enumtype))
+ error ("nested redefinition of %<enum %s%>", IDENTIFIER_POINTER (name));
+
C_TYPE_BEING_DEFINED (enumtype) = 1;
if (TYPE_VALUES (enumtype) != 0)
error ("overflow in enumeration values");
}
- if (pedantic && ! int_fits_type_p (value, integer_type_node))
+ if (pedantic && !int_fits_type_p (value, integer_type_node))
{
pedwarn ("ISO C restricts enumerator values to range of %<int%>");
/* XXX This causes -pedantic to change the meaning of the program.
/* Optionally warn of any global def with no previous prototype. */
else if (warn_missing_prototypes
&& TREE_PUBLIC (decl1)
- && ! MAIN_NAME_P (DECL_NAME (decl1))
+ && !MAIN_NAME_P (DECL_NAME (decl1))
&& C_DECL_ISNT_PROTOTYPE (old_decl))
warning ("%Jno previous prototype for %qD", decl1, decl1);
/* Optionally warn of any def with no previous prototype
else if (warn_missing_declarations
&& TREE_PUBLIC (decl1)
&& old_decl == 0
- && ! MAIN_NAME_P (DECL_NAME (decl1)))
+ && !MAIN_NAME_P (DECL_NAME (decl1)))
warning ("%Jno previous declaration for %qD", decl1, decl1);
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
if (argct > 0 && (argct < 2 || argct > 3))
pedwarn ("%J%qD takes only zero or two arguments", decl1, decl1);
- if (! TREE_PUBLIC (decl1))
+ if (!TREE_PUBLIC (decl1))
pedwarn ("%J%qD is normally a non-static function", decl1, decl1);
}
TREE_TYPE (parm) = error_mark_node;
}
- if (! DECL_WEAK (parm))
+ if (!DECL_WEAK (parm))
{
error ("%Jdeclaration for parameter %qD but no such parameter",
parm, parm);
/* Type for passing arg must be consistent with that
declared for the arg. ISO C says we take the unqualified
type for parameters declared with qualified type. */
- if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
- TYPE_MAIN_VARIANT (TREE_VALUE (type))))
+ if (!comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
+ TYPE_MAIN_VARIANT (TREE_VALUE (type))))
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
== TYPE_MAIN_VARIANT (TREE_VALUE (type)))
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
/* ??? Insert the contents of the pending sizes list into the function
- to be evaluated. This just changes mis-behaviour until assign_parms
+ to be evaluated. This just changes mis-behavior until assign_parms
phase ordering problems are resolved. */
{
tree t;
cfun->x_dont_save_pending_sizes_p = 1;
}
\f
-/* Give FNDECL and all its nested functions to cgraph for compilation. */
+/* Handle attribute((warn_unused_result)) on FNDECL and all its nested
+ functions. */
static void
-c_finalize (tree fndecl)
+c_warn_unused_result_recursively (tree fndecl)
{
struct cgraph_node *cgn;
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
- /* ??? Objc emits functions after finalizing the compilation unit.
- This should be cleaned up later and this conditional removed. */
- if (cgraph_global_info_ready)
- {
- c_expand_body (fndecl);
- return;
- }
-
/* Finalize all nested functions now. */
cgn = cgraph_node (fndecl);
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
- c_finalize (cgn->decl);
-
- cgraph_finalize_function (fndecl, false);
+ c_warn_unused_result_recursively (cgn->decl);
}
/* Finish up a function declaration and compile that function
if (!decl_function_context (fndecl))
{
c_genericize (fndecl);
- lower_nested_functions (fndecl);
- c_finalize (fndecl);
+ c_warn_unused_result_recursively (fndecl);
+
+ /* ??? Objc emits functions after finalizing the compilation unit.
+ This should be cleaned up later and this conditional removed. */
+ if (cgraph_global_info_ready)
+ {
+ c_expand_body (fndecl);
+ return;
+ }
+
+ cgraph_finalize_function (fndecl, false);
}
else
{
|| DECL_INITIAL (fndecl) == error_mark_node)
return;
- tree_rest_of_compilation (fndecl, false);
+ tree_rest_of_compilation (fndecl);
if (DECL_STATIC_CONSTRUCTOR (fndecl)
&& targetm.have_ctors_dtors)
struct c_declarator *target)
{
tree attrs;
+ int quals = 0;
struct c_declarator *itarget = target;
struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator);
if (type_quals_attrs)
{
attrs = type_quals_attrs->attrs;
- type_quals_attrs->attrs = NULL_TREE;
+ quals = quals_from_declspecs (type_quals_attrs);
if (attrs != NULL_TREE)
itarget = build_attrs_declarator (attrs, target);
}
ret->kind = cdk_pointer;
ret->declarator = itarget;
- ret->u.pointer_quals = type_quals_attrs;
+ ret->u.pointer_quals = quals;
return ret;
}
ret->type = 0;
ret->decl_attr = 0;
ret->attrs = 0;
- ret->specbits = 0;
+ ret->typespec_word = cts_none;
ret->storage_class = csc_none;
ret->non_sc_seen_p = false;
ret->typedef_p = false;
- ret->typedef_signed_p = false;
+ ret->explicit_signed_p = false;
ret->deprecated_p = false;
- ret->explicit_int_p = false;
- ret->explicit_char_p = false;
+ ret->default_int_p = false;
+ ret->long_p = false;
ret->long_long_p = false;
+ ret->short_p = false;
+ ret->signed_p = false;
+ ret->unsigned_p = false;
+ ret->complex_p = false;
ret->inline_p = false;
ret->thread_p = false;
+ ret->const_p = false;
+ ret->volatile_p = false;
+ ret->restrict_p = false;
return ret;
}
declspecs_add_qual (struct c_declspecs *specs, tree qual)
{
enum rid i;
+ bool dupe = false;
specs->non_sc_seen_p = true;
gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (qual));
i = C_RID_CODE (qual);
- gcc_assert (i == RID_CONST || i == RID_VOLATILE || i == RID_RESTRICT);
- if ((specs->specbits & (1 << (int) i)) && pedantic && !flag_isoc99)
+ switch (i)
+ {
+ case RID_CONST:
+ dupe = specs->const_p;
+ specs->const_p = true;
+ break;
+ case RID_VOLATILE:
+ dupe = specs->volatile_p;
+ specs->volatile_p = true;
+ break;
+ case RID_RESTRICT:
+ dupe = specs->restrict_p;
+ specs->restrict_p = true;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (dupe && pedantic && !flag_isoc99)
pedwarn ("duplicate %qs", IDENTIFIER_POINTER (qual));
- specs->specbits |= 1 << (int) i;
return specs;
}
specs->non_sc_seen_p = true;
if (TREE_DEPRECATED (type))
specs->deprecated_p = true;
- if (type == ridpointers[(int) RID_INT])
- specs->explicit_int_p = true;
- if (type == ridpointers[(int) RID_CHAR])
- specs->explicit_char_p = true;
+ /* Handle type specifier keywords. */
if (TREE_CODE (type) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (type))
{
enum rid i = C_RID_CODE (type);
+ if (specs->type)
+ {
+ error ("two or more data types in declaration specifiers");
+ return specs;
+ }
if ((int) i <= (int) RID_LAST_MODIFIER)
{
- if (i == RID_LONG && (specs->specbits & (1 << (int) RID_LONG)))
+ /* "long", "short", "signed", "unsigned" or "_Complex". */
+ bool dupe = false;
+ switch (i)
{
+ case RID_LONG:
if (specs->long_long_p)
- error ("%<long long long%> is too long for GCC");
- else
{
+ error ("%<long long long%> is too long for GCC");
+ break;
+ }
+ if (specs->long_p)
+ {
+ if (specs->typespec_word == cts_double)
+ {
+ error ("both %<long long%> and %<double%> in "
+ "declaration specifiers");
+ break;
+ }
if (pedantic && !flag_isoc99 && !in_system_header
&& warn_long_long)
pedwarn ("ISO C90 does not support %<long long%>");
specs->long_long_p = 1;
+ break;
}
+ if (specs->short_p)
+ error ("both %<long%> and %<short%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_void)
+ error ("both %<long%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_bool)
+ error ("both %<long%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_char)
+ error ("both %<long%> and %<char%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_float)
+ error ("both %<long%> and %<float%> in "
+ "declaration specifiers");
+ else
+ specs->long_p = true;
+ break;
+ case RID_SHORT:
+ dupe = specs->short_p;
+ if (specs->long_p)
+ error ("both %<long%> and %<short%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_void)
+ error ("both %<short%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_bool)
+ error ("both %<short%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_char)
+ error ("both %<short%> and %<char%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_float)
+ error ("both %<short%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_double)
+ error ("both %<short%> and %<double%> in "
+ "declaration specifiers");
+ else
+ specs->short_p = true;
+ break;
+ case RID_SIGNED:
+ dupe = specs->signed_p;
+ if (specs->unsigned_p)
+ error ("both %<signed%> and %<unsigned%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_void)
+ error ("both %<signed%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_bool)
+ error ("both %<signed%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_float)
+ error ("both %<signed%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_double)
+ error ("both %<signed%> and %<double%> in "
+ "declaration specifiers");
+ else
+ specs->signed_p = true;
+ break;
+ case RID_UNSIGNED:
+ dupe = specs->unsigned_p;
+ if (specs->signed_p)
+ error ("both %<signed%> and %<unsigned%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_void)
+ error ("both %<unsigned%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_bool)
+ error ("both %<unsigned%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_float)
+ error ("both %<unsigned%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_double)
+ error ("both %<unsigned%> and %<double%> in "
+ "declaration specifiers");
+ else
+ specs->unsigned_p = true;
+ break;
+ case RID_COMPLEX:
+ dupe = specs->complex_p;
+ if (pedantic && !flag_isoc99 && !in_system_header)
+ pedwarn ("ISO C90 does not support complex types");
+ if (specs->typespec_word == cts_void)
+ error ("both %<complex%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_bool)
+ error ("both %<complex%> and %<_Bool%> in "
+ "declaration specifiers");
+ else
+ specs->complex_p = true;
+ break;
+ default:
+ gcc_unreachable ();
}
- else if (specs->specbits & (1 << (int) i))
+
+ if (dupe)
error ("duplicate %qs", IDENTIFIER_POINTER (type));
- specs->specbits |= 1 << (int) i;
return specs;
}
+ else
+ {
+ /* "void", "_Bool", "char", "int", "float" or "double". */
+ if (specs->typespec_word != cts_none)
+ {
+ error ("two or more data types in declaration specifiers");
+ return specs;
+ }
+ switch (i)
+ {
+ case RID_VOID:
+ if (specs->long_p)
+ error ("both %<long%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->short_p)
+ error ("both %<short%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->signed_p)
+ error ("both %<signed%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->unsigned_p)
+ error ("both %<unsigned%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->complex_p)
+ error ("both %<complex%> and %<void%> in "
+ "declaration specifiers");
+ else
+ specs->typespec_word = cts_void;
+ return specs;
+ case RID_BOOL:
+ if (specs->long_p)
+ error ("both %<long%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->short_p)
+ error ("both %<short%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->signed_p)
+ error ("both %<signed%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->unsigned_p)
+ error ("both %<unsigned%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->complex_p)
+ error ("both %<complex%> and %<_Bool%> in "
+ "declaration specifiers");
+ else
+ specs->typespec_word = cts_bool;
+ return specs;
+ case RID_CHAR:
+ if (specs->long_p)
+ error ("both %<long%> and %<char%> in "
+ "declaration specifiers");
+ else if (specs->short_p)
+ error ("both %<short%> and %<char%> in "
+ "declaration specifiers");
+ else
+ specs->typespec_word = cts_char;
+ return specs;
+ case RID_INT:
+ specs->typespec_word = cts_int;
+ return specs;
+ case RID_FLOAT:
+ if (specs->long_p)
+ error ("both %<long%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->short_p)
+ error ("both %<short%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->signed_p)
+ error ("both %<signed%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->unsigned_p)
+ error ("both %<unsigned%> and %<float%> in "
+ "declaration specifiers");
+ else
+ specs->typespec_word = cts_float;
+ return specs;
+ case RID_DOUBLE:
+ if (specs->long_long_p)
+ error ("both %<long long%> and %<double%> in "
+ "declaration specifiers");
+ else if (specs->short_p)
+ error ("both %<short%> and %<double%> in "
+ "declaration specifiers");
+ else if (specs->signed_p)
+ error ("both %<signed%> and %<double%> in "
+ "declaration specifiers");
+ else if (specs->unsigned_p)
+ error ("both %<unsigned%> and %<double%> in "
+ "declaration specifiers");
+ else
+ specs->typespec_word = cts_double;
+ return specs;
+ default:
+ /* ObjC reserved word "id", handled below. */
+ break;
+ }
+ }
}
- if (specs->type)
+
+ /* Now we have a typedef (a TYPE_DECL node), an identifier (some
+ form of ObjC type, cases such as "int" and "long" being handled
+ above), a TYPE (struct, union, enum and typeof specifiers) or an
+ ERROR_MARK. In none of these cases may there have previously
+ been any type specifiers. */
+ if (specs->type || specs->typespec_word != cts_none
+ || specs->long_p || specs->short_p || specs->signed_p
+ || specs->unsigned_p || specs->complex_p)
error ("two or more data types in declaration specifiers");
- /* Actual typedefs come to us as TYPE_DECL nodes. */
else if (TREE_CODE (type) == TYPE_DECL)
{
if (TREE_TYPE (type) == error_mark_node)
specs->type = TREE_TYPE (type);
specs->decl_attr = DECL_ATTRIBUTES (type);
specs->typedef_p = true;
- specs->typedef_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
+ specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
}
}
- /* Built-in types come as identifiers. */
else if (TREE_CODE (type) == IDENTIFIER_NODE)
{
tree t = lookup_name (type);
switch (i)
{
case RID_INLINE:
- /* GCC has hitherto given an error for duplicate inline, but
- this should be revisited since C99 permits duplicate
- inline. */
- dupe = specs->inline_p;
+ /* C99 permits duplicate inline. Although of doubtful utility,
+ it seems simplest to permit it in gnu89 mode as well, as
+ there is also little utility in maintaining this as a
+ difference between gnu89 and C99 inline. */
+ dupe = false;
specs->inline_p = true;
break;
case RID_THREAD:
return specs;
}
+/* Combine "long", "short", "signed", "unsigned" and "_Complex" type
+ specifiers with any other type specifier to determine the resulting
+ type. This is where ISO C checks on complex types are made, since
+ "_Complex long" is a prefix of the valid ISO C type "_Complex long
+ double". */
+
+struct c_declspecs *
+finish_declspecs (struct c_declspecs *specs)
+{
+ /* If a type was specified as a whole, we have no modifiers and are
+ done. */
+ if (specs->type != NULL_TREE)
+ {
+ gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
+ && !specs->signed_p && !specs->unsigned_p
+ && !specs->complex_p);
+ return specs;
+ }
+
+ /* If none of "void", "_Bool", "char", "int", "float" or "double"
+ has been specified, treat it as "int" unless "_Complex" is
+ present and there are no other specifiers. If we just have
+ "_Complex", it is equivalent to "_Complex double", but e.g.
+ "_Complex short" is equivalent to "_Complex short int". */
+ if (specs->typespec_word == cts_none)
+ {
+ if (specs->long_p || specs->short_p
+ || specs->signed_p || specs->unsigned_p)
+ {
+ specs->typespec_word = cts_int;
+ }
+ else if (specs->complex_p)
+ {
+ specs->typespec_word = cts_double;
+ if (pedantic)
+ pedwarn ("ISO C does not support plain %<complex%> meaning "
+ "%<double complex%>");
+ }
+ else
+ {
+ specs->typespec_word = cts_int;
+ specs->default_int_p = true;
+ /* We don't diagnose this here because grokdeclarator will
+ give more specific diagnostics according to whether it is
+ a function definition. */
+ }
+ }
+
+ /* If "signed" was specified, record this to distinguish "int" and
+ "signed int" in the case of a bit-field with
+ -funsigned-bitfields. */
+ specs->explicit_signed_p = specs->signed_p;
+
+ /* Now compute the actual type. */
+ switch (specs->typespec_word)
+ {
+ case cts_void:
+ gcc_assert (!specs->long_p && !specs->short_p
+ && !specs->signed_p && !specs->unsigned_p
+ && !specs->complex_p);
+ specs->type = void_type_node;
+ break;
+ case cts_bool:
+ gcc_assert (!specs->long_p && !specs->short_p
+ && !specs->signed_p && !specs->unsigned_p
+ && !specs->complex_p);
+ specs->type = boolean_type_node;
+ break;
+ case cts_char:
+ gcc_assert (!specs->long_p && !specs->short_p);
+ gcc_assert (!(specs->signed_p && specs->unsigned_p));
+ if (specs->signed_p)
+ specs->type = signed_char_type_node;
+ else if (specs->unsigned_p)
+ specs->type = unsigned_char_type_node;
+ else
+ specs->type = char_type_node;
+ if (specs->complex_p)
+ {
+ if (pedantic)
+ pedwarn ("ISO C does not support complex integer types");
+ specs->type = build_complex_type (specs->type);
+ }
+ break;
+ case cts_int:
+ gcc_assert (!(specs->long_p && specs->short_p));
+ gcc_assert (!(specs->signed_p && specs->unsigned_p));
+ if (specs->long_long_p)
+ specs->type = (specs->unsigned_p
+ ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+ else if (specs->long_p)
+ specs->type = (specs->unsigned_p
+ ? long_unsigned_type_node
+ : long_integer_type_node);
+ else if (specs->short_p)
+ specs->type = (specs->unsigned_p
+ ? short_unsigned_type_node
+ : short_integer_type_node);
+ else
+ specs->type = (specs->unsigned_p
+ ? unsigned_type_node
+ : integer_type_node);
+ if (specs->complex_p)
+ {
+ if (pedantic)
+ pedwarn ("ISO C does not support complex integer types");
+ specs->type = build_complex_type (specs->type);
+ }
+ break;
+ case cts_float:
+ gcc_assert (!specs->long_p && !specs->short_p
+ && !specs->signed_p && !specs->unsigned_p);
+ specs->type = (specs->complex_p
+ ? complex_float_type_node
+ : float_type_node);
+ break;
+ case cts_double:
+ gcc_assert (!specs->long_long_p && !specs->short_p
+ && !specs->signed_p && !specs->unsigned_p);
+ if (specs->long_p)
+ {
+ specs->type = (specs->complex_p
+ ? complex_long_double_type_node
+ : long_double_type_node);
+ }
+ else
+ {
+ specs->type = (specs->complex_p
+ ? complex_double_type_node
+ : double_type_node);
+ }
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ return specs;
+}
+
/* Synthesize a function which calls all the global ctors or global
dtors in this file. This is only used for targets which do not
support .ctors/.dtors sections. FIXME: Migrate into cgraph. */
/* We're done parsing; proceed to optimize and emit assembly.
FIXME: shouldn't be the front end's responsibility to call this. */
cgraph_optimize ();
-
- /* Presently this has to happen after cgraph_optimize.
- FIXME: shouldn't be the front end's responsibility to call this. */
- if (flag_mudflap)
- mudflap_finish_file ();
}
#include "gt-c-decl.h"