aboutsummaryrefslogtreecommitdiff
path: root/contrib/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/decl.c')
-rw-r--r--contrib/gcc/cp/decl.c242
1 files changed, 173 insertions, 69 deletions
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c
index eb34d39ce8c0..6c7cece8eee1 100644
--- a/contrib/gcc/cp/decl.c
+++ b/contrib/gcc/cp/decl.c
@@ -1,6 +1,6 @@
/* 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.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
@@ -119,6 +119,7 @@ static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);
static tree next_initializable_field (tree);
static tree reshape_init (tree, tree *);
+static bool reshape_init_array (tree, tree, tree *, tree);
static tree build_typename_type (tree, tree, tree);
/* Erroneous argument lists can use this *IFF* they do not modify it. */
@@ -1067,6 +1068,12 @@ decls_match (tree newdecl, tree olddecl)
}
else
{
+ /* Need to check scope for variable declaration (VAR_DECL).
+ For typedef (TYPE_DECL), scope is ignored. */
+ if (TREE_CODE (newdecl) == VAR_DECL
+ && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
+ return 0;
+
if (TREE_TYPE (newdecl) == error_mark_node)
types_match = TREE_TYPE (olddecl) == error_mark_node;
else if (TREE_TYPE (olddecl) == NULL_TREE)
@@ -1410,19 +1417,32 @@ duplicate_decls (tree newdecl, tree olddecl)
/* One of the declarations is a template instantiation, and the
other is not a template at all. That's OK. */
return NULL_TREE;
- else if (TREE_CODE (newdecl) == NAMESPACE_DECL
- && DECL_NAMESPACE_ALIAS (newdecl)
- && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))
- /* In [namespace.alias] we have:
-
- In a declarative region, a namespace-alias-definition can be
- used to redefine a namespace-alias declared in that declarative
- region to refer only to the namespace to which it already
- refers.
-
- Therefore, if we encounter a second alias directive for the same
- alias, we can just ignore the second directive. */
- return olddecl;
+ else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
+ {
+ /* In [namespace.alias] we have:
+
+ In a declarative region, a namespace-alias-definition can be
+ used to redefine a namespace-alias declared in that declarative
+ region to refer only to the namespace to which it already
+ refers.
+
+ Therefore, if we encounter a second alias directive for the same
+ alias, we can just ignore the second directive. */
+ if (DECL_NAMESPACE_ALIAS (newdecl)
+ && (DECL_NAMESPACE_ALIAS (newdecl)
+ == DECL_NAMESPACE_ALIAS (olddecl)))
+ return olddecl;
+ /* [namespace.alias]
+
+ A namespace-name or namespace-alias shall not be declared as
+ the name of any other entity in the same declarative region.
+ A namespace-name defined at global scope shall not be
+ declared as the name of any other entity in any glogal scope
+ of the program. */
+ error ("declaration of `namespace %D' conflicts with", newdecl);
+ cp_error_at ("previous declaration of `namespace %D' here", olddecl);
+ return error_mark_node;
+ }
else
{
const char *errmsg = redeclaration_error_message (newdecl, olddecl);
@@ -2009,7 +2029,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
/* If both functions come from different namespaces, this is not
a redeclaration - this is a conflict with a used function. */
if (DECL_NAMESPACE_SCOPE_P (olddecl)
- && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl))
+ && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
+ && ! decls_match (olddecl, newdecl))
return "`%D' conflicts with used function";
/* We'll complain about linkage mismatches in
@@ -3690,12 +3711,12 @@ start_decl (tree declarator,
deprecated_state = DEPRECATED_NORMAL;
if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
- return NULL_TREE;
+ return error_mark_node;
type = TREE_TYPE (decl);
if (type == error_mark_node)
- return NULL_TREE;
+ return error_mark_node;
context = DECL_CONTEXT (decl);
@@ -4183,6 +4204,62 @@ next_initializable_field (tree field)
return field;
}
+/* Subroutine of reshape_init. Reshape the constructor for an array. INITP
+ is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of
+ the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we
+ are building.
+ ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST
+ representing the size of the array minus one (the maximum index), or
+ NULL_TREE if the array was declared without specifying the size. */
+
+static bool
+reshape_init_array (tree elt_type, tree max_index,
+ tree *initp, tree new_init)
+{
+ bool sized_array_p = (max_index != NULL_TREE);
+ unsigned HOST_WIDE_INT max_index_cst = 0;
+ unsigned HOST_WIDE_INT index;
+
+ if (sized_array_p)
+ {
+ if (host_integerp (max_index, 1))
+ max_index_cst = tree_low_cst (max_index, 1);
+ /* sizetype is sign extended, not zero extended. */
+ else
+ max_index_cst = tree_low_cst (convert (size_type_node, max_index), 1);
+ }
+
+ /* Loop until there are no more initializers. */
+ for (index = 0;
+ *initp && (!sized_array_p || index <= max_index_cst);
+ ++index)
+ {
+ tree element_init;
+ tree designated_index;
+
+ element_init = reshape_init (elt_type, initp);
+ if (element_init == error_mark_node)
+ return false;
+ TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
+ CONSTRUCTOR_ELTS (new_init) = element_init;
+ designated_index = TREE_PURPOSE (element_init);
+ if (designated_index)
+ {
+ /* Handle array designated initializers (GNU extension). */
+ if (TREE_CODE (designated_index) == IDENTIFIER_NODE)
+ {
+ error ("name `%D' used in a GNU-style designated "
+ "initializer for an array", designated_index);
+ TREE_PURPOSE (element_init) = NULL_TREE;
+ }
+ else
+ abort ();
+ }
+ }
+
+ return true;
+}
+
/* Undo the brace-elision allowed by [dcl.init.aggr] in a
brace-enclosed aggregate initializer.
@@ -4206,6 +4283,7 @@ reshape_init (tree type, tree *initp)
tree old_init_value;
tree new_init;
bool brace_enclosed_p;
+ bool string_init_p;
old_init = *initp;
old_init_value = (TREE_CODE (*initp) == TREE_LIST
@@ -4270,6 +4348,7 @@ reshape_init (tree type, tree *initp)
return old_init;
}
+ string_init_p = false;
if (TREE_CODE (old_init_value) == STRING_CST
&& TREE_CODE (type) == ARRAY_TYPE
&& char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
@@ -4284,6 +4363,7 @@ reshape_init (tree type, tree *initp)
/* Move past the initializer. */
*initp = TREE_CHAIN (old_init);
TREE_CHAIN (old_init) = NULL_TREE;
+ string_init_p = true;
}
else
{
@@ -4351,38 +4431,15 @@ reshape_init (tree type, tree *initp)
}
else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
{
- tree index;
tree max_index;
/* If the bound of the array is known, take no more initializers
than are allowed. */
max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
? array_type_nelts (type) : NULL_TREE);
- /* Loop through the array elements, gathering initializers. */
- for (index = size_zero_node;
- *initp && (!max_index || !tree_int_cst_lt (max_index, index));
- index = size_binop (PLUS_EXPR, index, size_one_node))
- {
- tree element_init;
-
- element_init = reshape_init (TREE_TYPE (type), initp);
- if (element_init == error_mark_node)
- return error_mark_node;
- TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
- CONSTRUCTOR_ELTS (new_init) = element_init;
- if (TREE_PURPOSE (element_init))
- {
- tree next_index = TREE_PURPOSE (element_init);
- if (TREE_CODE (next_index) == IDENTIFIER_NODE)
- {
- error ("name `%D' used in a GNU-style designated "
- "initializer for an array", next_index);
- TREE_PURPOSE (element_init) = NULL_TREE;
- }
- else
- index = next_index;
- }
- }
+ if (!reshape_init_array (TREE_TYPE (type), max_index,
+ initp, new_init))
+ return error_mark_node;
}
else
abort ();
@@ -4395,10 +4452,15 @@ reshape_init (tree type, tree *initp)
new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);
}
- /* If this was a brace-enclosed initializer and all of the
- initializers were not used up, there is a problem. */
- if (brace_enclosed_p && *initp)
- error ("too many initializers for `%T'", type);
+ /* If there are more initializers than necessary, issue a
+ diagnostic. */
+ if (*initp)
+ {
+ if (brace_enclosed_p)
+ error ("too many initializers for `%T'", type);
+ else if (warn_missing_braces && !string_init_p)
+ warning ("missing braces around initializer");
+ }
return new_init;
}
@@ -4723,6 +4785,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
tree cleanup;
const char *asmspec = NULL;
int was_readonly = 0;
+ bool var_definition_p = false;
if (decl == error_mark_node)
return;
@@ -4875,6 +4938,11 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
/* Remember that the initialization for this variable has
taken place. */
DECL_INITIALIZED_P (decl) = 1;
+ /* This declaration is the definition of this variable,
+ unless we are initializing a static data member within
+ the class specifier. */
+ if (!DECL_EXTERNAL (decl))
+ var_definition_p = true;
}
/* If the variable has an array type, lay out the type, even if
there is no initializer. It is valid to index through the
@@ -4949,8 +5017,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
initialize_local_var (decl, init);
}
- if (TREE_STATIC (decl))
- expand_static_init (decl, init);
+ /* If a variable is defined, and then a subsequent
+ definintion with external linkage is encountered, we will
+ get here twice for the same variable. We want to avoid
+ calling expand_static_init more than once. For variables
+ that are not static data members, we can call
+ expand_static_init only when we actually process the
+ initializer. It is not legal to redeclare a static data
+ member, so this issue does not arise in that case. */
+ if (var_definition_p && TREE_STATIC (decl))
+ expand_static_init (decl, init);
}
finish_end0:
@@ -6317,6 +6393,32 @@ check_special_function_return_type (special_function_kind sfk,
return type;
}
+/* A variable or data member (whose unqualified name is IDENTIFIER)
+ has been declared with the indicated TYPE. If the TYPE is not
+ acceptable, issue an error message and return a type to use for
+ error-recovery purposes. */
+
+tree
+check_var_type (tree identifier, tree type)
+{
+ if (VOID_TYPE_P (type))
+ {
+ if (!identifier)
+ error ("unnamed variable or field declared void");
+ else if (TREE_CODE (identifier) == IDENTIFIER_NODE)
+ {
+ if (IDENTIFIER_OPNAME_P (identifier))
+ abort ();
+ error ("variable or field `%E' declared void", identifier);
+ }
+ else
+ error ("variable or field declared void");
+ type = integer_type_node;
+ }
+
+ return type;
+}
+
/* Given declspecs and a declarator (abstract or otherwise), determine
the name and type of the object declared and construct a DECL node
for it.
@@ -8016,30 +8118,25 @@ grokdeclarator (tree declarator,
&& ! bitfield)
{
error ("abstract declarator `%T' used as declaration", type);
- declarator = make_anon_name ();
+ return error_mark_node;
}
- /* `void' at top level (not within pointer)
- is allowed only in typedefs or type names.
- We don't complain about parms either, but that is because
- a better error message can be made later. */
-
- if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
+ /* Only functions may be declared using an operator-function-id. */
+ if (declarator
+ && TREE_CODE (declarator) == IDENTIFIER_NODE
+ && IDENTIFIER_OPNAME_P (declarator)
+ && TREE_CODE (type) != FUNCTION_TYPE
+ && TREE_CODE (type) != METHOD_TYPE)
{
- if (! declarator)
- error ("unnamed variable or field declared void");
- else if (TREE_CODE (declarator) == IDENTIFIER_NODE)
- {
- if (IDENTIFIER_OPNAME_P (declarator))
- abort ();
- else
- error ("variable or field `%s' declared void", name);
- }
- else
- error ("variable or field declared void");
- type = integer_type_node;
+ error ("declaration of `%D' as non-function", declarator);
+ return error_mark_node;
}
+ /* We don't check parameter types here because we can emit a better
+ error message later. */
+ if (decl_context != PARM)
+ type = check_var_type (declarator, type);
+
/* Now create the decl, which may be a VAR_DECL, a PARM_DECL
or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */
@@ -9848,7 +9945,14 @@ finish_enum (tree enumtype)
underlying type in the range bmin to bmax, where bmin and bmax are,
respectively, the smallest and largest values of the smallest bit-
field that can store emin and emax. */
- TYPE_PRECISION (enumtype) = precision;
+
+ /* The middle-end currently assumes that types with TYPE_PRECISION
+ narrower than their underlying type are suitably zero or sign
+ extended to fill their mode. g++ doesn't make these guarantees.
+ Until the middle-end can represent such paradoxical types, we
+ set the TYPE_PRECISON to the width of the underlying type. */
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (underlying_type);
+
set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
/* [dcl.enum]