/* Process declarations and variables for C compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "input.h"
#include "tm.h"
#include "intl.h"
#include "tree.h"
static int current_extern_inline;
+/* Nonzero when the current toplevel function contains a declaration
+ of a nested function which is never defined. */
+
+static bool undef_nested_function;
+
/* True means global_bindings_p should return false even if the scope stack
says we are in file scope. */
bool c_override_global_bindings_to_false;
{
warning ("%Jarray %qD assumed to have one element", decl, decl);
- complete_array_type (type, NULL_TREE, 1);
+ complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
layout_decl (decl, 0);
}
bool functionbody = scope->function_body;
bool keep = functionbody || scope->keep || scope->bindings;
+ c_end_vm_scope (scope->depth);
+
/* If appropriate, create a BLOCK to record the decls for the life
of this function. */
block = 0;
&& DECL_ABSTRACT_ORIGIN (p) != 0
&& DECL_ABSTRACT_ORIGIN (p) != p)
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
+ if (!DECL_EXTERNAL (p)
+ && DECL_INITIAL (p) == 0)
+ {
+ error ("%Jnested function %qD declared but never defined", p, p);
+ undef_nested_function = true;
+ }
goto common_symbol;
case VAR_DECL:
/* Pop off the file scope and close this translation unit. */
pop_scope ();
file_scope = 0;
+
+ maybe_apply_pending_pragma_weaks ();
cgraph_finalize_compilation_unit ();
}
tree newargs, oldargs;
int i;
- /* ??? Elsewhere TYPE_MAIN_VARIANT is not used in this context. */
-#define END_OF_ARGLIST(t) (TYPE_MAIN_VARIANT (t) == void_type_node)
+#define END_OF_ARGLIST(t) ((t) == void_type_node)
oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype);
newargs = TYPE_ARG_TYPES (newtype);
for (;;)
{
- tree oldargtype = TREE_VALUE (oldargs);
- tree newargtype = TREE_VALUE (newargs);
+ tree oldargtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs));
+ tree newargtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs));
if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype))
break;
tree newtype, oldtype;
bool pedwarned = false;
bool warned = false;
+ bool retval = true;
/* If we have error_mark_node for either decl or type, just discard
the previous decl - we're in an error cascade already. */
if (DECL_INITIAL (newdecl))
{
- if (DECL_INITIAL (olddecl)
- && !(DECL_DECLARED_INLINE_P (olddecl)
- && DECL_EXTERNAL (olddecl)
- && !(DECL_DECLARED_INLINE_P (newdecl)
- && DECL_EXTERNAL (newdecl)
- && same_translation_unit_p (olddecl, newdecl))))
+ if (DECL_INITIAL (olddecl))
{
- error ("%Jredefinition of %qD", newdecl, newdecl);
- locate_old_decl (olddecl, error);
- return false;
- }
+ /* If both decls have extern inline and are in the same TU,
+ reject the new decl. */
+ if (DECL_DECLARED_INLINE_P (olddecl)
+ && DECL_EXTERNAL (olddecl)
+ && DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_EXTERNAL (newdecl)
+ && same_translation_unit_p (newdecl, olddecl))
+ {
+ error ("%Jredefinition of %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ /* If both decls have not extern inline, reject the new decl. */
+ if (!DECL_DECLARED_INLINE_P (olddecl)
+ && !DECL_EXTERNAL (olddecl)
+ && !DECL_DECLARED_INLINE_P (newdecl)
+ && !DECL_EXTERNAL (newdecl))
+ {
+ error ("%Jredefinition of %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ /* If the new decl is declared as extern inline, error if they are
+ in the same TU, otherwise retain the old decl. */
+ if (!DECL_DECLARED_INLINE_P (olddecl)
+ && !DECL_EXTERNAL (olddecl)
+ && DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_EXTERNAL (newdecl))
+ {
+ if (same_translation_unit_p (newdecl, olddecl))
+ {
+ error ("%Jredefinition of %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ else
+ retval = false;
+ }
+ }
}
/* If we have a prototype after an old-style function definition,
the argument types must be checked specially. */
if (warned || pedwarned)
locate_old_decl (olddecl, pedwarned ? pedwarn : warning);
- return true;
+ return retval;
}
/* Subroutine of duplicate_decls. NEWDECL has been found to be
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
+ DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
}
/* Merge the storage class information. */
{
tree old_decl = b->decl;
- if (TREE_CODE (old_decl) == PARM_DECL)
+ if (old_decl == error_mark_node)
+ {
+ warning ("%Jdeclaration of %qD shadows previous non-variable",
+ new_decl, new_decl);
+ break;
+ }
+ else if (TREE_CODE (old_decl) == PARM_DECL)
warning ("%Jdeclaration of %qD shadows a parameter",
new_decl, new_decl);
else if (DECL_FILE_SCOPE_P (old_decl))
new_decl, new_decl);
else if (TREE_CODE (old_decl) == FUNCTION_DECL
&& DECL_BUILT_IN (old_decl))
- warning ("%Jdeclaration of %qD shadows a built-in function",
- new_decl, new_decl);
+ {
+ warning ("%Jdeclaration of %qD shadows a built-in function",
+ new_decl, new_decl);
+ break;
+ }
else
warning ("%Jdeclaration of %qD shadows a previous local",
new_decl, new_decl);
- if (TREE_CODE (old_decl) != FUNCTION_DECL
- || !DECL_BUILT_IN (old_decl))
- warning ("%Jshadowed declaration is here", old_decl);
+ warning ("%Jshadowed declaration is here", old_decl);
break;
}
|| DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
DECL_CONTEXT (x) = current_function_decl;
+ /* If this is of variably modified type, prevent jumping into its
+ scope. */
+ if ((TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == TYPE_DECL)
+ && variably_modified_type_p (TREE_TYPE (x), NULL_TREE))
+ c_begin_vm_scope (scope->depth);
+
/* Anonymous decls are just inserted in the scope. */
if (!name)
{
its type saved; the others will already have had their
proper types saved and the types will not have changed as
their scopes will not have been re-entered. */
- if (DECL_FILE_SCOPE_P (b->decl) && !type_saved)
+ if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved)
{
b->type = TREE_TYPE (b->decl);
type_saved = true;
if (decl)
{
+ if (decl == error_mark_node)
+ return decl;
+
/* FIXME: Objective-C has weird not-really-builtin functions
which are supposed to be visible automatically. They wind up
in the external scope because they're pushed before the file
ID, including a reference to a builtin outside of function-call
context. Establish a binding of the identifier to error_mark_node
in an appropriate scope, which will suppress further errors for the
- same identifier. */
+ same identifier. The error message should be given location LOC. */
void
-undeclared_variable (tree id)
+undeclared_variable (tree id, location_t loc)
{
static bool already = false;
struct c_scope *scope;
if (current_function_decl == 0)
{
- error ("%qE undeclared here (not in a function)", id);
+ error ("%H%qE undeclared here (not in a function)", &loc, id);
scope = current_scope;
}
else
{
- error ("%qE undeclared (first use in this function)", id);
+ error ("%H%qE undeclared (first use in this function)", &loc, id);
if (!already)
{
- error ("(Each undeclared identifier is reported only once");
- error ("for each function it appears in.)");
+ error ("%H(Each undeclared identifier is reported only once", &loc);
+ error ("%Hfor each function it appears in.)", &loc);
already = true;
}
if (current_function_decl == 0)
{
- error ("label %qs referenced outside of any function",
- IDENTIFIER_POINTER (name));
+ error ("label %qE referenced outside of any function", name);
return 0;
}
at this scope */
if (b && B_IN_CURRENT_SCOPE (b))
{
- error ("duplicate label declaration %qs", IDENTIFIER_POINTER (name));
+ error ("duplicate label declaration %qE", name);
locate_old_decl (b->decl, error);
/* Just use the previous declaration. */
if there is a containing function with a declared label with
the same name. */
tree label = I_LABEL_DECL (name);
+ struct c_label_list *nlist_se, *nlist_vm;
if (label
&& ((DECL_CONTEXT (label) == current_function_decl
/* The label has been used or declared already in this function,
but not defined. Update its location to point to this
definition. */
+ if (C_DECL_UNDEFINABLE_STMT_EXPR (label))
+ error ("%Jjump into statement expression", label);
+ if (C_DECL_UNDEFINABLE_VM (label))
+ error ("%Jjump into scope of identifier with variably modified type",
+ label);
DECL_SOURCE_LOCATION (label) = location;
}
else
if (warn_traditional && !in_system_header && lookup_name (name))
warning ("%Htraditional C lacks a separate namespace for labels, "
- "identifier %qs conflicts", &location,
- IDENTIFIER_POINTER (name));
+ "identifier %qE conflicts", &location, name);
+
+ nlist_se = XOBNEW (&parser_obstack, struct c_label_list);
+ nlist_se->next = label_context_stack_se->labels_def;
+ nlist_se->label = label;
+ label_context_stack_se->labels_def = nlist_se;
+
+ nlist_vm = XOBNEW (&parser_obstack, struct c_label_list);
+ nlist_vm->next = label_context_stack_vm->labels_def;
+ nlist_vm->label = label;
+ label_context_stack_vm->labels_def = nlist_vm;
/* Mark label as having been defined. */
DECL_INITIAL (label) = error_mark_node;
pending_xref_error (void)
{
if (pending_invalid_xref != 0)
- error ("%H%qs defined as wrong kind of tag",
- &pending_invalid_xref_location,
- IDENTIFIER_POINTER (pending_invalid_xref));
+ error ("%H%qE defined as wrong kind of tag",
+ &pending_invalid_xref_location, pending_invalid_xref);
pending_invalid_xref = 0;
}
void
c_init_decl_processing (void)
{
- tree endlink;
- tree ptr_ftype_void, ptr_ftype_ptr;
location_t save_loc = input_location;
- /* Adds some ggc roots, and reserved words for c-parse.in. */
+ /* Initialize reserved words for parser. */
c_parse_init ();
current_function_decl = 0;
pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
boolean_type_node));
- endlink = void_list_node;
- ptr_ftype_void = build_function_type (ptr_type_node, endlink);
- ptr_ftype_ptr
- = build_function_type (ptr_type_node,
- tree_cons (NULL_TREE, ptr_type_node, endlink));
-
input_location = save_loc;
pedantic_lvalues = true;
tree decl, type, init;
size_t length = strlen (name);
- type = build_array_type
- (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
- build_index_type (size_int (length)));
+ type = build_array_type (char_type_node,
+ build_index_type (size_int (length)));
+ type = c_build_qualified_type (type, TYPE_QUAL_CONST);
decl = build_decl (VAR_DECL, id, type);
error ("variable %qD has initializer but incomplete type", decl);
initialized = 0;
}
- else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (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
&& TYPE_DOMAIN (type) == 0
&& TREE_CODE (decl) != TYPE_DECL)
{
- int do_default
+ bool do_default
= (TREE_STATIC (decl)
/* Even if pedantic, an external linkage array
may have incomplete type at first. */
? pedantic && !TREE_PUBLIC (decl)
: !DECL_EXTERNAL (decl));
int failure
- = complete_array_type (type, DECL_INITIAL (decl), do_default);
+ = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl),
+ do_default);
/* Get the completed type made by complete_array_type. */
type = TREE_TYPE (decl);
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
}
-
- /* TYPE_MAX_VALUE is always one less than the number of elements
- in the array, because we start counting at zero. Therefore,
- warn only if the value is less than zero. */
- else if (pedantic && TYPE_DOMAIN (type) != 0
- && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+ else if (failure == 3)
error ("%Jzero or negative size array %qD", decl, decl);
+ if (DECL_INITIAL (decl))
+ TREE_TYPE (DECL_INITIAL (decl)) = type;
+
layout_decl (decl, 0);
}
}
/* If #pragma weak was used, mark the decl weak now. */
- if (current_scope == file_scope)
- maybe_apply_pragma_weak (decl);
+ maybe_apply_pragma_weak (decl);
/* If this is a variable definition, determine its ELF visibility. */
if (TREE_CODE (decl) == VAR_DECL
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
{
- int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
-
+ int failure = complete_array_type (&TREE_TYPE (decl),
+ DECL_INITIAL (decl), true);
gcc_assert (!failure);
+
+ type = TREE_TYPE (decl);
+ TREE_TYPE (DECL_INITIAL (decl)) = type;
}
- type = TREE_TYPE (decl);
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
return error_mark_node;
stmt = build_stmt (DECL_EXPR, decl);
- complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+ complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
TREE_SIDE_EFFECTS (complit) = 1;
layout_decl (decl, 0);
DECL_DEFER_OUTPUT (decl) = 1;
DECL_COMDAT (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
pushdecl (decl);
rest_of_decl_compilation (decl, 1, 0);
}
return complit;
}
\f
-/* Make TYPE a complete type based on INITIAL_VALUE.
- Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
- 2 if there was no information (in which case assume 1 if DO_DEFAULT). */
-
-int
-complete_array_type (tree type, tree initial_value, int do_default)
-{
- tree maxindex = NULL_TREE;
- int value = 0;
-
- if (initial_value)
- {
- /* Note MAXINDEX is really the maximum index,
- one less than the size. */
- if (TREE_CODE (initial_value) == STRING_CST)
- {
- int eltsize
- = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
- maxindex = build_int_cst (NULL_TREE,
- (TREE_STRING_LENGTH (initial_value)
- / eltsize) - 1);
- }
- else if (TREE_CODE (initial_value) == CONSTRUCTOR)
- {
- tree elts = CONSTRUCTOR_ELTS (initial_value);
- maxindex = build_int_cst (NULL_TREE, -1);
- for (; elts; elts = TREE_CHAIN (elts))
- {
- if (TREE_PURPOSE (elts))
- maxindex = TREE_PURPOSE (elts);
- else
- maxindex = fold (build2 (PLUS_EXPR, integer_type_node,
- maxindex, integer_one_node));
- }
- }
- else
- {
- /* Make an error message unless that happened already. */
- if (initial_value != error_mark_node)
- value = 1;
-
- /* Prevent further error messages. */
- maxindex = build_int_cst (NULL_TREE, 0);
- }
- }
-
- if (!maxindex)
- {
- if (do_default)
- maxindex = build_int_cst (NULL_TREE, 0);
- value = 2;
- }
-
- if (maxindex)
- {
- TYPE_DOMAIN (type) = build_index_type (maxindex);
-
- gcc_assert (TREE_TYPE (maxindex));
- }
-
- /* Lay out the type now that we can get the real answer. */
-
- layout_type (type);
-
- return value;
-}
-\f
/* Determine whether TYPE is a structure with a flexible array member,
or a union containing such a structure (possibly recursively). */
unsigned HOST_WIDE_INT w;
const char *name = orig_name ? orig_name: _("<anonymous>");
- /* Necessary? */
- STRIP_NOPS (*width);
-
/* Detect and ignore out of range field width and process valid
field widths. */
- if (TREE_CODE (*width) != INTEGER_CST)
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (*width))
+ || TREE_CODE (*width) != INTEGER_CST)
{
error ("bit-field %qs width not an integer constant", name);
*width = integer_one_node;
if (volatilep > 1)
pedwarn ("duplicate %<volatile%>");
}
- if (!flag_gen_aux_info && (TYPE_QUALS (type)))
+ if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
type = TYPE_MAIN_VARIANT (type);
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
/* Now figure out the structure of the declarator proper.
Descend through it, creating more complex types, until we reach
- the declared identifier (or NULL_TREE, in an absolute declarator). */
+ the declared identifier (or NULL_TREE, in an absolute declarator).
+ At each stage we maintain an unqualified version of the type
+ together with any qualifiers that should be applied to it with
+ c_build_qualified_type; this way, array types including
+ multidimensional array types are first built up in unqualified
+ form and then the qualified form is created with
+ TYPE_MAIN_VARIANT pointing to the unqualified form. */
while (declarator && declarator->kind != cdk_id)
{
itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
}
- /* If pedantic, complain about arrays of incomplete types. */
- if (pedantic && !COMPLETE_TYPE_P (type))
- pedwarn ("array type has incomplete element type");
-
- /* Build the array type itself, then merge any constancy
- or volatility into the target type. We must do it in
- this order to ensure that the TYPE_MAIN_VARIANT field
- of the array type is set correctly. */
- type = build_array_type (type, itype);
- if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ /* Complain about arrays of incomplete types. */
+ if (!COMPLETE_TYPE_P (type))
+ {
+ error ("array type has incomplete element type");
+ type = error_mark_node;
+ }
+ else
+ type = build_array_type (type, itype);
if (size_varies)
C_TYPE_VARIABLE_SIZE (type) = 1;
}
}
- /* Now TYPE has the actual type. */
+ /* Now TYPE has the actual type, apart from any qualifiers in
+ TYPE_QUALS. */
/* Check the type and width of a bit-field. */
if (bitfield)
error ("field %qs has incomplete type", name);
type = error_mark_node;
}
- /* Move type qualifiers down to element of an array. */
- if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
- type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
+ type = c_build_qualified_type (type, type_quals);
decl = build_decl (FIELD_DECL, declarator->u.id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
/* An uninitialized decl with `extern' is a reference. */
int extern_ref = !initialized && storage_class == csc_extern;
- /* Move type qualifiers down to element of an array. */
- if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
- {
- int saved_align = TYPE_ALIGN(type);
- type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
- TYPE_ALIGN (type) = saved_align;
- }
- else if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals);
/* C99 6.2.2p7: It is invalid (compile-time undefined
behavior) to create an 'extern' declaration for a
}
decl = build_decl (VAR_DECL, declarator->u.id, type);
+ DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
if (TYPE_SIZE (ref))
{
if (code == UNION_TYPE)
- error ("redefinition of %<union %s%>", IDENTIFIER_POINTER (name));
+ error ("redefinition of %<union %E%>", name);
else
- error ("redefinition of %<struct %s%>", IDENTIFIER_POINTER (name));
+ error ("redefinition of %<struct %E%>", name);
}
else if (C_TYPE_BEING_DEFINED (ref))
{
if (code == UNION_TYPE)
- error ("nested redefinition of %<union %s%>",
- IDENTIFIER_POINTER (name));
+ error ("nested redefinition of %<union %E%>", name);
else
- error ("nested redefinition of %<struct %s%>",
- IDENTIFIER_POINTER (name));
+ error ("nested redefinition of %<struct %E%>", name);
}
}
else
= tree_low_cst (DECL_INITIAL (*fieldlistp), 1);
tree type = TREE_TYPE (*fieldlistp);
if (width != TYPE_PRECISION (type))
- TREE_TYPE (*fieldlistp)
- = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+ {
+ TREE_TYPE (*fieldlistp)
+ = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+ DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
+ }
DECL_INITIAL (*fieldlistp) = 0;
}
else
}
if (C_TYPE_BEING_DEFINED (enumtype))
- error ("nested redefinition of %<enum %s%>", IDENTIFIER_POINTER (name));
+ error ("nested redefinition of %<enum %E%>", name);
C_TYPE_BEING_DEFINED (enumtype) = 1;
if (TYPE_VALUES (enumtype) != 0)
{
/* This enum is a named one that has been declared already. */
- error ("redeclaration of %<enum %s%>", IDENTIFIER_POINTER (name));
+ error ("redeclaration of %<enum %E%>", name);
/* Completely replace its old definition.
The old enumerators remain defined, however. */
/* Validate and default VALUE. */
- /* Remove no-op casts from the value. */
- if (value)
- STRIP_TYPE_NOPS (value);
-
if (value != 0)
{
/* Don't issue more errors for error_mark_node (i.e. an
undeclared identifier) - just ignore the value expression. */
if (value == error_mark_node)
value = 0;
- else if (TREE_CODE (value) != INTEGER_CST)
+ else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))
+ || TREE_CODE (value) != INTEGER_CST)
{
error ("enumerator value for %qE is not an integer constant", name);
value = 0;
{
tree decl1, old_decl;
tree restype, resdecl;
+ struct c_label_context_se *nstack_se;
+ struct c_label_context_vm *nstack_vm;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
current_extern_inline = 0;
c_switch_stack = NULL;
+ nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
+ nstack_se->labels_def = NULL;
+ nstack_se->labels_used = NULL;
+ nstack_se->next = label_context_stack_se;
+ label_context_stack_se = nstack_se;
+
+ nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
+ nstack_vm->labels_def = NULL;
+ nstack_vm->labels_used = NULL;
+ nstack_vm->scope = 0;
+ nstack_vm->next = label_context_stack_vm;
+ label_context_stack_vm = nstack_vm;
+
/* Indicate no valid break/continue context by setting these variables
to some non-null, non-label value. We'll notice and emit the proper
error message in c_finish_bc_stmt. */
/* Optionally warn of old-fashioned def with no previous prototype. */
if (warn_strict_prototypes
+ && old_decl != error_mark_node
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
&& C_DECL_ISNT_PROTOTYPE (old_decl))
warning ("function declaration isn%'t a prototype");
/* Optionally warn of any global def with no previous prototype. */
else if (warn_missing_prototypes
+ && old_decl != error_mark_node
&& TREE_PUBLIC (decl1)
&& !MAIN_NAME_P (DECL_NAME (decl1))
&& C_DECL_ISNT_PROTOTYPE (old_decl))
/* Optionally warn of any def with no previous prototype
if the function has already been used. */
else if (warn_missing_prototypes
- && old_decl != 0 && TREE_USED (old_decl)
+ && old_decl != 0
+ && old_decl != error_mark_node
+ && TREE_USED (old_decl)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
warning ("%J%qD was used with no prototype before its definition",
decl1, decl1);
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
else if (warn_missing_declarations
- && old_decl != 0 && TREE_USED (old_decl)
+ && old_decl != 0
+ && old_decl != error_mark_node
+ && TREE_USED (old_decl)
&& C_DECL_IMPLICIT (old_decl))
warning ("%J%qD was used with no declaration before its definition",
decl1, decl1);
{
tree fndecl = current_function_decl;
+ label_context_stack_se = label_context_stack_se->next;
+ label_context_stack_vm = label_context_stack_vm->next;
+
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
{
else
{
if (flag_isoc99)
- c_finish_return (integer_zero_node);
+ {
+ tree stmt = c_finish_return (integer_zero_node);
+#ifdef USE_MAPPED_LOCATION
+ /* Hack. We don't want the middle-end to warn that this return
+ is unreachable, so we mark its location as special. Using
+ UNKNOWN_LOCATION has the problem that it gets clobbered in
+ annotate_one_with_locus. A cleaner solution might be to
+ ensure ! should_carry_locus_p (stmt), but that needs a flag.
+ */
+ SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
+#else
+ /* Hack. We don't want the middle-end to warn that this
+ return is unreachable, so put the statement on the
+ special line 0. */
+ annotate_with_file_line (stmt, input_filename, 0);
+#endif
+ }
}
}
until their parent function is genericized. Since finalizing
requires GENERIC, delay that as well. */
- if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
+ if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node
+ && !undef_nested_function)
{
if (!decl_function_context (fndecl))
{
}
}
+ if (!decl_function_context (fndecl))
+ undef_nested_function = false;
+
/* We're leaving the context of this function, so zap cfun.
It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
tree_rest_of_compilation. */
ret->kind = cdk_id;
ret->declarator = 0;
ret->u.id = ident;
+ /* Default value - may get reset to a more precise location. */
+ ret->id_loc = input_location;
return ret;
}
ret->attrs = 0;
ret->typespec_word = cts_none;
ret->storage_class = csc_none;
+ ret->declspecs_seen_p = false;
+ ret->type_seen_p = false;
ret->non_sc_seen_p = false;
ret->typedef_p = false;
ret->tag_defined_p = false;
enum rid i;
bool dupe = false;
specs->non_sc_seen_p = true;
+ specs->declspecs_seen_p = true;
gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (qual));
i = C_RID_CODE (qual);
gcc_unreachable ();
}
if (dupe && pedantic && !flag_isoc99)
- pedwarn ("duplicate %qs", IDENTIFIER_POINTER (qual));
+ pedwarn ("duplicate %qE", qual);
return specs;
}
{
tree type = spec.spec;
specs->non_sc_seen_p = true;
+ specs->declspecs_seen_p = true;
+ specs->type_seen_p = true;
if (TREE_DEPRECATED (type))
specs->deprecated_p = true;
}
if (dupe)
- error ("duplicate %qs", IDENTIFIER_POINTER (type));
+ error ("duplicate %qE", type);
return specs;
}
{
tree t = lookup_name (type);
if (!t || TREE_CODE (t) != TYPE_DECL)
- error ("%qs fails to be a typedef or built in type",
- IDENTIFIER_POINTER (type));
+ error ("%qE fails to be a typedef or built in type", type);
else if (TREE_TYPE (t) == error_mark_node)
;
else
enum rid i;
enum c_storage_class n = csc_none;
bool dupe = false;
+ specs->declspecs_seen_p = true;
gcc_assert (TREE_CODE (scspec) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (scspec));
i = C_RID_CODE (scspec);
if (extra_warnings && specs->non_sc_seen_p)
- warning ("%qs is not at beginning of declaration",
- IDENTIFIER_POINTER (scspec));
+ warning ("%qE is not at beginning of declaration", scspec);
switch (i)
{
case RID_INLINE:
if (n != csc_none && n == specs->storage_class)
dupe = true;
if (dupe)
- error ("duplicate %qs", IDENTIFIER_POINTER (scspec));
+ error ("duplicate %qE", scspec);
if (n != csc_none)
{
if (specs->storage_class != csc_none && n != specs->storage_class)
specs->storage_class = n;
if (n != csc_extern && n != csc_static && specs->thread_p)
{
- error ("%<__thread%> used with %qs",
- IDENTIFIER_POINTER (scspec));
+ error ("%<__thread%> used with %qE", scspec);
specs->thread_p = false;
}
}
declspecs_add_attrs (struct c_declspecs *specs, tree attrs)
{
specs->attrs = chainon (attrs, specs->attrs);
+ specs->declspecs_seen_p = true;
return specs;
}