/* 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"
#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 '%D' assumed to have one element", decl, decl);
+ warning ("%Jarray %qD assumed to have one element", decl, decl);
complete_array_type (type, NULL_TREE, 1);
if (current_scope && scope->depth == 0)
{
scope->depth--;
- sorry ("GCC supports only %u nested scopes\n", scope->depth);
+ sorry ("GCC supports only %u nested scopes", scope->depth);
}
current_scope = scope;
/* Warnings for unused labels, errors for undefined labels. */
if (TREE_USED (p) && !DECL_INITIAL (p))
{
- error ("%Jlabel `%D' used but not defined", p, p);
+ error ("%Jlabel %qD used but not defined", p, p);
DECL_INITIAL (p) = error_mark_node;
}
else if (!TREE_USED (p) && warn_unused_label)
{
if (DECL_INITIAL (p))
- warning ("%Jlabel `%D' defined but not used", p, p);
+ warning ("%Jlabel %qD defined but not used", p, p);
else
- warning ("%Jlabel `%D' declared but not defined", p, p);
+ warning ("%Jlabel %qD declared but not defined", p, p);
}
/* Labels go in BLOCK_VARS. */
TREE_CHAIN (p) = BLOCK_VARS (block);
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)
- warning ("%Junused variable `%D'", p, p);
+ && scope != file_scope
+ && scope != external_scope)
+ warning ("%Junused variable %qD", p, p);
if (b->inner_comp)
{
/* Pop off the file scope and close this translation unit. */
pop_scope ();
file_scope = 0;
+
+ maybe_apply_pending_pragma_weaks ();
cgraph_finalize_compilation_unit ();
}
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;
if (TREE_CHAIN (t) == 0
&& TYPE_MAIN_VARIANT (type) != void_type_node)
{
- inform ("a parameter list with an ellipsis can't match "
+ inform ("a parameter list with an ellipsis can%'t match "
"an empty parameter name list declaration");
break;
}
if (c_type_promotes_to (type) != type)
{
- inform ("an argument type that has a default promotion can't match "
+ inform ("an argument type that has a default promotion can%'t match "
"an empty parameter name list declaration");
break;
}
agree on the number of arguments. */
if (END_OF_ARGLIST (oldargtype))
{
- error ("%Jprototype for '%D' declares more arguments "
+ error ("%Jprototype for %qD declares more arguments "
"than previous old-style definition", newdecl, newdecl);
return false;
}
else if (END_OF_ARGLIST (newargtype))
{
- error ("%Jprototype for '%D' declares fewer arguments "
+ error ("%Jprototype for %qD declares fewer arguments "
"than previous old-style definition", newdecl, newdecl);
return false;
}
/* 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 '%D' declares arg %d with incompatible type",
+ error ("%Jprototype for %qD declares argument %d"
+ " with incompatible type",
newdecl, newdecl, i);
return false;
}
/* If we get here, no errors were found, but do issue a warning
for this poor-style construct. */
- warning ("%Jprototype for '%D' follows non-prototype definition",
+ warning ("%Jprototype for %qD follows non-prototype definition",
newdecl, newdecl);
return true;
#undef END_OF_ARGLIST
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
;
else if (DECL_INITIAL (decl))
- diag (N_("%Jprevious definition of '%D' was here"), decl, decl);
+ diag (N_("%Jprevious definition of %qD was here"), decl, decl);
else if (C_DECL_IMPLICIT (decl))
- diag (N_("%Jprevious implicit declaration of '%D' was here"), decl, decl);
+ diag (N_("%Jprevious implicit declaration of %qD was here"), decl, decl);
else
- diag (N_("%Jprevious declaration of '%D' was here"), decl, decl);
+ diag (N_("%Jprevious declaration of %qD was here"), decl, decl);
}
/* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL.
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. */
&& DECL_BUILT_IN (olddecl)
&& !C_DECL_DECLARED_BUILTIN (olddecl)))
{
- error ("%J'%D' redeclared as different kind of symbol",
+ error ("%J%qD redeclared as different kind of symbol",
newdecl, newdecl);
locate_old_decl (olddecl, error);
}
else if (TREE_PUBLIC (newdecl))
- warning ("%Jbuilt-in function '%D' declared as non-function",
+ warning ("%Jbuilt-in function %qD declared as non-function",
newdecl, newdecl);
else if (warn_shadow)
- warning ("%Jdeclaration of '%D' shadows a built-in function",
+ warning ("%Jdeclaration of %qD shadows a built-in function",
newdecl, newdecl);
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
/* 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 ("%Jconflicting types for built-in function '%D'",
+ warning ("%Jconflicting types for built-in function %qD",
newdecl, newdecl);
return false;
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl)
&& TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
- && C_FUNCTION_IMPLICIT_INT (newdecl))
+ && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
{
- pedwarn ("%Jconflicting types for '%D'", newdecl, newdecl);
+ pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
/* Make sure we keep void as the return type. */
TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
pedwarned = true;
}
+ /* Permit void foo (...) to match an earlier call to foo (...) with
+ no declared type (thus, implicitly int). */
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL
+ && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
+ && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
+ {
+ pedwarn ("%Jconflicting types for %qD", newdecl, 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 '%D'", newdecl, newdecl);
+ error ("%J conflicting type qualifiers for %qD", newdecl, newdecl);
else
- error ("%Jconflicting types for '%D'", newdecl, newdecl);
+ error ("%Jconflicting types for %qD", newdecl, 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 '%D'", newdecl, newdecl);
+ error ("%Jredefinition of typedef %qD", newdecl, newdecl);
locate_old_decl (olddecl, error);
return false;
}
&& !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
{
if (warn_shadow)
- warning ("%Jdeclaration of '%D' shadows a built-in function",
+ warning ("%Jdeclaration of %qD shadows a built-in function",
newdecl, newdecl);
/* Discard the old built-in function. */
return false;
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 '%D'", 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. */
&& !(DECL_EXTERNAL (olddecl)
&& DECL_DECLARED_INLINE_P (olddecl)))
{
- error ("%Jstatic declaration of '%D' follows "
+ error ("%Jstatic declaration of %qD follows "
"non-static declaration", newdecl, newdecl);
locate_old_decl (olddecl, error);
}
{
if (DECL_CONTEXT (olddecl))
{
- error ("%Jnon-static declaration of '%D' follows "
+ error ("%Jnon-static declaration of %qD follows "
"static declaration", newdecl, newdecl);
locate_old_decl (olddecl, error);
return false;
}
else if (warn_traditional)
{
- warning ("%Jnon-static declaration of '%D' follows "
+ warning ("%Jnon-static declaration of %qD follows "
"static declaration", newdecl, newdecl);
warned = true;
}
if (DECL_THREAD_LOCAL (newdecl) != DECL_THREAD_LOCAL (olddecl))
{
if (DECL_THREAD_LOCAL (newdecl))
- error ("%Jthread-local declaration of '%D' follows "
+ error ("%Jthread-local declaration of %qD follows "
"non-thread-local declaration", newdecl, newdecl);
else
- error ("%Jnon-thread-local declaration of '%D' follows "
+ error ("%Jnon-thread-local declaration of %qD follows "
"thread-local declaration", newdecl, newdecl);
locate_old_decl (olddecl, error);
/* Multiple initialized definitions are not allowed (6.9p3,5). */
if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
{
- error ("%Jredefinition of '%D'", newdecl, newdecl);
+ error ("%Jredefinition of %qD", newdecl, newdecl);
locate_old_decl (olddecl, error);
return false;
}
}
else if (warn_traditional)
{
- warning ("%Jnon-static declaration of '%D' follows "
+ warning ("%Jnon-static declaration of %qD follows "
"static declaration", newdecl, newdecl);
warned = true;
}
else
{
if (TREE_PUBLIC (newdecl))
- error ("%Jnon-static declaration of '%D' follows "
+ error ("%Jnon-static declaration of %qD follows "
"static declaration", newdecl, newdecl);
else
- error ("%Jstatic declaration of '%D' follows "
+ error ("%Jstatic declaration of %qD follows "
"non-static declaration", newdecl, newdecl);
locate_old_decl (olddecl, error);
}
else if (DECL_EXTERNAL (olddecl))
{
- error ("%Jdeclaration of '%D' with no linkage follows "
+ error ("%Jdeclaration of %qD with no linkage follows "
"extern declaration", newdecl, newdecl);
locate_old_decl (olddecl, error);
}
else
{
- error ("%Jredeclaration of '%D' with no linkage",
+ error ("%Jredeclaration of %qD with no linkage",
newdecl, newdecl);
locate_old_decl (olddecl, error);
}
if (DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY_SPECIFIED (olddecl)
&& DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
{
- warning ("%Jredeclaration of '%D' with different visibility "
+ warning ("%Jredeclaration of %qD with different visibility "
"(old visibility preserved)", newdecl, newdecl);
warned = true;
}
if (DECL_DECLARED_INLINE_P (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
{
- warning ("%Jinline declaration of '%D' follows "
+ warning ("%Jinline declaration of %qD follows "
"declaration with attribute noinline", newdecl, newdecl);
warned = true;
}
else if (DECL_DECLARED_INLINE_P (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
{
- warning ("%Jdeclaration of '%D' with attribute noinline follows "
+ warning ("%Jdeclaration of %qD with attribute noinline follows "
"inline declaration ", newdecl, newdecl);
warned = true;
}
{
if (TREE_USED (olddecl))
{
- warning ("%J'%D' declared inline after being called",
+ warning ("%J%qD declared inline after being called",
olddecl, olddecl);
warned = true;
}
else if (DECL_INITIAL (olddecl))
{
- warning ("%J'%D' declared inline after its definition",
+ warning ("%J%qD declared inline after its definition",
olddecl, olddecl);
warned = true;
}
if (TREE_CODE (newdecl) == PARM_DECL
&& (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
{
- error ("%Jredefinition of parameter '%D'", newdecl, newdecl);
+ error ("%Jredefinition of parameter %qD", newdecl, newdecl);
locate_old_decl (olddecl, error);
return false;
}
&& !(TREE_CODE (newdecl) == PARM_DECL
&& TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)))
{
- warning ("%Jredundant redeclaration of '%D'", newdecl, newdecl);
+ warning ("%Jredundant redeclaration of %qD", newdecl, newdecl);
warned = true;
}
if (warned || pedwarned)
locate_old_decl (olddecl, pedwarned ? pedwarn : warning);
- return true;
+ return retval;
}
/* Subroutine of duplicate_decls. NEWDECL has been found to be
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;
}
}
tree old_decl = b->decl;
if (TREE_CODE (old_decl) == PARM_DECL)
- warning ("%Jdeclaration of '%D' shadows a parameter",
+ warning ("%Jdeclaration of %qD shadows a parameter",
new_decl, new_decl);
else if (DECL_FILE_SCOPE_P (old_decl))
- warning ("%Jdeclaration of '%D' shadows a global declaration",
+ warning ("%Jdeclaration of %qD shadows a global declaration",
new_decl, new_decl);
else if (TREE_CODE (old_decl) == FUNCTION_DECL
&& DECL_BUILT_IN (old_decl))
- warning ("%Jdeclaration of '%D' shadows a built-in function",
+ warning ("%Jdeclaration of %qD shadows a built-in function",
new_decl, new_decl);
else
- warning ("%Jdeclaration of '%D' shadows a previous local",
+ warning ("%Jdeclaration of %qD shadows a previous local",
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
if (warn_nested_externs
&& scope != file_scope
&& !DECL_IN_SYSTEM_HEADER (x))
- warning ("nested extern declaration of '%D'", x);
+ warning ("nested extern declaration of %qD", x);
while (b && !B_IN_EXTERNAL_SCOPE (b))
{
just need to fall through to make the declaration in
this scope. */
nested = true;
+ x = visdecl;
}
else
{
}
}
}
- /* Similarly, a declaration of a function with static linkage at
- block scope must be checked against any existing declaration
- of that function at file scope. */
- else if (TREE_CODE (x) == FUNCTION_DECL && scope != file_scope
- && !TREE_PUBLIC (x) && !DECL_INITIAL (x))
- {
- if (warn_nested_externs && !DECL_IN_SYSTEM_HEADER (x))
- warning ("nested static declaration of '%D'", x);
-
- while (b && !B_IN_FILE_SCOPE (b))
- b = b->shadowed;
-
- if (b && same_translation_unit_p (x, b->decl)
- && duplicate_decls (x, b->decl))
- {
- bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
- return b->decl;
- }
- else
- {
- bind (name, x, file_scope, /*invisible=*/true, /*nested=*/false);
- nested = true;
- }
- }
warn_if_shadowing (x);
{
tree name;
bool nested = false;
-
- gcc_assert (TREE_CODE (x) == VAR_DECL);
+ gcc_assert (TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == CONST_DECL);
name = DECL_NAME (x);
- gcc_assert (!I_SYMBOL_BINDING (name));
+ gcc_assert (TREE_CODE (x) == CONST_DECL || !I_SYMBOL_BINDING (name));
if (TREE_PUBLIC (x))
{
default: gcc_unreachable ();
}
- diag (N_("implicit declaration of function '%E'"), id);
+ diag (N_("implicit declaration of function %qE"), id);
if (olddecl)
locate_old_decl (olddecl, diag);
}
{
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. */
if (current_function_decl == 0)
{
- error ("'%E' undeclared here (not in a function)", id);
+ error ("%qE undeclared here (not in a function)", id);
scope = current_scope;
}
else
{
- error ("'%E' undeclared (first use in this function)", id);
+ 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.)");
if (current_function_decl == 0)
{
- error ("label %s referenced outside of any function",
+ error ("label %qs referenced outside of any function",
IDENTIFIER_POINTER (name));
return 0;
}
at this scope */
if (b && B_IN_CURRENT_SCOPE (b))
{
- error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
+ error ("duplicate label declaration %qs", IDENTIFIER_POINTER (name));
locate_old_decl (b->decl, error);
/* Just use the previous declaration. */
|| (DECL_CONTEXT (label) != current_function_decl
&& C_DECLARED_LABEL_FLAG (label))))
{
- error ("%Hduplicate label `%D'", &location, label);
+ error ("%Hduplicate label %qD", &location, label);
locate_old_decl (label, error);
return 0;
}
if (warn_traditional && !in_system_header && lookup_name (name))
warning ("%Htraditional C lacks a separate namespace for labels, "
- "identifier `%s' conflicts", &location,
+ "identifier %qs conflicts", &location,
IDENTIFIER_POINTER (name));
/* Mark label as having been defined. */
pending_xref_error (void)
{
if (pending_invalid_xref != 0)
- error ("%H`%s' defined as wrong kind of tag",
+ error ("%H%qs defined as wrong kind of tag",
&pending_invalid_xref_location,
IDENTIFIER_POINTER (pending_invalid_xref));
pending_invalid_xref = 0;
{
bool found_tag = false;
- 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;
}
}
+ else if (!declspecs->tag_defined_p
+ && declspecs->storage_class != csc_none)
+ {
+ if (warned != 1)
+ pedwarn ("empty declaration with storage class specifier "
+ "does not redeclare tag");
+ warned = 1;
+ pending_xref_error ();
+ }
+ else if (!declspecs->tag_defined_p
+ && (declspecs->const_p
+ || declspecs->volatile_p
+ || declspecs->restrict_p))
+ {
+ if (warned != 1)
+ pedwarn ("empty declaration with type qualifier "
+ "does not redeclare tag");
+ warned = 1;
+ pending_xref_error ();
+ }
else
{
+ pending_invalid_xref = 0;
t = lookup_tag (code, name, 1);
if (t == 0)
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))))
+ pending_invalid_xref = 0;
+
+ if (declspecs->inline_p)
+ {
+ error ("%<inline%> in empty declaration");
+ warned = 1;
+ }
+
+ if (current_scope == file_scope && declspecs->storage_class == csc_auto)
{
- error ("long, short, signed, unsigned or complex used invalidly "
- "in empty declaration");
+ error ("%<auto%> in file-scope empty declaration");
warned = 1;
}
- if (!warned && !in_system_header && declspecs->specbits)
+ if (current_scope == file_scope && declspecs->storage_class == csc_register)
{
- warning ("useless keyword or type name in empty declaration");
+ error ("%<register%> in file-scope empty declaration");
+ warned = 1;
+ }
+
+ if (!warned && !in_system_header && declspecs->storage_class != csc_none)
+ {
+ warning ("useless storage class specifier in empty declaration");
+ warned = 2;
+ }
+
+ if (!warned && !in_system_header && declspecs->thread_p)
+ {
+ warning ("useless %<__thread%> in empty declaration");
+ warned = 2;
+ }
+
+ if (!warned && !in_system_header && (declspecs->const_p
+ || declspecs->volatile_p
+ || declspecs->restrict_p))
+ {
+ 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)
{
if (static_p || quals != NULL)
- pedwarn ("ISO C90 does not support `static' or type qualifiers in parameter array declarators");
+ pedwarn ("ISO C90 does not support %<static%> or type "
+ "qualifiers in parameter array declarators");
if (vla_unspec_p)
- pedwarn ("ISO C90 does not support `[*]' array declarators");
+ pedwarn ("ISO C90 does not support %<[*]%> array declarators");
}
if (vla_unspec_p)
- warning ("GCC does not yet properly implement `[*]' array declarators");
+ warning ("GCC does not yet properly implement %<[*]%> array declarators");
return declarator;
}
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;
decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized, NULL);
+ if (!decl)
+ return 0;
deprecated_state = DEPRECATED_NORMAL;
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
&& MAIN_NAME_P (DECL_NAME (decl)))
- warning ("%J'%D' is usually a function", decl, decl);
+ warning ("%J%qD is usually a function", decl, decl);
if (initialized)
/* Is it valid for this decl to have an initializer at all?
switch (TREE_CODE (decl))
{
case TYPE_DECL:
- error ("typedef '%D' is initialized (use __typeof__ instead)", decl);
+ error ("typedef %qD is initialized (use __typeof__ instead)", decl);
initialized = 0;
break;
case FUNCTION_DECL:
- error ("function '%D' is initialized like a variable", decl);
+ error ("function %qD is initialized like a variable", decl);
initialized = 0;
break;
case PARM_DECL:
/* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE. */
- error ("parameter '%D' is initialized", decl);
+ error ("parameter %qD is initialized", decl);
initialized = 0;
break;
}
else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
{
- error ("variable '%D' has initializer but incomplete type", decl);
+ 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 '%D' have incomplete 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
+ 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;
}
}
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
- warning ("%Jinline function '%D' given attribute noinline", decl, decl);
+ warning ("%Jinline function %qD given attribute noinline", decl, decl);
/* Add this decl to the current scope.
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);
type = TREE_TYPE (decl);
if (failure == 1)
- error ("%Jinitializer fails to determine size of '%D'", decl, decl);
+ error ("%Jinitializer fails to determine size of %qD", decl, decl);
else if (failure == 2)
{
if (do_default)
- error ("%Jarray size missing in '%D'", decl, decl);
+ error ("%Jarray size missing in %qD", decl, decl);
/* If a `static' var's size isn't known,
make it extern as well as static, so it does not get
allocated.
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;
}
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)
- error ("%Jzero or negative size array '%D'", decl, decl);
+ error ("%Jzero or negative size array %qD", decl, decl);
layout_decl (decl, 0);
}
is an error. */
: !DECL_EXTERNAL (decl)))
{
- error ("%Jstorage size of '%D' isn't known", decl, decl);
+ error ("%Jstorage size of %qD isn%'t known", decl, 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 '%D' isn't constant", decl, decl);
+ error ("%Jstorage size of %qD isn%'t constant", decl, decl);
}
if (TREE_USED (type))
if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
{
if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
- {
- tree builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
- set_user_assembler_name (builtin, asmspec);
- if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
- init_block_move_fn (asmspec);
- else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
- init_block_clear_fn (asmspec);
- }
+ set_builtin_user_assembler_name (decl, asmspec);
set_user_assembler_name (decl, asmspec);
}
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))
warning ("%Jignoring asm-specifier for non-static local "
- "variable '%D'", decl, decl);
+ "variable %qD", decl, decl);
else if (C_DECL_REGISTER (decl))
change_decl_assembler_name (decl, get_identifier (asmspec));
else
/* 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);
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);
}
field widths. */
if (TREE_CODE (*width) != INTEGER_CST)
{
- error ("bit-field `%s' width not an integer constant", name);
+ error ("bit-field %qs width not an integer constant", name);
*width = integer_one_node;
}
else
constant_expression_warning (*width);
if (tree_int_cst_sgn (*width) < 0)
{
- error ("negative width in bit-field `%s'", name);
+ error ("negative width in bit-field %qs", name);
*width = integer_one_node;
}
else if (integer_zerop (*width) && orig_name)
{
- error ("zero width for bit-field `%s'", name);
+ error ("zero width for bit-field %qs", name);
*width = integer_one_node;
}
}
&& TREE_CODE (*type) != BOOLEAN_TYPE
&& TREE_CODE (*type) != ENUMERAL_TYPE)
{
- error ("bit-field `%s' has invalid type", name);
+ error ("bit-field %qs has invalid type", name);
*type = unsigned_type_node;
}
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
&& type_mv != boolean_type_node)
- pedwarn ("type of bit-field `%s' is a GCC extension", name);
+ pedwarn ("type of bit-field %qs is a GCC extension", name);
if (type_mv == boolean_type_node)
max_width = CHAR_TYPE_SIZE;
if (0 < compare_tree_int (*width, max_width))
{
- error ("width of `%s' exceeds its type", name);
+ error ("width of %qs exceeds its type", name);
w = max_width;
*width = build_int_cst (NULL_TREE, w);
}
if (!lt
|| w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
|| w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
- warning ("`%s' is narrower than values of its type", name);
+ warning ("%qs is narrower than values of its type", name);
}
}
\f
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 constp;
int restrictp;
int volatilep;
int type_quals = TYPE_UNQUALIFIED;
- int inlinep;
- 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. */
- && ! (specbits & (1 << (int) RID_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 `%s'",
- 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. */
+ /* Diagnose defaulting to "int". */
- /* Long double is a special combination. */
-
- 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;
- }
-
- /* 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 `%s'", 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 `%s'", 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 `%s'", 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 `%s'", name);
- else if (TREE_CODE (type) != INTEGER_TYPE)
- error ("long, short, signed or unsigned invalid for `%s'", name);
- else
- {
- ok = 1;
- if (!declspecs->explicit_int_p && !defaulted_int
- && !declspecs->explicit_char_p)
- {
- error ("long, short, signed or unsigned used invalidly for `%s'",
- 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;
- }
+ /* 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);
}
- if ((specbits & (1 << (int) RID_COMPLEX))
- && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
- {
- error ("complex invalid for `%s'", 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);
- }
- }
-
- /* Check the type and width of a bit-field. */
- if (bitfield)
- check_bitfield_type_and_width (&type, width, orig_name);
+ /* 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);
/* Figure out the type qualifiers for the declaration. There are
two ways a declaration can become qualified. One is something
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);
- inlinep = !! (specbits & (1 << (int) RID_INLINE));
+ 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)
- pedwarn ("duplicate `const'");
+ pedwarn ("duplicate %<const%>");
if (restrictp > 1)
- pedwarn ("duplicate `restrict'");
+ pedwarn ("duplicate %<restrict%>");
if (volatilep > 1)
- pedwarn ("duplicate `volatile'");
+ 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)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
- /* Warn if two storage classes are given. Default to `auto'. */
-
- {
- int nclasses = 0;
-
- if (specbits & 1 << (int) RID_AUTO) nclasses++;
- if (specbits & 1 << (int) RID_STATIC) nclasses++;
- if (specbits & 1 << (int) RID_EXTERN) nclasses++;
- if (specbits & 1 << (int) RID_REGISTER) nclasses++;
- if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
-
- /* "static __thread" and "extern __thread" are allowed. */
- if ((specbits & (1 << (int) RID_THREAD
- | 1 << (int) RID_STATIC
- | 1 << (int) RID_EXTERN)) == (1 << (int) RID_THREAD))
- nclasses++;
-
- /* Warn about storage classes that are invalid for certain
- kinds of declarations (parameters, typenames, etc.). */
-
- if (nclasses > 1)
- error ("multiple storage classes in declaration of `%s'", name);
- else if (funcdef_flag
- && (specbits
- & ((1 << (int) RID_REGISTER)
- | (1 << (int) RID_AUTO)
- | (1 << (int) RID_TYPEDEF)
- | (1 << (int) RID_THREAD))))
- {
- if (specbits & 1 << (int) RID_AUTO
- && (pedantic || current_scope == file_scope))
- pedwarn ("function definition declared `auto'");
- if (specbits & 1 << (int) RID_REGISTER)
- error ("function definition declared `register'");
- if (specbits & 1 << (int) RID_TYPEDEF)
- error ("function definition declared `typedef'");
- if (specbits & 1 << (int) RID_THREAD)
- error ("function definition declared `__thread'");
- specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
- | (1 << (int) RID_AUTO) | (1 << (int) RID_THREAD));
- }
- else if (decl_context != NORMAL && nclasses > 0)
- {
- if (decl_context == PARM && specbits & 1 << (int) RID_REGISTER)
- ;
- else
- {
- switch (decl_context)
- {
- case FIELD:
- error ("storage class specified for structure field `%s'",
- name);
- break;
- case PARM:
- error ("storage class specified for parameter `%s'", name);
- break;
- default:
- error ("storage class specified for typename");
- break;
- }
- specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
- | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
- | (1 << (int) RID_EXTERN) | (1 << (int) RID_THREAD));
- }
- }
- else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
- {
- /* `extern' with initialization is invalid if not at file scope. */
- if (current_scope == file_scope)
- warning ("`%s' initialized and declared `extern'", name);
- else
- error ("`%s' has both `extern' and initializer", name);
- }
- else if (current_scope == file_scope)
- {
- if (specbits & 1 << (int) RID_AUTO)
- error ("file-scope declaration of `%s' specifies `auto'", name);
- }
- else
- {
- if (specbits & 1 << (int) RID_EXTERN && funcdef_flag)
- error ("nested function `%s' declared `extern'", name);
- else if ((specbits & (1 << (int) RID_THREAD
- | 1 << (int) RID_EXTERN
- | 1 << (int) RID_STATIC))
- == (1 << (int) RID_THREAD))
- {
- error ("function-scope `%s' implicitly auto and declared `__thread'",
- name);
- specbits &= ~(1 << (int) RID_THREAD);
- }
- }
- }
+ /* Warn about storage classes that are invalid for certain
+ kinds of declarations (parameters, typenames, etc.). */
+
+ if (funcdef_flag
+ && (threadp
+ || storage_class == csc_auto
+ || storage_class == csc_register
+ || storage_class == csc_typedef))
+ {
+ if (storage_class == csc_auto
+ && (pedantic || current_scope == file_scope))
+ pedwarn ("function definition declared %<auto%>");
+ if (storage_class == csc_register)
+ error ("function definition declared %<register%>");
+ if (storage_class == csc_typedef)
+ error ("function definition declared %<typedef%>");
+ if (threadp)
+ error ("function definition declared %<__thread%>");
+ threadp = false;
+ if (storage_class == csc_auto
+ || storage_class == csc_register
+ || storage_class == csc_typedef)
+ storage_class = csc_none;
+ }
+ else if (decl_context != NORMAL && (storage_class != csc_none || threadp))
+ {
+ if (decl_context == PARM && storage_class == csc_register)
+ ;
+ else
+ {
+ switch (decl_context)
+ {
+ case FIELD:
+ error ("storage class specified for structure field %qs",
+ name);
+ break;
+ case PARM:
+ error ("storage class specified for parameter %qs", name);
+ break;
+ default:
+ error ("storage class specified for typename");
+ break;
+ }
+ storage_class = csc_none;
+ threadp = false;
+ }
+ }
+ else if (storage_class == csc_extern
+ && initialized
+ && !funcdef_flag)
+ {
+ /* 'extern' with initialization is invalid if not at file scope. */
+ if (current_scope == file_scope)
+ warning ("%qs initialized and declared %<extern%>", name);
+ else
+ error ("%qs has both %<extern%> and initializer", name);
+ }
+ else if (current_scope == file_scope)
+ {
+ if (storage_class == csc_auto)
+ error ("file-scope declaration of %qs specifies %<auto%>", name);
+ if (pedantic && storage_class == csc_register)
+ pedwarn ("file-scope declaration of %qs specifies %<register%>", name);
+ }
+ else
+ {
+ if (storage_class == csc_extern && funcdef_flag)
+ error ("nested function %qs declared %<extern%>", name);
+ else if (threadp && storage_class == csc_none)
+ {
+ error ("function-scope %qs implicitly auto and declared "
+ "%<__thread%>",
+ name);
+ threadp = false;
+ }
+ }
/* Now figure out the structure of the declarator proper.
Descend through it, creating more complex types, until we reach
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;
if (VOID_TYPE_P (type))
{
- error ("declaration of `%s' as array of voids", name);
+ error ("declaration of %qs as array of voids", name);
type = error_mark_node;
}
if (TREE_CODE (type) == FUNCTION_TYPE)
{
- error ("declaration of `%s' as array of functions", name);
+ error ("declaration of %qs as array of functions", name);
type = error_mark_node;
}
lvalue. */
STRIP_TYPE_NOPS (size);
- if (! INTEGRAL_TYPE_P (TREE_TYPE (size)))
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
{
- error ("size of array `%s' has non-integer type", name);
+ error ("size of array %qs has non-integer type", name);
size = integer_one_node;
}
if (pedantic && integer_zerop (size))
- pedwarn ("ISO C forbids zero-size array `%s'", name);
+ pedwarn ("ISO C forbids zero-size array %qs", name);
if (TREE_CODE (size) == INTEGER_CST)
{
constant_expression_warning (size);
if (tree_int_cst_sgn (size) < 0)
{
- error ("size of array `%s' is negative", name);
+ error ("size of array %qs is negative", name);
size = integer_one_node;
}
}
if (!flag_isoc99 && pedantic)
{
if (TREE_CONSTANT (size))
- pedwarn ("ISO C90 forbids array `%s' whose size can't be evaluated",
+ pedwarn ("ISO C90 forbids array %qs whose size "
+ "can%'t be evaluated",
name);
else
- pedwarn ("ISO C90 forbids variable-size array `%s'",
+ pedwarn ("ISO C90 forbids variable-size array %qs",
name);
}
}
}
else
{
+ /* Arrange for the SAVE_EXPR on the inside of the
+ MINUS_EXPR, which allows the -1 to get folded
+ with the +1 that happens when building TYPE_SIZE. */
+ if (size_varies)
+ size = variable_size (size);
+
/* Compute the maximum valid index, that is, size
- 1. Do the calculation in index_type, so that
if it is a variable the computations will be
complication. */
if (TREE_OVERFLOW (itype))
{
- error ("size of array `%s' is too large", name);
+ error ("size of array %qs is too large", name);
type = error_mark_node;
continue;
}
- if (size_varies)
- itype = variable_size (itype);
itype = build_index_type (itype);
}
}
zero. */
if (size && integer_zerop (size))
{
- layout_type (type);
TYPE_SIZE (type) = bitsize_zero_node;
TYPE_SIZE_UNIT (type) = size_zero_node;
}
- else if (declarator->kind == cdk_pointer)
- /* We can never complete an array type which is the
- target of a pointer, so go ahead and lay it out. */
- 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;
/* Warn about some types functions can't return. */
if (TREE_CODE (type) == FUNCTION_TYPE)
{
- error ("`%s' declared as function returning a function", name);
+ error ("%qs declared as function returning a function", name);
type = integer_type_node;
}
if (TREE_CODE (type) == ARRAY_TYPE)
{
- error ("`%s' declared as function returning an array", name);
+ error ("%qs declared as function returning an array", name);
type = integer_type_node;
}
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;
/* Now TYPE has the actual type. */
+ /* Check the type and width of a bit-field. */
+ if (bitfield)
+ check_bitfield_type_and_width (&type, width, orig_name);
+
/* Did array size calculations overflow? */
if (TREE_CODE (type) == ARRAY_TYPE
&& COMPLETE_TYPE_P (type)
&& TREE_OVERFLOW (TYPE_SIZE (type)))
{
- error ("size of array `%s' is too large", name);
+ error ("size of array %qs is too large", name);
/* If we proceed with the array type as it is, we'll eventually
crash in tree_low_cst(). */
type = error_mark_node;
/* If this is declaring a typedef name, return a TYPE_DECL. */
- if (specbits & (1 << (int) RID_TYPEDEF))
+ 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)
- && ((specbits & (1 << (int) RID_EXTERN))
+ && !((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
+ && (storage_class == csc_extern
|| (current_scope == file_scope
- && !(specbits
- & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
+ && !(storage_class == csc_static
+ || storage_class == csc_register)))))
{
- error ("variable or field `%s' declared void", name);
+ error ("variable or field %qs declared void", name);
type = integer_type_node;
}
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;
-
- /* We don't yet implement attributes in this context. */
- if (array_ptr_quals->attrs != NULL_TREE)
- warning ("attributes in parameter array declarator ignored");
+ type_quals = array_ptr_quals;
- /* 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))));
+ /* We don't yet implement attributes in this context. */
+ if (array_ptr_attrs != NULL_TREE)
+ warning ("attributes in parameter array declarator ignored");
- 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)
{
- error ("field `%s' declared as a function", name);
+ error ("field %qs declared as a function", name);
type = build_pointer_type (type);
}
else if (TREE_CODE (type) != ERROR_MARK
&& !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type))
{
- error ("field `%s' has incomplete type", name);
+ error ("field %qs has incomplete type", name);
type = error_mark_node;
}
/* Move type qualifiers down to element of an array. */
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- if (specbits & (1 << (int) RID_REGISTER)
- || specbits & (1 << (int) RID_THREAD))
- error ("invalid storage class for function `%s'", name);
+ if (storage_class == csc_register || threadp)
+ {
+ error ("invalid storage class for function %qs", name);
+ }
else if (current_scope != file_scope)
{
/* Function declaration not at file scope. Storage
6.7.1p5, and `extern' makes no difference. However,
GCC allows 'auto', perhaps with 'inline', to support
nested functions. */
- if (specbits & (1 << (int) RID_AUTO))
+ if (storage_class == csc_auto)
{
if (pedantic)
- pedwarn ("invalid storage class for function `%s'", name);
+ pedwarn ("invalid storage class for function %qs", name);
+ }
+ else if (storage_class == csc_static)
+ {
+ error ("invalid storage class for function %qs", name);
+ if (funcdef_flag)
+ storage_class = declspecs->storage_class = csc_none;
+ else
+ return 0;
}
- if (specbits & (1 << (int) RID_STATIC))
- error ("invalid storage class for function `%s'", name);
}
decl = build_decl (FUNCTION_DECL, declarator->u.id, 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
that the function does not return. */
if ((type_quals & TYPE_QUAL_VOLATILE)
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
- warning ("`noreturn' function returns non-void value");
+ warning ("%<noreturn%> function returns non-void value");
/* Every function declaration is an external reference
(DECL_EXTERNAL) except for those which are not at file
scope and are explicitly declared "auto". This is
forbidden by standard C (C99 6.7.1p5) and is interpreted by
GCC to signify a forward declaration of a nested function. */
- if ((specbits & (1 << RID_AUTO)) && current_scope != file_scope)
+ if (storage_class == csc_auto && current_scope != file_scope)
DECL_EXTERNAL (decl) = 0;
else
DECL_EXTERNAL (decl) = 1;
/* Record absence of global scope for `static' or `auto'. */
TREE_PUBLIC (decl)
- = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
+ = !(storage_class == csc_static || storage_class == csc_auto);
/* For a function definition, record the argument information
block where store_parm_decls will look for it. */
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 (inlinep)
- warning ("cannot inline function `main'");
+ if (declspecs->inline_p)
+ pedwarn ("cannot inline function %<main%>");
}
- else if (inlinep)
+ else if (declspecs->inline_p)
{
/* Record that the function is declared `inline'. */
DECL_DECLARED_INLINE_P (decl) = 1;
if (initialized)
{
DECL_INLINE (decl) = 1;
- if (specbits & (1 << (int) RID_EXTERN))
+ if (storage_class == csc_extern)
current_extern_inline = 1;
}
}
{
/* It's a variable. */
/* An uninitialized decl with `extern' is a reference. */
- int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
+ 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)
&& global_decl != visible_decl
&& TREE_CODE (global_decl) == VAR_DECL
&& !TREE_PUBLIC (global_decl))
- error ("variable previously declared 'static' redeclared "
- "'extern'");
+ error ("variable previously declared %<static%> redeclared "
+ "%<extern%>");
}
decl = build_decl (VAR_DECL, declarator->u.id, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
- if (inlinep)
- pedwarn ("%Jvariable '%D' declared `inline'", decl, decl);
+ if (declspecs->inline_p)
+ pedwarn ("%Jvariable %qD declared %<inline%>", decl, decl);
/* At file scope, an initialized extern declaration may follow
a static declaration. In that case, DECL_EXTERNAL will be
reset later in start_decl. */
- DECL_EXTERNAL (decl) = !!(specbits & (1 << (int) RID_EXTERN));
+ DECL_EXTERNAL (decl) = (storage_class == csc_extern);
/* At file scope, the presence of a `static' or `register' storage
class specifier, or the absence of all storage class specifiers
the absence of both `static' and `register' makes it public. */
if (current_scope == file_scope)
{
- TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
- | (1 << (int) RID_REGISTER)));
+ TREE_PUBLIC (decl) = !(storage_class == csc_static
+ || storage_class == csc_register);
TREE_STATIC (decl) = !extern_ref;
}
/* Not at file scope, only `static' makes a static definition. */
else
{
- TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
+ TREE_STATIC (decl) = (storage_class == csc_static);
TREE_PUBLIC (decl) = extern_ref;
}
- if (specbits & 1 << (int) RID_THREAD)
+ if (threadp)
{
if (targetm.have_tls)
DECL_THREAD_LOCAL (decl) = 1;
/* Record `register' declaration for warnings on &
and in case doing stupid register allocation. */
- if (specbits & (1 << (int) RID_REGISTER))
+ if (storage_class == csc_register)
{
C_DECL_REGISTER (decl) = 1;
DECL_REGISTER (decl) = 1;
if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag
&& !in_system_header)
- warning ("function declaration isn't a prototype");
+ warning ("function declaration isn%'t a prototype");
if (arg_types == error_mark_node)
return 0; /* don't set TYPE_ARG_TYPES in this case */
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;
if (funcdef_flag)
{
if (DECL_NAME (parm))
- error ("%Jparameter %u ('%D') has incomplete type",
+ error ("%Jparameter %u (%qD) has incomplete type",
parm, parmno, parm);
else
error ("%Jparameter %u has incomplete type",
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 ('%D') 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);
}
}
if (TREE_THIS_VOLATILE (b->decl)
|| TREE_READONLY (b->decl)
|| C_DECL_REGISTER (b->decl))
- error ("'void' as only parameter may not be qualified");
+ error ("%<void%> as only parameter may not be qualified");
/* There cannot be an ellipsis. */
if (ellipsis)
- error ("'void' must be the only parameter");
+ error ("%<void%> must be the only parameter");
arg_info->types = void_list_node;
return arg_info;
/* Check for forward decls that never got their actual decl. */
if (TREE_ASM_WRITTEN (decl))
- error ("%Jparameter '%D' has just a forward declaration",
+ error ("%Jparameter %qD has just a forward declaration",
decl, decl);
/* Check for (..., void, ...) and issue an error. */
else if (VOID_TYPE_P (type) && !DECL_NAME (decl))
{
if (!gave_void_only_once_err)
{
- error ("'void' must be the only parameter");
+ error ("%<void%> must be the only parameter");
gave_void_only_once_err = true;
}
}
{
if (b->id)
/* The %s will be one of 'struct', 'union', or 'enum'. */
- warning ("'%s %E' declared inside parameter list",
+ warning ("%<%s %E%> declared inside parameter list",
keyword, b->id);
else
/* The %s will be one of 'struct', 'union', or 'enum'. */
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");
case CONST_DECL:
case TYPE_DECL:
+ case FUNCTION_DECL:
/* CONST_DECLs appear here when we have an embedded enum,
and TYPE_DECLs appear here when we have an embedded struct
or union. No warnings for this - we already warned about the
- type itself. */
+ type itself. FUNCTION_DECLs appear when there is an implicit
+ function declaration in the parameter list. */
+
TREE_CHAIN (decl) = others;
others = decl;
/* fall through */
/* Other things that might be encountered. */
case LABEL_DECL:
- case FUNCTION_DECL:
case VAR_DECL:
default:
gcc_unreachable ();
}
\f
/* Get the struct, enum or union (CODE says which) with tag NAME.
- Define the tag as a forward-reference if it is not defined. */
+ Define the tag as a forward-reference if it is not defined.
+ Return a c_typespec structure for the type specifier. */
-tree
-xref_tag (enum tree_code code, tree name)
+struct c_typespec
+parser_xref_tag (enum tree_code code, tree name)
{
+ struct c_typespec ret;
/* If a cross reference is requested, look up the type
already defined for this tag and return it. */
this would not work properly if we return the reference found.
(For example, with "struct foo" in an outer scope, "union foo;"
must shadow that tag with a new one of union type.) */
+ ret.kind = (ref ? ctsk_tagref : ctsk_tagfirstref);
if (ref && TREE_CODE (ref) == code)
- return ref;
+ {
+ ret.spec = ref;
+ return ret;
+ }
/* If no such tag is yet defined, create a forward-reference node
and record it as the "definition".
pushtag (name, ref);
- return ref;
+ ret.spec = ref;
+ return ret;
+}
+
+/* Get the struct, enum or union (CODE says which) with tag NAME.
+ Define the tag as a forward-reference if it is not defined.
+ Return a tree for the type. */
+
+tree
+xref_tag (enum tree_code code, tree name)
+{
+ return parser_xref_tag (code, name).spec;
}
\f
/* Make sure that the tag NAME is defined *in the current scope*
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));
+ error ("redefinition of %<union %s%>", IDENTIFIER_POINTER (name));
else
- error ("redefinition of `struct %s'", IDENTIFIER_POINTER (name));
+ 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,
for (y = fieldlist; y != x; y = TREE_CHAIN (y))
if (DECL_NAME (y) == DECL_NAME (x))
{
- error ("%Jduplicate member '%D'", x, x);
+ error ("%Jduplicate member %qD", x, x);
DECL_NAME (x) = NULL_TREE;
}
}
slot = htab_find_slot (htab, y, INSERT);
if (*slot)
{
- error ("%Jduplicate member '%D'", x, x);
+ error ("%Jduplicate member %qD", x, x);
DECL_NAME (x) = NULL_TREE;
}
*slot = y;
break;
if (x == 0)
- pedwarn ("%s has no %s",
- TREE_CODE (t) == UNION_TYPE ? _("union") : _("struct"),
- fieldlist ? _("named members") : _("members"));
+ {
+ if (TREE_CODE (t) == UNION_TYPE)
+ {
+ if (fieldlist)
+ pedwarn ("union has no named members");
+ else
+ pedwarn ("union has no members");
+ }
+ else
+ {
+ if (fieldlist)
+ pedwarn ("struct has no named members");
+ else
+ pedwarn ("struct has no members");
+ }
+ }
}
/* Install struct as DECL_CONTEXT of each field decl.
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 `%s'",
- 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);
}
}
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel);
+ /* If we're inside a function proper, i.e. not file-scope and not still
+ parsing parameters, then arrange for the size of a variable sized type
+ to be bound now. */
+ if (cur_stmt_list && variably_modified_type_p (t, NULL))
+ add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t)));
+
return t;
}
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)
{
/* This enum is a named one that has been declared already. */
- error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name));
+ error ("redeclaration of %<enum %s%>", IDENTIFIER_POINTER (name));
/* Completely replace its old definition.
The old enumerators remain defined, however. */
value = 0;
else if (TREE_CODE (value) != INTEGER_CST)
{
- error ("enumerator value for '%E' is not an integer constant", name);
+ error ("enumerator value for %qE is not an integer constant", name);
value = 0;
}
else
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'");
+ pedwarn ("ISO C restricts enumerator values to range of %<int%>");
/* XXX This causes -pedantic to change the meaning of the program.
Remove? -zw 2004-03-15 */
value = convert (integer_type_node, value);
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
- warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
+ warning ("%Jinline function %qD given attribute noinline", decl1, decl1);
announce_function (decl1);
}
if (warn_about_return_type)
- pedwarn_c99 ("return type defaults to `int'");
+ pedwarn_c99 ("return type defaults to %<int%>");
/* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in pop_scope) with the BLOCK. */
DECL_INITIAL (decl1) = error_mark_node;
/* If this definition isn't a prototype and we had a prototype declaration
- before, copy the arg type info from that prototype.
- But not if what we had before was a builtin function. */
+ before, copy the arg type info from that prototype. */
old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
- && !DECL_BUILT_IN (old_decl)
&& comptypes (TREE_TYPE (TREE_TYPE (decl1)),
TREE_TYPE (TREE_TYPE (old_decl)))
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
if (warn_strict_prototypes
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
&& C_DECL_ISNT_PROTOTYPE (old_decl))
- warning ("function declaration isn't a prototype");
+ warning ("function declaration isn%'t a prototype");
/* 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 '%D'", decl1, decl1);
+ warning ("%Jno previous prototype for %qD", decl1, decl1);
/* 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)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
- warning ("%J'%D' was used with no prototype before its definition",
+ warning ("%J%qD was used with no prototype before its definition",
decl1, 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 ("%Jno previous declaration for '%D'", decl1, 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. */
else if (warn_missing_declarations
&& old_decl != 0 && TREE_USED (old_decl)
&& C_DECL_IMPLICIT (old_decl))
- warning ("%J`%D' was used with no declaration before its definition",
+ warning ("%J%qD was used with no declaration before its definition",
decl1, decl1);
/* This is a definition, not a reference.
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
- pedwarn ("%Jreturn type of '%D' is not `int'", decl1, decl1);
+ pedwarn ("%Jreturn type of %qD is not %<int%>", decl1, 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 '%D' should be `int'",
+ pedwarn ("%Jfirst argument of %qD should be %<int%>",
decl1, decl1);
break;
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn ("%Jsecond argument of '%D' should be 'char **'",
+ pedwarn ("%Jsecond argument of %qD should be %<char **%>",
decl1, decl1);
break;
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn ("%Jthird argument of '%D' should probably be "
- "'char **'", decl1, decl1);
+ pedwarn ("%Jthird argument of %qD should probably be "
+ "%<char **%>", decl1, decl1);
break;
}
}
argument because it's only mentioned in an appendix of the
standard. */
if (argct > 0 && (argct < 2 || argct > 3))
- pedwarn ("%J'%D' takes only zero or two arguments", decl1, decl1);
+ pedwarn ("%J%qD takes only zero or two arguments", decl1, decl1);
- if (! TREE_PUBLIC (decl1))
- pedwarn ("%J'%D' is normally a non-static function", decl1, decl1);
+ if (!TREE_PUBLIC (decl1))
+ pedwarn ("%J%qD is normally a non-static function", decl1, decl1);
}
/* Record the decl so that the function name is defined.
decl = b->decl;
/* If we got something other than a PARM_DECL it is an error. */
if (TREE_CODE (decl) != PARM_DECL)
- error ("%J'%D' declared as a non-parameter", decl, decl);
+ error ("%J%qD declared as a non-parameter", decl, decl);
/* If the declaration is already marked, we have a duplicate
name. Complain and ignore the duplicate. */
else if (DECL_WEAK (decl))
{
- error ("%Jmultiple parameters named '%D'", decl, decl);
+ error ("%Jmultiple parameters named %qD", decl, decl);
TREE_PURPOSE (parm) = 0;
continue;
}
an int. */
else if (VOID_TYPE_P (TREE_TYPE (decl)))
{
- error ("%Jparameter '%D' declared with void type", decl, decl);
+ error ("%Jparameter %qD declared with void type", decl, decl);
TREE_TYPE (decl) = integer_type_node;
DECL_ARG_TYPE (decl) = integer_type_node;
layout_decl (decl, 0);
pushdecl (decl);
if (flag_isoc99)
- pedwarn ("%Jtype of '%D' defaults to 'int'", decl, decl);
+ pedwarn ("%Jtype of %qD defaults to %<int%>", decl, decl);
else if (extra_warnings)
- warning ("%Jtype of '%D' defaults to 'int'", decl, decl);
+ warning ("%Jtype of %qD defaults to %<int%>", decl, decl);
}
TREE_PURPOSE (parm) = decl;
if (TREE_CODE (parm) != PARM_DECL)
continue;
- if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
+ if (TREE_TYPE (parm) != error_mark_node
+ && !COMPLETE_TYPE_P (TREE_TYPE (parm)))
{
- error ("%Jparameter '%D' has incomplete type", parm, parm);
+ error ("%Jparameter %qD has incomplete type", parm, parm);
TREE_TYPE (parm) = error_mark_node;
}
- if (! DECL_WEAK (parm))
+ if (!DECL_WEAK (parm))
{
- error ("%Jdeclaration for parameter '%D' but no such parameter",
+ error ("%Jdeclaration for parameter %qD but no such parameter",
parm, parm);
/* Pretend the parameter was not missing.
if (parm == 0 || type == 0
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
- error ("number of arguments doesn't match prototype");
+ error ("number of arguments doesn%'t match prototype");
error ("%Hprototype declaration",
¤t_function_prototype_locus);
break;
/* 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)))
if (pedantic)
{
- pedwarn ("promoted argument '%D' "
- "doesn't match prototype", parm);
+ pedwarn ("promoted argument %qD "
+ "doesn%'t match prototype", parm);
pedwarn ("%Hprototype declaration",
¤t_function_prototype_locus);
}
}
else
{
- error ("argument '%D' doesn't match prototype", parm);
+ error ("argument %qD doesn%'t match prototype", parm);
error ("%Hprototype declaration",
¤t_function_prototype_locus);
}
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
- phase ordering problems are resolved. */
+ to be evaluated. The only reason left to have this is
+ void foo(int n, int array[n++])
+ because we throw away the array type in favor of a pointer type, and
+ thus won't naturally see the SAVE_EXPR containing the increment. All
+ other pending sizes would be handled by gimplify_parameters. */
{
tree t;
for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (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 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 '%D' is not `int'", fndecl, fndecl);
+ pedwarn ("%Jreturn type of %qD is not %<int%>", fndecl, fndecl);
}
else
{
if (flag_isoc99)
- c_finish_return (integer_zero_node);
+ {
+ tree stmt = c_finish_return (integer_zero_node);
+ /* 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);
+ }
}
}
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)
/* If we get here, declarations have been used in a for loop without
the C99 for loop scope. This doesn't make much sense, so don't
allow it. */
- error ("'for' loop initial declaration used outside C99 mode");
+ error ("%<for%> loop initial declaration used outside C99 mode");
return;
}
/* C99 subclause 6.8.5 paragraph 3:
{
case VAR_DECL:
if (TREE_STATIC (decl))
- error ("%Jdeclaration of static variable '%D' in 'for' loop "
+ error ("%Jdeclaration of static variable %qD in %<for%> loop "
"initial declaration", decl, decl);
else if (DECL_EXTERNAL (decl))
- error ("%Jdeclaration of 'extern' variable '%D' in 'for' loop "
+ error ("%Jdeclaration of %<extern%> variable %qD in %<for%> loop "
"initial declaration", decl, decl);
break;
case RECORD_TYPE:
- error ("'struct %E' declared in 'for' loop initial declaration", id);
+ error ("%<struct %E%> declared in %<for%> loop initial declaration",
+ id);
break;
case UNION_TYPE:
- error ("'union %E' declared in 'for' loop initial declaration", id);
+ error ("%<union %E%> declared in %<for%> loop initial declaration",
+ id);
break;
case ENUMERAL_TYPE:
- error ("'enum %E' declared in 'for' loop initial declaration", id);
+ error ("%<enum %E%> declared in %<for%> loop initial declaration",
+ id);
break;
default:
- error ("%Jdeclaration of non-variable '%D' in 'for' loop "
+ error ("%Jdeclaration of non-variable %qD in %<for%> loop "
"initial declaration", decl, decl);
}
}
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->tag_defined_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;
}
returning SPECS. */
struct c_declspecs *
-declspecs_add_type (struct c_declspecs *specs, tree type)
+declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
{
+ tree type = spec.spec;
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);
specs->type = TREE_TYPE (t);
}
else if (TREE_CODE (type) != ERROR_MARK)
- specs->type = type;
+ {
+ if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref)
+ specs->tag_defined_p = true;
+ if (spec.kind == ctsk_typeof)
+ specs->typedef_p = true;
+ specs->type = type;
+ }
return specs;
}
declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
{
enum rid i;
+ enum c_storage_class n = csc_none;
+ bool dupe = false;
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));
- if (specs->specbits & (1 << (int) i))
- error ("duplicate %qs", IDENTIFIER_POINTER (scspec));
- /* Diagnose "__thread extern" and "__thread static". */
- if (specs->specbits & (1 << (int) RID_THREAD))
- {
- if (i == RID_EXTERN)
+ switch (i)
+ {
+ case RID_INLINE:
+ /* 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:
+ dupe = specs->thread_p;
+ if (specs->storage_class == csc_auto)
+ error ("%<__thread%> used with %<auto%>");
+ else if (specs->storage_class == csc_register)
+ error ("%<__thread%> used with %<register%>");
+ else if (specs->storage_class == csc_typedef)
+ error ("%<__thread%> used with %<typedef%>");
+ else
+ specs->thread_p = true;
+ break;
+ case RID_AUTO:
+ n = csc_auto;
+ break;
+ case RID_EXTERN:
+ n = csc_extern;
+ /* Diagnose "__thread extern". */
+ if (specs->thread_p)
error ("%<__thread%> before %<extern%>");
- else if (i == RID_STATIC)
+ break;
+ case RID_REGISTER:
+ n = csc_register;
+ break;
+ case RID_STATIC:
+ n = csc_static;
+ /* Diagnose "__thread static". */
+ if (specs->thread_p)
error ("%<__thread%> before %<static%>");
+ break;
+ case RID_TYPEDEF:
+ n = csc_typedef;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (n != csc_none && n == specs->storage_class)
+ dupe = true;
+ if (dupe)
+ error ("duplicate %qs", IDENTIFIER_POINTER (scspec));
+ if (n != csc_none)
+ {
+ if (specs->storage_class != csc_none && n != specs->storage_class)
+ {
+ error ("multiple storage classes in declaration specifiers");
+ }
+ else
+ {
+ specs->storage_class = n;
+ if (n != csc_extern && n != csc_static && specs->thread_p)
+ {
+ error ("%<__thread%> used with %qs",
+ IDENTIFIER_POINTER (scspec));
+ specs->thread_p = false;
+ }
+ }
}
- specs->specbits |= 1 << (int) i;
return specs;
}
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. */
&& !TREE_PUBLIC (decl)
&& C_DECL_USED (decl))
{
- pedwarn ("%J%<%F%> used but never defined", decl, decl);
+ pedwarn ("%J%qF used but never defined", decl, decl);
TREE_NO_WARNING (decl) = 1;
}
}
/* 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"