aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2007-06-15 16:58:29 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2007-06-15 16:58:29 +0000
commit555551c24b5159164cef489982455d2012561f8b (patch)
treeb580e5336b6a72d59b683347c5293fe4228f6485 /gcc/cp/class.c
parent2f119dcccd49dcb0c8b72b4048712bdbc0e3988e (diff)
downloadgcc-555551c24b5159164cef489982455d2012561f8b.zip
gcc-555551c24b5159164cef489982455d2012561f8b.tar.gz
gcc-555551c24b5159164cef489982455d2012561f8b.tar.bz2
cp-tree.h (DECL_VAR_MARKED_P): Remove.
* cp-tree.h (DECL_VAR_MARKED_P): Remove. (DECL_ANON_UNION_VAR_P): New macro. * class.c (fixed_type_or_null): Tidy. Use a hash table, rather than DECL_VAR_MARKED_P, to keep track of which variables we have seen. * decl.c (redeclaration_error_message): Complain about redeclaring anonymous union members at namespace scope. * decl2.c (build_anon_union_vars): Set DECL_ANON_UNION_VAR_P. * g++.dg/lookup/anon6.C: New test. From-SVN: r125745
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 953cdff..0314df3 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5244,16 +5244,17 @@ finish_struct (tree t, tree attributes)
before this function is called. */
static tree
-fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
+fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
{
+#define RECUR(T) fixed_type_or_null((T), nonnull, cdtorp)
+
switch (TREE_CODE (instance))
{
case INDIRECT_REF:
if (POINTER_TYPE_P (TREE_TYPE (instance)))
return NULL_TREE;
else
- return fixed_type_or_null (TREE_OPERAND (instance, 0),
- nonnull, cdtorp);
+ return RECUR (TREE_OPERAND (instance, 0));
case CALL_EXPR:
/* This is a call to a constructor, hence it's never zero. */
@@ -5273,20 +5274,21 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
*nonnull = 1;
return TREE_TYPE (instance);
}
- return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+ return RECUR (TREE_OPERAND (instance, 0));
case PLUS_EXPR:
case MINUS_EXPR:
if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
- return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+ return RECUR (TREE_OPERAND (instance, 0));
if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
/* Propagate nonnull. */
- return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+ return RECUR (TREE_OPERAND (instance, 0));
+
return NULL_TREE;
case NOP_EXPR:
case CONVERT_EXPR:
- return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+ return RECUR (TREE_OPERAND (instance, 0));
case ADDR_EXPR:
instance = TREE_OPERAND (instance, 0);
@@ -5299,14 +5301,14 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
if (t && DECL_P (t))
*nonnull = 1;
}
- return fixed_type_or_null (instance, nonnull, cdtorp);
+ return RECUR (instance);
case COMPONENT_REF:
/* If this component is really a base class reference, then the field
itself isn't definitive. */
if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
- return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
- return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull, cdtorp);
+ return RECUR (TREE_OPERAND (instance, 0));
+ return RECUR (TREE_OPERAND (instance, 1));
case VAR_DECL:
case FIELD_DECL:
@@ -5344,22 +5346,33 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
}
else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
{
+ /* We only need one hash table because it is always left empty. */
+ static htab_t ht;
+ if (!ht)
+ ht = htab_create (37,
+ htab_hash_pointer,
+ htab_eq_pointer,
+ /*htab_del=*/NULL);
+
/* Reference variables should be references to objects. */
if (nonnull)
*nonnull = 1;
- /* DECL_VAR_MARKED_P is used to prevent recursion; a
+ /* Enter the INSTANCE in a table to prevent recursion; a
variable's initializer may refer to the variable
itself. */
if (TREE_CODE (instance) == VAR_DECL
&& DECL_INITIAL (instance)
- && !DECL_VAR_MARKED_P (instance))
+ && !htab_find (ht, instance))
{
tree type;
- DECL_VAR_MARKED_P (instance) = 1;
- type = fixed_type_or_null (DECL_INITIAL (instance),
- nonnull, cdtorp);
- DECL_VAR_MARKED_P (instance) = 0;
+ void **slot;
+
+ slot = htab_find_slot (ht, instance, INSERT);
+ *slot = instance;
+ type = RECUR (DECL_INITIAL (instance));
+ htab_clear_slot (ht, slot);
+
return type;
}
}
@@ -5368,6 +5381,7 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
default:
return NULL_TREE;
}
+#undef RECUR
}
/* Return nonzero if the dynamic type of INSTANCE is known, and
@@ -5389,7 +5403,6 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
{
tree t = TREE_TYPE (instance);
int cdtorp = 0;
-
tree fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
if (fixed == NULL_TREE)
return 0;