You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
/* Process declarations and symbol lookup for C front end.
Also constructs types; the standard scalar types at initialization,
#include "libfuncs.h"
#include "except.h"
#include "langhooks-def.h"
+#include "pointer-set.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree);
\f
+/* T is a statement. Add it to the statement-tree. This is the
+ C/ObjC version--C++ has a slightly different version of this
+ function. */
+
+tree
+add_stmt (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ if (EXPR_P (t) && code != LABEL_EXPR)
+ {
+ if (!EXPR_HAS_LOCATION (t))
+ SET_EXPR_LOCATION (t, input_location);
+ }
+
+ if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
+ STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;
+
+ /* Add T to the statement-tree. Non-side-effect statements need to be
+ recorded during statement expressions. */
+ append_to_statement_list_force (t, &cur_stmt_list);
+
+ return t;
+}
+\f
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
{
tree rid = ridpointers[C_RID_CODE (node)];
indent_to (file, indent + 4);
- fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
+ fprintf (file, "rid %p \"%s\"",
(void *) rid, IDENTIFIER_POINTER (rid));
}
}
&& !DECL_EXTERNAL (decl)
&& TYPE_DOMAIN (type) == 0)
{
- warning (0, "%Jarray %qD assumed to have one element", decl, decl);
+ warning (0, "array %q+D assumed to have one element", decl);
complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
scope = scope->outer)
{
for (b = scope->bindings; b; b = b->prev)
- {
- if (TREE_CODE (b->decl) == VAR_DECL
- || TREE_CODE (b->decl) == PARM_DECL)
- {
- C_DECL_REGISTER (b->decl) = 0;
- DECL_REGISTER (b->decl) = 0;
- TREE_THIS_VOLATILE (b->decl) = 1;
- }
- }
+ objc_volatilize_decl (b->decl);
/* Do not climb up past the current function. */
if (scope->function_body)
/* Warnings for unused labels, errors for undefined labels. */
if (TREE_USED (p) && !DECL_INITIAL (p))
{
- error ("%Jlabel %qD used but not defined", p, p);
+ error ("label %q+D used but not defined", p);
DECL_INITIAL (p) = error_mark_node;
}
else if (!TREE_USED (p) && warn_unused_label)
{
if (DECL_INITIAL (p))
- warning (0, "%Jlabel %qD defined but not used", p, p);
+ warning (0, "label %q+D defined but not used", p);
else
- warning (0, "%Jlabel %qD declared but not defined", p, p);
+ warning (0, "label %q+D declared but not defined", p);
}
/* Labels go in BLOCK_VARS. */
TREE_CHAIN (p) = BLOCK_VARS (block);
if (!DECL_EXTERNAL (p)
&& DECL_INITIAL (p) == 0)
{
- error ("%Jnested function %qD declared but never defined", p, p);
+ error ("nested function %q+D declared but never defined", p);
undef_nested_function = true;
}
goto common_symbol;
case VAR_DECL:
/* Warnings for unused variables. */
- if (warn_unused_variable
- && !TREE_USED (p)
+ if (!TREE_USED (p)
+ && !TREE_NO_WARNING (p)
&& !DECL_IN_SYSTEM_HEADER (p)
&& DECL_NAME (p)
&& !DECL_ARTIFICIAL (p)
&& scope != file_scope
&& scope != external_scope)
- warning (0, "%Junused variable %qD", p, p);
+ warning (OPT_Wunused_variable, "unused variable %q+D", p);
if (b->inner_comp)
{
- error ("%Jtype of array %qD completed incompatibly with"
- " implicit initialization", p, p);
+ error ("type of array %q+D completed incompatibly with"
+ " implicit initialization", p);
}
/* Fall through. */
agree on the number of arguments. */
if (END_OF_ARGLIST (oldargtype))
{
- error ("%Jprototype for %qD declares more arguments "
- "than previous old-style definition", newdecl, newdecl);
+ error ("prototype for %q+D declares more arguments "
+ "than previous old-style definition", newdecl);
return false;
}
else if (END_OF_ARGLIST (newargtype))
{
- error ("%Jprototype for %qD declares fewer arguments "
- "than previous old-style definition", newdecl, newdecl);
+ error ("prototype for %q+D declares fewer arguments "
+ "than previous old-style definition", newdecl);
return false;
}
for the arg. */
else if (!comptypes (oldargtype, newargtype))
{
- error ("%Jprototype for %qD declares argument %d"
+ error ("prototype for %q+D declares argument %d"
" with incompatible type",
- newdecl, newdecl, i);
+ newdecl, i);
return false;
}
/* If we get here, no errors were found, but do issue a warning
for this poor-style construct. */
- warning (0, "%Jprototype for %qD follows non-prototype definition",
- newdecl, newdecl);
+ warning (0, "prototype for %q+D follows non-prototype definition",
+ newdecl);
return true;
#undef END_OF_ARGLIST
}
first in a pair of mismatched declarations, using the diagnostic
function DIAG. */
static void
-locate_old_decl (tree decl, void (*diag)(const char *, ...))
+locate_old_decl (tree decl, void (*diag)(const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2))
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
;
else if (DECL_INITIAL (decl))
- diag (N_("%Jprevious definition of %qD was here"), decl, decl);
+ diag (G_("previous definition of %q+D was here"), decl);
else if (C_DECL_IMPLICIT (decl))
- diag (N_("%Jprevious implicit declaration of %qD was here"), decl, decl);
+ diag (G_("previous implicit declaration of %q+D was here"), decl);
else
- diag (N_("%Jprevious declaration of %qD was here"), decl, decl);
+ diag (G_("previous declaration of %q+D was here"), decl);
}
/* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL.
bool warned = false;
bool retval = true;
+#define DECL_EXTERN_INLINE(DECL) (DECL_DECLARED_INLINE_P (DECL) \
+ && DECL_EXTERNAL (DECL))
+
/* If we have error_mark_node for either decl or type, just discard
the previous decl - we're in an error cascade already. */
if (olddecl == error_mark_node || newdecl == error_mark_node)
&& DECL_BUILT_IN (olddecl)
&& !C_DECL_DECLARED_BUILTIN (olddecl)))
{
- error ("%J%qD redeclared as different kind of symbol",
- newdecl, newdecl);
+ error ("%q+D redeclared as different kind of symbol", newdecl);
locate_old_decl (olddecl, error);
}
else if (TREE_PUBLIC (newdecl))
- warning (0, "%Jbuilt-in function %qD declared as non-function",
- newdecl, newdecl);
- else if (warn_shadow)
- warning (0, "%Jdeclaration of %qD shadows a built-in function",
- newdecl, newdecl);
+ warning (0, "built-in function %q+D declared as non-function",
+ newdecl);
+ else
+ warning (OPT_Wshadow, "declaration of %q+D shadows "
+ "a built-in function", newdecl);
return false;
}
given scope. */
if (TREE_CODE (olddecl) == CONST_DECL)
{
- error ("%Jredeclaration of enumerator %qD", newdecl, newdecl);
+ error ("redeclaration of enumerator %q+D", newdecl);
locate_old_decl (olddecl, error);
return false;
}
/* If types don't match for a built-in, throw away the
built-in. No point in calling locate_old_decl here, it
won't print anything. */
- warning (0, "%Jconflicting types for built-in function %qD",
- newdecl, newdecl);
+ warning (0, "conflicting types for built-in function %q+D",
+ newdecl);
return false;
}
}
&& TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
&& C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
{
- pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
+ pedwarn ("conflicting types for %q+D", newdecl);
/* Make sure we keep void as the return type. */
TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
&& TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
&& C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
{
- pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
+ pedwarn ("conflicting types for %q+D", newdecl);
/* Make sure we keep void as the return type. */
TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
pedwarned = true;
else
{
if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype))
- error ("%J conflicting type qualifiers for %qD", newdecl, newdecl);
+ error ("conflicting type qualifiers for %q+D", newdecl);
else
- error ("%Jconflicting types for %qD", newdecl, newdecl);
+ error ("conflicting types for %q+D", newdecl);
diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
locate_old_decl (olddecl, error);
return false;
if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl))
return true; /* Allow OLDDECL to continue in use. */
- error ("%Jredefinition of typedef %qD", newdecl, newdecl);
+ error ("redefinition of typedef %q+D", newdecl);
locate_old_decl (olddecl, error);
return false;
}
Multiple definitions are not allowed (6.9p3,5) but GCC permits
two definitions if one is 'extern inline' and one is not. The non-
extern-inline definition supersedes the extern-inline definition. */
+
else if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
/* If you declare a built-in function name as static, or
|| (DECL_INITIAL (newdecl)
&& !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
{
- if (warn_shadow)
- warning (0, "%Jdeclaration of %qD shadows a built-in function",
- newdecl, newdecl);
+ warning (OPT_Wshadow, "declaration of %q+D shadows "
+ "a built-in function", newdecl);
/* Discard the old built-in function. */
return false;
}
{
if (DECL_INITIAL (olddecl))
{
- /* 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)
+ /* If both decls are in the same TU and the new declaration
+ isn't overriding an extern inline reject the new decl.
+ When we handle c99 style inline rules we'll want to reject
+ the following:
+
+ DECL_EXTERN_INLINE (olddecl)
+ && !DECL_EXTERN_INLINE (newdecl)
+
+ if they're in the same translation unit. Until we implement
+ the full semantics we accept the construct. */
+ if (!(DECL_EXTERN_INLINE (olddecl)
+ && !DECL_EXTERN_INLINE (newdecl))
&& same_translation_unit_p (newdecl, olddecl))
{
- error ("%Jredefinition of %qD", newdecl, newdecl);
+ error ("redefinition of %q+D", 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. */
occur only in Objective C; see also above. (FIXME: Make
Objective C use normal builtins.) */
if (!DECL_IS_BUILTIN (olddecl)
- && !(DECL_EXTERNAL (olddecl)
- && DECL_DECLARED_INLINE_P (olddecl)))
+ && !DECL_EXTERN_INLINE (olddecl))
{
- error ("%Jstatic declaration of %qD follows "
- "non-static declaration", newdecl, newdecl);
+ error ("static declaration of %q+D follows "
+ "non-static declaration", newdecl);
locate_old_decl (olddecl, error);
}
return false;
{
if (DECL_CONTEXT (olddecl))
{
- error ("%Jnon-static declaration of %qD follows "
- "static declaration", newdecl, newdecl);
+ error ("non-static declaration of %q+D follows "
+ "static declaration", newdecl);
locate_old_decl (olddecl, error);
return false;
}
else if (warn_traditional)
{
- warning (0, "%Jnon-static declaration of %qD follows "
- "static declaration", newdecl, newdecl);
+ warning (OPT_Wtraditional, "non-static declaration of %q+D "
+ "follows static declaration", newdecl);
warned = true;
}
}
{
/* Only variables can be thread-local, and all declarations must
agree on this property. */
- if (DECL_THREAD_LOCAL (newdecl) != DECL_THREAD_LOCAL (olddecl))
+ if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
{
- if (DECL_THREAD_LOCAL (newdecl))
- error ("%Jthread-local declaration of %qD follows "
- "non-thread-local declaration", newdecl, newdecl);
+ if (DECL_THREAD_LOCAL_P (newdecl))
+ error ("thread-local declaration of %q+D follows "
+ "non-thread-local declaration", newdecl);
else
- error ("%Jnon-thread-local declaration of %qD follows "
- "thread-local declaration", newdecl, newdecl);
+ error ("non-thread-local declaration of %q+D follows "
+ "thread-local declaration", newdecl);
locate_old_decl (olddecl, error);
return false;
/* Multiple initialized definitions are not allowed (6.9p3,5). */
if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
{
- error ("%Jredefinition of %qD", newdecl, newdecl);
+ error ("redefinition of %q+D", newdecl);
locate_old_decl (olddecl, error);
return false;
}
{
if (!DECL_FILE_SCOPE_P (olddecl))
{
- error ("%Jextern declaration of %qD follows "
- "declaration with no linkage", newdecl, newdecl);
+ error ("extern declaration of %q+D follows "
+ "declaration with no linkage", newdecl);
locate_old_decl (olddecl, error);
return false;
}
else if (warn_traditional)
{
- warning (0, "%Jnon-static declaration of %qD follows "
- "static declaration", newdecl, newdecl);
+ warning (OPT_Wtraditional, "non-static declaration of %q+D "
+ "follows static declaration", newdecl);
warned = true;
}
}
else
{
if (TREE_PUBLIC (newdecl))
- error ("%Jnon-static declaration of %qD follows "
- "static declaration", newdecl, newdecl);
+ error ("non-static declaration of %q+D follows "
+ "static declaration", newdecl);
else
- error ("%Jstatic declaration of %qD follows "
- "non-static declaration", newdecl, newdecl);
+ error ("static declaration of %q+D follows "
+ "non-static declaration", newdecl);
locate_old_decl (olddecl, error);
return false;
}
else if (DECL_EXTERNAL (olddecl))
{
- error ("%Jdeclaration of %qD with no linkage follows "
- "extern declaration", newdecl, newdecl);
+ error ("declaration of %q+D with no linkage follows "
+ "extern declaration", newdecl);
locate_old_decl (olddecl, error);
}
else
{
- error ("%Jredeclaration of %qD with no linkage",
- newdecl, newdecl);
+ error ("redeclaration of %q+D with no linkage", newdecl);
locate_old_decl (olddecl, error);
}
/* warnings */
/* All decls must agree on a visibility. */
- if (DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (newdecl), TS_DECL_WITH_VIS)
+ && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
&& DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
{
- warning (0, "%Jredeclaration of %qD with different visibility "
- "(old visibility preserved)", newdecl, newdecl);
+ warning (0, "redeclaration of %q+D with different visibility "
+ "(old visibility preserved)", newdecl);
warned = true;
}
if (DECL_DECLARED_INLINE_P (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
{
- warning (0, "%Jinline declaration of %qD follows "
- "declaration with attribute noinline", newdecl, newdecl);
+ warning (OPT_Wattributes, "inline declaration of %qD follows "
+ "declaration with attribute noinline", newdecl);
warned = true;
}
else if (DECL_DECLARED_INLINE_P (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
{
- warning (0, "%Jdeclaration of %qD with attribute noinline follows "
- "inline declaration ", newdecl, newdecl);
+ warning (OPT_Wattributes, "declaration of %q+D with attribute "
+ "noinline follows inline declaration ", newdecl);
warned = true;
}
{
if (TREE_USED (olddecl))
{
- warning (0, "%J%qD declared inline after being called",
- olddecl, olddecl);
+ warning (0, "%q+D declared inline after being called", olddecl);
warned = true;
}
else if (DECL_INITIAL (olddecl))
{
- warning (0, "%J%qD declared inline after its definition",
- olddecl, olddecl);
+ warning (0, "%q+D declared inline after its definition", olddecl);
warned = true;
}
}
if (TREE_CODE (newdecl) == PARM_DECL
&& (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
{
- error ("%Jredefinition of parameter %qD", newdecl, newdecl);
+ error ("redefinition of parameter %q+D", newdecl);
locate_old_decl (olddecl, error);
return false;
}
&& !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl))
/* Don't warn about forward parameter decls. */
&& !(TREE_CODE (newdecl) == PARM_DECL
- && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)))
+ && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
+ /* Don't warn about a variable definition following a declaration. */
+ && !(TREE_CODE (newdecl) == VAR_DECL
+ && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)))
{
- warning (0, "%Jredundant redeclaration of %qD", newdecl, newdecl);
+ warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D",
+ newdecl);
warned = true;
}
if (warned || pedwarned)
locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
+#undef DECL_EXTERN_INLINE
+
return retval;
}
}
}
- /* Keep the old rtl since we can safely use it. */
- COPY_DECL_RTL (olddecl, newdecl);
/* Merge the type qualifiers. */
if (TREE_READONLY (newdecl))
&& !C_DECL_BUILTIN_PROTOTYPE (olddecl)))
DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
- /* Merge the unused-warning information. */
- if (DECL_IN_SYSTEM_HEADER (olddecl))
- DECL_IN_SYSTEM_HEADER (newdecl) = 1;
- else if (DECL_IN_SYSTEM_HEADER (newdecl))
- DECL_IN_SYSTEM_HEADER (olddecl) = 1;
-
/* Merge the initialization information. */
if (DECL_INITIAL (newdecl) == 0)
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
- /* Merge the section attribute.
- We want to issue an error if the sections conflict but that must be
- done later in decl_attributes since we are called before attributes
- are assigned. */
- if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
- DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
-
- /* Copy the assembler name.
- Currently, it can only be defined in the prototype. */
- COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
-
- /* Use visibility of whichever declaration had it specified */
- if (DECL_VISIBILITY_SPECIFIED (olddecl))
- {
- DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
- DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
- }
-
- if (TREE_CODE (newdecl) == FUNCTION_DECL)
- {
- DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
- DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
- DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
- DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
- |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
- TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
- 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. */
- merge_weak (newdecl, olddecl);
-
- /* For functions, static overrides non-static. */
- if (TREE_CODE (newdecl) == FUNCTION_DECL)
- {
- TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
- /* This is since we don't automatically
- 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))
- TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
- }
- if (DECL_EXTERNAL (newdecl))
- {
- TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
- DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
-
- /* An extern decl does not override previous storage class. */
- TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
- if (!DECL_EXTERNAL (newdecl))
- {
- DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
- DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
- }
- }
- else
- {
- TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
- TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
- }
-
- if (TREE_CODE (newdecl) == FUNCTION_DECL)
- {
- /* If we're redefining a function previously defined as extern
- inline, make sure we emit debug info for the inline before we
- throw it away, in case it was inlined into a function that hasn't
- been written out yet. */
- if (new_is_definition && DECL_INITIAL (olddecl))
- {
- if (TREE_USED (olddecl)
- /* In unit-at-a-time mode we never inline re-defined extern
- inline functions. */
- && !flag_unit_at_a_time
- && cgraph_function_possibly_inlined_p (olddecl))
- (*debug_hooks->outlining_inline_function) (olddecl);
-
- /* The new defn must not be inline. */
- DECL_INLINE (newdecl) = 0;
- DECL_UNINLINABLE (newdecl) = 1;
- }
- else
- {
- /* If either decl says `inline', this fn is inline,
- unless its definition was passed already. */
- if (DECL_DECLARED_INLINE_P (newdecl)
- || DECL_DECLARED_INLINE_P (olddecl))
- DECL_DECLARED_INLINE_P (newdecl) = 1;
-
- DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
- = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
- }
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
+ {
+ /* Merge the unused-warning information. */
+ if (DECL_IN_SYSTEM_HEADER (olddecl))
+ DECL_IN_SYSTEM_HEADER (newdecl) = 1;
+ else if (DECL_IN_SYSTEM_HEADER (newdecl))
+ DECL_IN_SYSTEM_HEADER (olddecl) = 1;
+
+ /* Merge the section attribute.
+ We want to issue an error if the sections conflict but that must be
+ done later in decl_attributes since we are called before attributes
+ are assigned. */
+ if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
+ DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
+
+ /* Copy the assembler name.
+ Currently, it can only be defined in the prototype. */
+ COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
+
+ /* Use visibility of whichever declaration had it specified */
+ if (DECL_VISIBILITY_SPECIFIED (olddecl))
+ {
+ DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+ DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
+ }
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
+ DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
+ DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
+ |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
+ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ 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. */
+ merge_weak (newdecl, olddecl);
- if (DECL_BUILT_IN (olddecl))
- {
- /* If redeclaring a builtin function, it stays built in.
- But it gets tagged as having been declared. */
- DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
- DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
- C_DECL_DECLARED_BUILTIN (newdecl) = 1;
- if (new_is_prototype)
- C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
- else
- C_DECL_BUILTIN_PROTOTYPE (newdecl)
- = C_DECL_BUILTIN_PROTOTYPE (olddecl);
- }
+ /* For functions, static overrides non-static. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
+ /* This is since we don't automatically
+ 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))
+ TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
+ }
+ }
+
+ if (DECL_EXTERNAL (newdecl))
+ {
+ TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
+ DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
+
+ /* An extern decl does not override previous storage class. */
+ TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
+ if (!DECL_EXTERNAL (newdecl))
+ {
+ DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
+ DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
+ }
+ }
+ else
+ {
+ TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
+ TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
+ }
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ /* If we're redefining a function previously defined as extern
+ inline, make sure we emit debug info for the inline before we
+ throw it away, in case it was inlined into a function that hasn't
+ been written out yet. */
+ if (new_is_definition && DECL_INITIAL (olddecl))
+ {
+ if (TREE_USED (olddecl)
+ /* In unit-at-a-time mode we never inline re-defined extern
+ inline functions. */
+ && !flag_unit_at_a_time
+ && cgraph_function_possibly_inlined_p (olddecl))
+ (*debug_hooks->outlining_inline_function) (olddecl);
+
+ /* The new defn must not be inline. */
+ DECL_INLINE (newdecl) = 0;
+ DECL_UNINLINABLE (newdecl) = 1;
+ }
+ else
+ {
+ /* If either decl says `inline', this fn is inline,
+ unless its definition was passed already. */
+ if (DECL_DECLARED_INLINE_P (newdecl)
+ || DECL_DECLARED_INLINE_P (olddecl))
+ DECL_DECLARED_INLINE_P (newdecl) = 1;
+
+ DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
+ = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
+ }
- /* Also preserve various other info from the definition. */
- if (!new_is_definition)
- {
- DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
- DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
- DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
- DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
- DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
-
- /* Set DECL_INLINE on the declaration if we've got a body
- from which to instantiate. */
- if (DECL_INLINE (olddecl) && !DECL_UNINLINABLE (newdecl))
- {
- DECL_INLINE (newdecl) = 1;
- DECL_ABSTRACT_ORIGIN (newdecl)
- = DECL_ABSTRACT_ORIGIN (olddecl);
- }
- }
- else
- {
- /* If a previous declaration said inline, mark the
- definition as inlinable. */
- if (DECL_DECLARED_INLINE_P (newdecl)
- && !DECL_UNINLINABLE (newdecl))
- DECL_INLINE (newdecl) = 1;
- }
- }
+ if (DECL_BUILT_IN (olddecl))
+ {
+ /* If redeclaring a builtin function, it stays built in.
+ But it gets tagged as having been declared. */
+ DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
+ DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+ C_DECL_DECLARED_BUILTIN (newdecl) = 1;
+ if (new_is_prototype)
+ C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
+ else
+ C_DECL_BUILTIN_PROTOTYPE (newdecl)
+ = C_DECL_BUILTIN_PROTOTYPE (olddecl);
+ }
- /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
+ /* Also preserve various other info from the definition. */
+ if (!new_is_definition)
+ {
+ DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
+ DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
+ DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
+ DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+ DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
+
+ /* Set DECL_INLINE on the declaration if we've got a body
+ from which to instantiate. */
+ if (DECL_INLINE (olddecl) && !DECL_UNINLINABLE (newdecl))
+ {
+ DECL_INLINE (newdecl) = 1;
+ DECL_ABSTRACT_ORIGIN (newdecl)
+ = DECL_ABSTRACT_ORIGIN (olddecl);
+ }
+ }
+ else
+ {
+ /* If a previous declaration said inline, mark the
+ definition as inlinable. */
+ if (DECL_DECLARED_INLINE_P (newdecl)
+ && !DECL_UNINLINABLE (newdecl))
+ DECL_INLINE (newdecl) = 1;
+ }
+ }
+
+ /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */
{
unsigned olddecl_uid = DECL_UID (olddecl);
tree olddecl_context = DECL_CONTEXT (olddecl);
-
+
memcpy ((char *) olddecl + sizeof (struct tree_common),
(char *) newdecl + sizeof (struct tree_common),
- sizeof (struct tree_decl) - sizeof (struct tree_common));
+ sizeof (struct tree_decl_common) - sizeof (struct tree_common));
+ switch (TREE_CODE (olddecl))
+ {
+ case FIELD_DECL:
+ case VAR_DECL:
+ case PARM_DECL:
+ case LABEL_DECL:
+ case RESULT_DECL:
+ case CONST_DECL:
+ case TYPE_DECL:
+ case FUNCTION_DECL:
+ memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+ (char *) newdecl + sizeof (struct tree_decl_common),
+ tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
+ break;
+
+ default:
+
+ memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+ (char *) newdecl + sizeof (struct tree_decl_common),
+ sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common));
+ }
DECL_UID (olddecl) = olddecl_uid;
DECL_CONTEXT (olddecl) = olddecl_context;
}
tree newtype = NULL, oldtype = NULL;
if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
- return false;
+ {
+ /* Avoid `unused variable' and other warnings warnings for OLDDECL. */
+ TREE_NO_WARNING (olddecl) = 1;
+ return false;
+ }
merge_decls (newdecl, olddecl, newtype, oldtype);
return true;
/* No shadow warnings for internally generated vars. */
|| DECL_IS_BUILTIN (new_decl)
/* No shadow warnings for vars made for inlining. */
- || DECL_FROM_INLINE (new_decl)
- /* Don't warn about the parm names in function declarator
- within a function declarator. It would be nice to avoid
- warning in any function declarator in a declaration, as
- opposed to a definition, but there is no way to tell
- it's not a definition at this point. */
- || (TREE_CODE (new_decl) == PARM_DECL && current_scope->outer->parm_flag))
+ || DECL_FROM_INLINE (new_decl))
return;
/* Is anything being shadowed? Invisible decls do not count. */
if (old_decl == error_mark_node)
{
- warning (0, "%Jdeclaration of %qD shadows previous non-variable",
- new_decl, new_decl);
+ warning (OPT_Wshadow, "declaration of %q+D shadows previous "
+ "non-variable", new_decl);
break;
}
else if (TREE_CODE (old_decl) == PARM_DECL)
- warning (0, "%Jdeclaration of %qD shadows a parameter",
- new_decl, new_decl);
+ warning (OPT_Wshadow, "declaration of %q+D shadows a parameter",
+ new_decl);
else if (DECL_FILE_SCOPE_P (old_decl))
- warning (0, "%Jdeclaration of %qD shadows a global declaration",
- new_decl, new_decl);
+ warning (OPT_Wshadow, "declaration of %q+D shadows a global "
+ "declaration", new_decl);
else if (TREE_CODE (old_decl) == FUNCTION_DECL
&& DECL_BUILT_IN (old_decl))
{
- warning (0, "%Jdeclaration of %qD shadows a built-in function",
- new_decl, new_decl);
+ warning (OPT_Wshadow, "declaration of %q+D shadows "
+ "a built-in function", new_decl);
break;
}
else
- warning (0, "%Jdeclaration of %qD shadows a previous local",
- new_decl, new_decl);
+ warning (OPT_Wshadow, "declaration of %q+D shadows a previous local",
+ new_decl);
- warning (0, "%Jshadowed declaration is here", old_decl);
+ warning (OPT_Wshadow, "%Jshadowed declaration is here", old_decl);
break;
}
visdecl = b->decl;
vistype = TREE_TYPE (visdecl);
}
- if (warn_nested_externs
- && scope != file_scope
+ if (scope != file_scope
&& !DECL_IN_SYSTEM_HEADER (x))
- warning (0, "nested extern declaration of %qD", x);
+ warning (OPT_Wnested_externs, "nested extern declaration of %qD", x);
while (b && !B_IN_EXTERNAL_SCOPE (b))
{
}
}
- warn_if_shadowing (x);
+ if (TREE_CODE (x) != PARM_DECL)
+ warn_if_shadowing (x);
skip_external_and_shadow_checks:
if (TREE_CODE (x) == TYPE_DECL)
static void
implicit_decl_warning (tree id, tree olddecl)
{
- void (*diag) (const char *, ...);
+ void (*diag) (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
switch (mesg_implicit_function_declaration)
{
case 0: return;
default: gcc_unreachable ();
}
- diag (N_("implicit declaration of function %qE"), id);
+ diag (G_("implicit declaration of function %qE"), id);
if (olddecl)
locate_old_decl (olddecl, diag);
}
/*invisible=*/false, /*nested=*/false);
}
- if (warn_traditional && !in_system_header && lookup_name (name))
- warning (0, "%Htraditional C lacks a separate namespace for labels, "
- "identifier %qE conflicts", &location, name);
+ if (!in_system_header && lookup_name (name))
+ warning (OPT_Wtraditional, "%Htraditional C lacks a separate namespace "
+ "for labels, identifier %qE conflicts", &location, name);
nlist_se = XOBNEW (&parser_obstack, struct c_label_list);
nlist_se->next = label_context_stack_se->labels_def;
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
&& MAIN_NAME_P (DECL_NAME (decl)))
- warning (0, "%J%qD is usually a function", decl, decl);
+ warning (OPT_Wmain, "%q+D is usually a function", decl);
if (initialized)
/* Is it valid for this decl to have an initializer at all?
if (TREE_CODE (decl) == VAR_DECL
&& !initialized
&& TREE_PUBLIC (decl)
- && !DECL_THREAD_LOCAL (decl)
+ && !DECL_THREAD_LOCAL_P (decl)
&& !flag_no_common)
DECL_COMMON (decl) = 1;
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
- warning (0, "%Jinline function %qD given attribute noinline", decl, decl);
+ warning (OPT_Wattributes, "inline function %q+D given attribute noinline",
+ decl);
/* Add this decl to the current scope.
TEM may equal DECL or it may be a previous decl of the same name. */
/* Get the completed type made by complete_array_type. */
type = TREE_TYPE (decl);
- if (failure == 1)
- error ("%Jinitializer fails to determine size of %qD", decl, decl);
-
- else if (failure == 2)
+ switch (failure)
{
+ case 1:
+ error ("initializer fails to determine size of %q+D", decl);
+ break;
+
+ case 2:
if (do_default)
- error ("%Jarray size missing in %qD", decl, decl);
+ error ("array size missing in %q+D", decl);
/* If a `static' var's size isn't known,
make it extern as well as static, so it does not get
allocated.
and it will get allocated. */
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
+ break;
+
+ case 3:
+ error ("zero or negative size array %q+D", decl);
+ break;
+
+ case 0:
+ /* For global variables, update the copy of the type that
+ exists in the binding. */
+ if (TREE_PUBLIC (decl))
+ {
+ struct c_binding *b_ext = I_SYMBOL_BINDING (DECL_NAME (decl));
+ while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
+ b_ext = b_ext->shadowed;
+ if (b_ext)
+ {
+ if (b_ext->type)
+ b_ext->type = composite_type (b_ext->type, type);
+ else
+ b_ext->type = type;
+ }
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
}
- else if (failure == 3)
- error ("%Jzero or negative size array %qD", decl, decl);
if (DECL_INITIAL (decl))
TREE_TYPE (DECL_INITIAL (decl)) = type;
is an error. */
: !DECL_EXTERNAL (decl)))
{
- error ("%Jstorage size of %qD isn%'t known", decl, decl);
+ error ("storage size of %q+D isn%'t known", decl);
TREE_TYPE (decl) = error_mark_node;
}
if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
constant_expression_warning (DECL_SIZE (decl));
else
- error ("%Jstorage size of %qD isn%'t constant", decl, decl);
+ error ("storage size of %q+D isn%'t constant", decl);
}
if (TREE_USED (type))
&& TREE_CODE (decl) == VAR_DECL
&& !C_DECL_REGISTER (decl)
&& !TREE_STATIC (decl))
- warning (0, "%Jignoring asm-specifier for non-static local "
- "variable %qD", decl, decl);
- else if (C_DECL_REGISTER (decl))
- change_decl_assembler_name (decl, get_identifier (asmspec));
+ warning (0, "ignoring asm-specifier for non-static local "
+ "variable %q+D", decl);
else
set_user_assembler_name (decl, asmspec);
}
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gcc_personality_sj0"
: "__gcc_personality_v0");
+ default_init_unwind_resume_libfunc ();
using_eh_for_cleanups ();
}
warning (0, "%qs is narrower than values of its type", name);
}
}
+
+/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */
+static tree
+c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
+{
+ /* Extended integer types of the same width as a standard type have
+ lesser rank, so those of the same width as int promote to int or
+ unsigned int and are valid for printf formats expecting int or
+ unsigned int. To avoid such special cases, avoid creating
+ extended integer types for bit-fields if a standard integer type
+ is available. */
+ if (width == TYPE_PRECISION (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+ if (width == TYPE_PRECISION (signed_char_type_node))
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+ if (width == TYPE_PRECISION (short_integer_type_node))
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+ if (width == TYPE_PRECISION (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+ if (width == TYPE_PRECISION (long_long_integer_type_node))
+ return (unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+ return build_nonstandard_integer_type (width, unsignedp);
+}
\f
/* Given declspecs and a declarator,
determine the name and type of the object declared
- 1. Do the calculation in index_type, so that
if it is a variable the computations will be
done in the proper mode. */
- itype = fold (build2 (MINUS_EXPR, index_type,
- convert (index_type, size),
- convert (index_type,
- size_one_node)));
+ itype = fold_build2 (MINUS_EXPR, index_type,
+ convert (index_type, size),
+ convert (index_type,
+ size_one_node));
/* If that overflowed, the array is too big. ???
While a size of INT_MAX+1 technically shouldn't
index_type, before the subtraction. Handling
this case seems like an unnecessary
complication. */
- if (TREE_OVERFLOW (itype))
+ if (TREE_CODE (itype) == INTEGER_CST
+ && TREE_OVERFLOW (itype))
{
error ("size of array %qs is too large", name);
type = error_mark_node;
else
type = build_array_type (type, itype);
- if (size_varies)
- C_TYPE_VARIABLE_SIZE (type) = 1;
-
- /* The GCC extension for zero-length arrays differs from
- ISO flexible array members in that sizeof yields
- zero. */
- if (size && integer_zerop (size))
+ if (type != error_mark_node)
{
- TYPE_SIZE (type) = bitsize_zero_node;
- TYPE_SIZE_UNIT (type) = size_zero_node;
+ if (size_varies)
+ C_TYPE_VARIABLE_SIZE (type) = 1;
+
+ /* The GCC extension for zero-length arrays differs from
+ ISO flexible array members in that sizeof yields
+ zero. */
+ if (size && integer_zerop (size))
+ {
+ TYPE_SIZE (type) = bitsize_zero_node;
+ TYPE_SIZE_UNIT (type) = size_zero_node;
+ }
}
if (decl_context != PARM
them for noreturn functions. */
if (VOID_TYPE_P (type) && really_funcdef)
pedwarn ("function definition has qualified void return type");
- else if (warn_return_type)
- warning (0, "type qualifiers ignored on function return type");
+ else
+ warning (OPT_Wreturn_type,
+ "type qualifiers ignored on function return type");
type = c_build_qualified_type (type, type_quals);
}
if (TREE_CODE (type) == ARRAY_TYPE
&& COMPLETE_TYPE_P (type)
- && TREE_OVERFLOW (TYPE_SIZE (type)))
+ && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
+ && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
{
error ("size of array %qs is too large", name);
/* If we proceed with the array type as it is, we'll eventually
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
decl_attributes (&decl, returned_attrs, 0);
if (declspecs->inline_p)
- pedwarn ("%Jtypedef %qD declared %<inline%>", decl, decl);
+ pedwarn ("typedef %q+D declared %<inline%>", decl);
return decl;
}
/* We don't yet implement attributes in this context. */
if (array_ptr_attrs != NULL_TREE)
- warning (0, "attributes in parameter array declarator ignored");
+ warning (OPT_Wattributes,
+ "attributes in parameter array declarator ignored");
size_varies = 0;
}
promoted_type = c_type_promotes_to (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);
+ pedwarn ("parameter %q+D declared %<inline%>", decl);
}
else if (decl_context == FIELD)
{
C_DECL_VARIABLE_SIZE (decl) = 1;
if (declspecs->inline_p)
- pedwarn ("%Jvariable %qD declared %<inline%>", decl, decl);
+ pedwarn ("variable %q+D declared %<inline%>", decl);
/* At file scope, an initialized extern declaration may follow
a static declaration. In that case, DECL_EXTERNAL will be
if (threadp)
{
if (targetm.have_tls)
- DECL_THREAD_LOCAL (decl) = 1;
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
else
/* A mere warning is sure to result in improper semantics
at runtime. Don't bother to allow this to compile. */
/* If a type has volatile components, it should be stored in memory.
Otherwise, the fact that those components are volatile
- will be ignored, and would even crash the compiler. */
- if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
+ will be ignored, and would even crash the compiler.
+ Of course, this only makes sense on VAR,PARM, and RESULT decl's. */
+ if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))
+ && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
+ || TREE_CODE (decl) == RESULT_DECL))
{
/* It is not an error for a structure with volatile fields to
be declared register, but reset DECL_REGISTER since it
{
tree arg_types = arg_info->types;
- if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag
- && !in_system_header)
- warning (0, "function declaration isn%'t a prototype");
+ if (arg_types == 0 && !funcdef_flag && !in_system_header)
+ warning (OPT_Wstrict_prototypes,
+ "function declaration isn%'t a prototype");
if (arg_types == error_mark_node)
return 0; /* don't set TYPE_ARG_TYPES in this case */
if (funcdef_flag)
{
if (DECL_NAME (parm))
- error ("%Jparameter %u (%qD) has incomplete type",
- parm, parmno, parm);
+ error ("parameter %u (%q+D) has incomplete type",
+ parmno, parm);
else
error ("%Jparameter %u has incomplete type",
parm, parmno);
else if (VOID_TYPE_P (type))
{
if (DECL_NAME (parm))
- warning (0, "%Jparameter %u (%qD) has void type",
- parm, parmno, parm);
+ warning (0, "parameter %u (%q+D) has void type",
+ parmno, parm);
else
warning (0, "%Jparameter %u has void type",
parm, parmno);
}
}
+
+ if (DECL_NAME (parm) && TREE_USED (parm))
+ warn_if_shadowing (parm);
}
return arg_types;
}
/* Check for forward decls that never got their actual decl. */
if (TREE_ASM_WRITTEN (decl))
- error ("%Jparameter %qD has just a forward declaration",
- decl, decl);
+ error ("parameter %q+D has just a forward declaration", decl);
/* Check for (..., void, ...) and issue an error. */
else if (VOID_TYPE_P (type) && !DECL_NAME (decl))
{
for (y = fieldlist; y != x; y = TREE_CHAIN (y))
if (DECL_NAME (y) == DECL_NAME (x))
{
- error ("%Jduplicate member %qD", x, x);
+ error ("duplicate member %q+D", x);
DECL_NAME (x) = NULL_TREE;
}
}
slot = htab_find_slot (htab, y, INSERT);
if (*slot)
{
- error ("%Jduplicate member %qD", x, x);
+ error ("duplicate member %q+D", x);
DECL_NAME (x) = NULL_TREE;
}
*slot = y;
if (width != TYPE_PRECISION (type))
{
TREE_TYPE (*fieldlistp)
- = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+ = c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type));
DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
}
DECL_INITIAL (*fieldlistp) = 0;
TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
TYPE_ALIGN (x) = TYPE_ALIGN (t);
TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
+ C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
+ C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
+ C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
}
/* If this was supposed to be a transparent union, but we can't
/* If the declarator is not suitable for a function definition,
cause a syntax error. */
if (decl1 == 0)
- return 0;
+ {
+ label_context_stack_se = label_context_stack_se->next;
+ label_context_stack_vm = label_context_stack_vm->next;
+ return 0;
+ }
decl_attributes (&decl1, attributes, 0);
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
- warning (0, "%Jinline function %qD given attribute noinline", decl1, decl1);
+ warning (OPT_Wattributes, "inline function %q+D given attribute noinline",
+ decl1);
announce_function (decl1);
&& old_decl != error_mark_node
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
&& C_DECL_ISNT_PROTOTYPE (old_decl))
- warning (0, "function declaration isn%'t a prototype");
+ warning (OPT_Wstrict_prototypes,
+ "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))
- warning (0, "%Jno previous prototype for %qD", decl1, decl1);
+ warning (OPT_Wmissing_prototypes, "no previous prototype for %q+D", decl1);
/* Optionally warn of any def with no previous prototype
if the function has already been used. */
else if (warn_missing_prototypes
&& old_decl != error_mark_node
&& TREE_USED (old_decl)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
- warning (0, "%J%qD was used with no prototype before its definition",
- decl1, decl1);
+ warning (OPT_Wmissing_prototypes,
+ "%q+D was used with no prototype before its definition", decl1);
/* Optionally warn of any global def with no previous declaration. */
else if (warn_missing_declarations
&& TREE_PUBLIC (decl1)
&& old_decl == 0
&& !MAIN_NAME_P (DECL_NAME (decl1)))
- warning (0, "%Jno previous declaration for %qD", decl1, decl1);
+ warning (OPT_Wmissing_declarations, "no previous declaration for %q+D",
+ decl1);
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
else if (warn_missing_declarations
&& old_decl != error_mark_node
&& TREE_USED (old_decl)
&& C_DECL_IMPLICIT (old_decl))
- warning (0, "%J%qD was used with no declaration before its definition",
- decl1, decl1);
+ warning (OPT_Wmissing_declarations,
+ "%q+D was used with no declaration before its definition", decl1);
/* This is a definition, not a reference.
So normally clear DECL_EXTERNAL.
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
- pedwarn ("%Jreturn type of %qD is not %<int%>", decl1, decl1);
+ pedwarn ("return type of %q+D is not %<int%>", decl1);
for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
args = TREE_CHAIN (args))
{
case 1:
if (TYPE_MAIN_VARIANT (type) != integer_type_node)
- pedwarn ("%Jfirst argument of %qD should be %<int%>",
- decl1, decl1);
+ pedwarn ("first argument of %q+D should be %<int%>", decl1);
break;
case 2:
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn ("%Jsecond argument of %qD should be %<char **%>",
- decl1, decl1);
+ pedwarn ("second argument of %q+D should be %<char **%>",
+ decl1);
break;
case 3:
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn ("%Jthird argument of %qD should probably be "
- "%<char **%>", decl1, decl1);
+ pedwarn ("third argument of %q+D should probably be "
+ "%<char **%>", decl1);
break;
}
}
argument because it's only mentioned in an appendix of the
standard. */
if (argct > 0 && (argct < 2 || argct > 3))
- pedwarn ("%J%qD takes only zero or two arguments", decl1, decl1);
+ pedwarn ("%q+D takes only zero or two arguments", decl1);
if (!TREE_PUBLIC (decl1))
- pedwarn ("%J%qD is normally a non-static function", decl1, decl1);
+ pedwarn ("%q+D is normally a non-static function", decl1);
}
/* Record the decl so that the function name is defined.
warning if we got here because ARG_INFO_TYPES was error_mark_node
(this happens when a function definition has just an ellipsis in
its parameter list). */
- else if (warn_traditional && !in_system_header && !current_function_scope
+ else if (!in_system_header && !current_function_scope
&& arg_info->types != error_mark_node)
- warning (0, "%Jtraditional C rejects ISO C style function definitions",
+ warning (OPT_Wtraditional,
+ "%Jtraditional C rejects ISO C style function definitions",
fndecl);
/* Now make all the parameter declarations visible in the function body.
{
DECL_CONTEXT (decl) = current_function_decl;
if (DECL_NAME (decl))
- bind (DECL_NAME (decl), decl, current_scope,
- /*invisible=*/false, /*nested=*/false);
+ {
+ bind (DECL_NAME (decl), decl, current_scope,
+ /*invisible=*/false, /*nested=*/false);
+ if (!TREE_USED (decl))
+ warn_if_shadowing (decl);
+ }
else
error ("%Jparameter name omitted", decl);
}
struct c_binding *b;
tree parm, decl, last;
tree parmids = arg_info->parms;
-
- /* We use DECL_WEAK as a flag to show which parameters have been
- seen already, since it is not used on PARM_DECL. */
-#ifdef ENABLE_CHECKING
- for (b = current_scope->bindings; b; b = b->prev)
- gcc_assert (TREE_CODE (b->decl) != PARM_DECL || !DECL_WEAK (b->decl));
-#endif
+ struct pointer_set_t *seen_args = pointer_set_create ();
if (!in_system_header)
- warning (OPT_Wold_style_definition, "%Jold-style function definition", fndecl);
+ warning (OPT_Wold_style_definition, "%Jold-style function definition",
+ fndecl);
/* Match each formal parameter name with its declaration. Save each
decl in the appropriate TREE_PURPOSE slot of the parmids chain. */
decl = b->decl;
/* If we got something other than a PARM_DECL it is an error. */
if (TREE_CODE (decl) != PARM_DECL)
- error ("%J%qD declared as a non-parameter", decl, decl);
+ error ("%q+D declared as a non-parameter", decl);
/* If the declaration is already marked, we have a duplicate
name. Complain and ignore the duplicate. */
- else if (DECL_WEAK (decl))
+ else if (pointer_set_contains (seen_args, decl))
{
- error ("%Jmultiple parameters named %qD", decl, decl);
+ error ("multiple parameters named %q+D", decl);
TREE_PURPOSE (parm) = 0;
continue;
}
an int. */
else if (VOID_TYPE_P (TREE_TYPE (decl)))
{
- error ("%Jparameter %qD declared with void type", decl, decl);
+ error ("parameter %q+D declared with void type", decl);
TREE_TYPE (decl) = integer_type_node;
DECL_ARG_TYPE (decl) = integer_type_node;
layout_decl (decl, 0);
}
+ warn_if_shadowing (decl);
}
/* If no declaration found, default to int. */
else
DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (fndecl);
pushdecl (decl);
+ warn_if_shadowing (decl);
if (flag_isoc99)
- pedwarn ("%Jtype of %qD defaults to %<int%>", decl, decl);
+ pedwarn ("type of %q+D defaults to %<int%>", decl);
else if (extra_warnings)
- warning (0, "%Jtype of %qD defaults to %<int%>", decl, decl);
+ warning (OPT_Wextra, "type of %q+D defaults to %<int%>", decl);
}
TREE_PURPOSE (parm) = decl;
- DECL_WEAK (decl) = 1;
+ pointer_set_insert (seen_args, decl);
}
/* Now examine the parms chain for incomplete declarations
if (TREE_TYPE (parm) != error_mark_node
&& !COMPLETE_TYPE_P (TREE_TYPE (parm)))
{
- error ("%Jparameter %qD has incomplete type", parm, parm);
+ error ("parameter %q+D has incomplete type", parm);
TREE_TYPE (parm) = error_mark_node;
}
- if (!DECL_WEAK (parm))
+ if (!pointer_set_contains (seen_args, parm))
{
- error ("%Jdeclaration for parameter %qD but no such parameter",
- parm, parm);
+ error ("declaration for parameter %q+D but no such parameter", parm);
/* Pretend the parameter was not missing.
This gets us to a standard state and minimizes
{
last = TREE_PURPOSE (parm);
DECL_ARGUMENTS (fndecl) = last;
- DECL_WEAK (last) = 0;
for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm))
if (TREE_PURPOSE (parm))
{
TREE_CHAIN (last) = TREE_PURPOSE (parm);
last = TREE_PURPOSE (parm);
- DECL_WEAK (last) = 0;
}
TREE_CHAIN (last) = 0;
}
+ pointer_set_destroy (seen_args);
+
/* If there was a previous prototype,
set the DECL_ARG_TYPE of each argument according to
the type previously specified, and report any mismatches. */
/* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
If warn_main is -1 (-Wno-main) we don't want to be warned. */
if (!warn_main)
- pedwarn ("%Jreturn type of %qD is not %<int%>", fndecl, fndecl);
+ pedwarn ("return type of %q+D is not %<int%>", fndecl);
}
else
{
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
inline function, as we might never be compiled separately. */
&& DECL_INLINE (fndecl))
- warning (0, "no return statement in function returning non-void");
+ {
+ warning (OPT_Wreturn_type,
+ "no return statement in function returning non-void");
+ TREE_NO_WARNING (fndecl) = 1;
+ }
/* With just -Wextra, complain only if function returns both with
and without a value. */
if (extra_warnings
&& current_function_returns_value
&& current_function_returns_null)
- warning (0, "this function may return with or without a value");
+ warning (OPT_Wextra, "this function may return with or without a value");
/* Store the end of the function, so that we get good line number
info for the epilogue. */
{
case VAR_DECL:
if (TREE_STATIC (decl))
- error ("%Jdeclaration of static variable %qD in %<for%> loop "
- "initial declaration", decl, decl);
+ error ("declaration of static variable %q+D in %<for%> loop "
+ "initial declaration", decl);
else if (DECL_EXTERNAL (decl))
- error ("%Jdeclaration of %<extern%> variable %qD in %<for%> loop "
- "initial declaration", decl, decl);
+ error ("declaration of %<extern%> variable %q+D in %<for%> loop "
+ "initial declaration", decl);
break;
case RECORD_TYPE:
id);
break;
default:
- error ("%Jdeclaration of non-variable %qD in %<for%> loop "
- "initial declaration", decl, decl);
+ error ("declaration of non-variable %q+D in %<for%> loop "
+ "initial declaration", decl);
}
}
}
functions are not called from anywhere in the C front end, but as
these changes continue, that will change. */
-/* Returns nonzero if the current statement is a full expression,
- i.e. temporaries created during that statement should be destroyed
- at the end of the statement. */
-
-int
-stmts_are_full_exprs_p (void)
-{
- return 0;
-}
-
/* Returns the stmt_tree (if any) to which statements are currently
being added. If there is no active statement-tree, NULL is
returned. */
&& C_IS_RESERVED_WORD (scspec));
i = C_RID_CODE (scspec);
if (extra_warnings && specs->non_sc_seen_p)
- warning (0, "%qE is not at beginning of declaration", scspec);
+ warning (OPT_Wextra, "%qE is not at beginning of declaration", scspec);
switch (i)
{
case RID_INLINE:
cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY);
}
-/* Perform final processing on one file scope's declarations (or the
- external scope's declarations), GLOBALS. */
+/* A subroutine of c_write_global_declarations. Perform final processing
+ on one file scope's declarations (or the external scope's declarations),
+ GLOBALS. */
+
static void
c_write_global_declarations_1 (tree globals)
{
- size_t len = list_length (globals);
- tree *vec = XNEWVEC (tree, len);
- size_t i;
tree decl;
+ bool reconsider;
/* Process the decls in the order they were written. */
- for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
+ for (decl = globals; decl; decl = TREE_CHAIN (decl))
{
- vec[i] = decl;
/* Check for used but undefined static functions using the C
standard's definition of "used", and set TREE_NO_WARNING so
that check_global_declarations doesn't repeat the check. */
&& !TREE_PUBLIC (decl)
&& C_DECL_USED (decl))
{
- pedwarn ("%J%qF used but never defined", decl, decl);
+ pedwarn ("%q+F used but never defined", decl);
TREE_NO_WARNING (decl) = 1;
}
+
+ wrapup_global_declaration_1 (decl);
}
- wrapup_global_declarations (vec, len);
- check_global_declarations (vec, len);
+ do
+ {
+ reconsider = false;
+ for (decl = globals; decl; decl = TREE_CHAIN (decl))
+ reconsider |= wrapup_global_declaration_2 (decl);
+ }
+ while (reconsider);
- free (vec);
+ for (decl = globals; decl; decl = TREE_CHAIN (decl))
+ check_global_declaration_1 (decl);
}
+/* A subroutine of c_write_global_declarations Emit debug information for each
+ of the declarations in GLOBALS. */
+
+static void
+c_write_global_declarations_2 (tree globals)
+{
+ tree decl;
+
+ for (decl = globals; decl ; decl = TREE_CHAIN (decl))
+ debug_hooks->global_decl (decl);
+}
+
+/* Preserve the external declarations scope across a garbage collect. */
+static GTY(()) tree ext_block;
+
void
c_write_global_declarations (void)
{
- tree ext_block, t;
+ tree t;
/* We don't want to do this if generating a PCH. */
if (pch_file)
external_scope = 0;
gcc_assert (!current_scope);
+ if (ext_block)
+ {
+ tree tmp = BLOCK_VARS (ext_block);
+ int flags;
+ FILE * stream = dump_begin (TDI_tu, &flags);
+ if (stream && tmp)
+ {
+ dump_node (tmp, flags & ~TDF_SLIM, stream);
+ dump_end (TDI_tu, stream);
+ }
+ }
+
/* Process all file scopes in this compilation, and the external_scope,
through wrapup_global_declarations and check_global_declarations. */
for (t = all_translation_units; t; t = TREE_CHAIN (t))
/* We're done parsing; proceed to optimize and emit assembly.
FIXME: shouldn't be the front end's responsibility to call this. */
cgraph_optimize ();
+
+ /* After cgraph has had a chance to emit everything that's going to
+ be emitted, output debug information for globals. */
+ if (errorcount == 0 && sorrycount == 0)
+ {
+ timevar_push (TV_SYMOUT);
+ for (t = all_translation_units; t; t = TREE_CHAIN (t))
+ c_write_global_declarations_2 (BLOCK_VARS (DECL_INITIAL (t)));
+ c_write_global_declarations_2 (BLOCK_VARS (ext_block));
+ timevar_pop (TV_SYMOUT);
+ }
+
+ ext_block = NULL;
}
#include "gt-c-decl.h"