/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
/* Avoid crashing later. */
define_label (location, DECL_NAME (label));
}
- else if (warn_unused_label && !TREE_USED (label))
- warning (0, "label %q+D defined but not used", label);
+ else if (!TREE_USED (label))
+ warning (OPT_Wunused_label, "label %q+D defined but not used", label);
}
SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value);
&& ! TREE_USED (decl)
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
- warning (0, "unused variable %q+D", decl);
+ warning (OPT_Wunused_variable, "unused variable %q+D", decl);
/* Remove declarations for all the DECLs in this level. */
for (link = decls; link; link = TREE_CHAIN (link))
bad choice of name. */
if (! TREE_PUBLIC (newdecl))
{
- if (warn_shadow)
- warning (0, "shadowing %s function %q#D",
- DECL_BUILT_IN (olddecl) ? "built-in" : "library",
- olddecl);
+ warning (OPT_Wshadow, "shadowing %s function %q#D",
+ DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+ olddecl);
/* Discard the old built-in function. */
return NULL_TREE;
}
warning (0, "ambiguates built-in declaration %q#D",
olddecl);
}
- else if (warn_shadow)
- warning (0, "shadowing %s function %q#D",
+ else
+ warning (OPT_Wshadow, "shadowing %s function %q#D",
DECL_BUILT_IN (olddecl) ? "built-in" : "library",
olddecl);
}
/* Don't warn about friends, let add_friend take care of it. */
&& ! (newdecl_is_friend || DECL_FRIEND_P (olddecl)))
{
- warning (0, "redundant redeclaration of %qD in same scope", newdecl);
- warning (0, "previous declaration of %q+D", olddecl);
+ warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
+ warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
}
}
constructs like "typedef struct foo { ... } foo"
would look like an erroneous redeclaration. */
if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
- return 0;
+ return NULL;
else
return "redefinition of %q#D";
}
abort()). Don't complain about redefinition in this case. */
if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl)
&& DECL_INITIAL (olddecl) == NULL_TREE)
- return 0;
+ return NULL;
/* If both functions come from different namespaces, this is not
a redeclaration - this is a conflict with a used function. */
else
return "redefinition of %q#D";
}
- return 0;
+ return NULL;
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
/* Objects declared at top level: */
/* If at least one is a reference, it's ok. */
if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
- return 0;
+ return NULL;
/* Reject two definitions. */
return "redefinition of %q#D";
}
together with an external reference. */
if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)))
return "redeclaration of %q#D";
- return 0;
+ return NULL;
}
}
\f
TREE_OPERAND (fullname, 1),
NULL_TREE, context,
/*entering_scope=*/0,
- tf_error | tf_warning | tf_user);
+ tf_warning_or_error | tf_user);
}
else
{
while (b->level_chain->kind != sk_function_parms)
b = b->level_chain;
pushdecl_with_scope (decl, b, /*is_friend=*/false);
- cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+ cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
+ LOOKUP_ONLYCONVERTING);
}
else
pushdecl_top_level_and_finish (decl, init);
If the length of an array type is not known before,
it must be determined now, from the initial value, or it is an error.
- INIT holds the value of an initializer that should be allowed to escape
- the normal rules.
+ INIT is the initializer (if any) for DECL. If INIT_CONST_EXPR_P is
+ true, then INIT is an integral constant expression.
FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
if the (init) syntax was used. */
void
-cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
+cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
+ tree asmspec_tree, int flags)
{
tree type;
tree cleanup;
add_decl_expr (decl);
if (init && DECL_INITIAL (decl))
- DECL_INITIAL (decl) = init;
+ {
+ DECL_INITIAL (decl) = init;
+ if (init_const_expr_p)
+ {
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+ if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+ TREE_CONSTANT (decl) = 1;
+ }
+ }
+
if (TREE_CODE (decl) == VAR_DECL
&& !DECL_PRETTY_FUNCTION_P (decl)
&& !dependent_type_p (TREE_TYPE (decl)))
&& (!DECL_EXTERNAL (decl) || init))
{
if (init)
- DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+ {
+ DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+ if (init_const_expr_p)
+ {
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+ if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+ TREE_CONSTANT (decl) = 1;
+ }
+ }
init = check_initializer (decl, init, flags, &cleanup);
/* Thread-local storage cannot be dynamically initialized. */
if (DECL_THREAD_LOCAL_P (decl) && init)
void
finish_decl (tree decl, tree init, tree asmspec_tree)
{
- cp_finish_decl (decl, init, asmspec_tree, 0);
+ cp_finish_decl (decl, init, /*init_const_expr_p=*/false, asmspec_tree, 0);
}
/* Returns a declaration for a VAR_DECL as if:
library), then it is possible that our declaration will be merged
with theirs by pushdecl. */
decl = pushdecl (decl);
- cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
+ finish_decl (decl, NULL_TREE, NULL_TREE);
pop_from_top_level ();
return decl;
tree
compute_array_index_type (tree name, tree size)
{
- tree type = TREE_TYPE (size);
+ tree type;
tree itype;
+ if (error_operand_p (size))
+ return error_mark_node;
+
+ type = TREE_TYPE (size);
/* The array bound must be an integer type. */
if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
{
this value will be NULL_TREE, even if the entity is located at
namespace scope. */
tree in_namespace = NULL_TREE;
- cp_decl_spec ds;
cp_storage_class storage_class;
bool unsigned_p, signed_p, short_p, long_p, thread_p;
bool type_was_error_mark_node = false;
unsigned_p = declspecs->specs[(int)ds_unsigned];
short_p = declspecs->specs[(int)ds_short];
long_p = declspecs->specs[(int)ds_long];
+ longlong = declspecs->specs[(int)ds_long] >= 2;
thread_p = declspecs->specs[(int)ds_thread];
if (decl_context == FUNCDEF)
type = TREE_OPERAND (decl, 0);
name = IDENTIFIER_POINTER (constructor_name (type));
+ dname = decl;
}
break;
a function declarator. */
if (funcdef_flag && innermost_code != cdk_function)
- return 0;
+ return NULL_TREE;
if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
&& innermost_code != cdk_function
explicit_int = declspecs->explicit_int_p;
explicit_char = declspecs->explicit_char_p;
- /* Check for repeated decl-specifiers. */
- for (ds = ds_first; ds != ds_last; ++ds)
- {
- unsigned count = declspecs->specs[(int)ds];
- if (count < 2)
- continue;
- /* The "long" specifier is a special case because of
- "long long". */
- if (ds == ds_long)
- {
- if (count > 2)
- error ("%<long long long%> is too long for GCC");
- else if (pedantic && !in_system_header && warn_long_long)
- pedwarn ("ISO C++ does not support %<long long%>");
- else
- longlong = 1;
- }
- else if (declspecs->specs[(int)ds] > 1)
- {
- static const char *const decl_spec_names[] = {
- "signed",
- "unsigned",
- "short",
- "long",
- "const",
- "volatile",
- "restrict",
- "inline",
- "virtual",
- "explicit",
- "friend",
- "typedef",
- "__complex",
- "__thread"
- };
- error ("duplicate %qs", decl_spec_names[(int)ds]);
- }
- }
-
#if 0
/* See the code below that used this. */
if (typedef_decl)
`signed int' cannot be so controlled. */
&& !(typedef_decl
&& C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))
- && (TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == CHAR_TYPE)
+ && TREE_CODE (type) == INTEGER_TYPE
&& !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
{
if (longlong)
type_quals |= cp_type_quals (type);
type = cp_build_qualified_type_real
(type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
- ? tf_ignore_bad_quals : 0) | tf_error | tf_warning));
+ ? tf_ignore_bad_quals : 0) | tf_warning_or_error));
/* We might have ignored or rejected some of the qualifiers. */
type_quals = cp_type_quals (type);
if (virtualp && staticp == 2)
{
error ("member %qD cannot be declared both virtual and static", dname);
+ storage_class = sc_none;
staticp = 0;
}
friendp = !! declspecs->specs[(int)ds_friend];
void grok_special_member_properties (tree decl)
{
- if (!DECL_NONSTATIC_MEMBER_FUNCTION_P(decl))
+ if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
; /* Not special. */
else if (DECL_CONSTRUCTOR_P (decl))
{
tree name = DECL_NAME (decl);
enum tree_code operator_code;
int arity;
+ bool ellipsis_p;
tree class_type;
- /* Count the number of arguments. */
+ /* Count the number of arguments and check for ellipsis. */
for (argtype = argtypes, arity = 0;
argtype && argtype != void_list_node;
argtype = TREE_CHAIN (argtype))
++arity;
+ ellipsis_p = !argtype;
class_type = DECL_CONTEXT (decl);
if (class_type && !CLASS_TYPE_P (class_type))
}
if (what)
- warning (0, "conversion to %s%s will never use a type "
+ warning (OPT_Wconversion, "conversion to %s%s will never use a type "
"conversion operator",
ref ? "a reference to " : "", what);
}
+
if (operator_code == COND_EXPR)
{
/* 13.4.0.3 */
error ("ISO C++ prohibits overloading operator ?:");
}
+ else if (ellipsis_p)
+ error ("%qD must not have variable number of arguments", decl);
else if (ambi_op_p (operator_code))
{
if (arity == 1)
if (TREE_CODE (ret) != REFERENCE_TYPE
|| !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
arg))
- warning (0, "prefix %qD should return %qT", decl,
+ warning (OPT_Weffc__, "prefix %qD should return %qT", decl,
build_reference_type (arg));
}
else
{
if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg))
- warning (0, "postfix %qD should return %qT", decl, arg);
+ warning (OPT_Weffc__, "postfix %qD should return %qT", decl, arg);
}
}
}
&& (operator_code == TRUTH_ANDIF_EXPR
|| operator_code == TRUTH_ORIF_EXPR
|| operator_code == COMPOUND_EXPR))
- warning (0, "user-defined %qD always evaluates both arguments",
+ warning (OPT_Weffc__, "user-defined %qD always evaluates both arguments",
decl);
}
|| operator_code == MULT_EXPR
|| operator_code == TRUNC_MOD_EXPR)
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE)
- warning (0, "%qD should return by value", decl);
+ warning (OPT_Weffc__, "%qD should return by value", decl);
/* [over.oper]/8 */
for (; argtypes && argtypes != void_list_node;
if (warn_ecpp
&& DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
- warning (0, "%<operator=%> should return a reference to %<*this%>");
+ warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
/* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in poplevel) with the BLOCK. */
/* Structor return values (if any) are set by the compiler. */
&& !DECL_CONSTRUCTOR_P (fndecl)
&& !DECL_DESTRUCTOR_P (fndecl))
- warning (0, "no return statement in function returning non-void");
+ warning (OPT_Wreturn_type, "no return statement in function returning non-void");
/* Store the end of the function, so that we get good line number
info for the epilogue. */
if (DECL_IN_AGGR_P (fndecl))
{
if (DECL_CONTEXT (fndecl)
- && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
+ && TREE_CODE (DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
error ("%qD is already defined in class %qT", fndecl,
DECL_CONTEXT (fndecl));
return error_mark_node;
grok_special_member_properties (fndecl);
}
- cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
+ finish_decl (fndecl, NULL_TREE, NULL_TREE);
/* Make a place for the parms. */
begin_scope (sk_function_parms, fndecl);