aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-01-19 06:55:53 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-01-19 06:55:53 +0000
commitc888c93b290aeb3f7eb556bd5b7ed4f7564c822a (patch)
tree7783dc30a654ed3f4012aa97244eb51ffd2fa604 /gcc/cp
parente79b9d54a17db3d8676ae30c1f04e90e90691cec (diff)
downloadgcc-c888c93b290aeb3f7eb556bd5b7ed4f7564c822a.zip
gcc-c888c93b290aeb3f7eb556bd5b7ed4f7564c822a.tar.gz
gcc-c888c93b290aeb3f7eb556bd5b7ed4f7564c822a.tar.bz2
re PR c++/25836 (G++ does not allow a conversion of templated types)
PR c++/25836 * cp-tree.h (push_class_stack): New function. (pop_class_stack): Likewise. * class.c (class_stack_node): Add hidden field. (pushclass): Clear it. (push_class_stack): New function. (pop_class_stack): Likewise. (currently_open_class): Ignore hidden classes. (currently_open_derived_class): Likewise. * name-lookup.c (push_to_top_level): Call push_class_stack. (pop_from_top_level): Call pop_class_stack. PR c++/25836 * g++.dg/template/init6.C: New test. From-SVN: r109945
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/class.c54
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/name-lookup.c2
4 files changed, 62 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1ed12d6..b386ef4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2006-01-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25836
+ * cp-tree.h (push_class_stack): New function.
+ (pop_class_stack): Likewise.
+ * class.c (class_stack_node): Add hidden field.
+ (pushclass): Clear it.
+ (push_class_stack): New function.
+ (pop_class_stack): Likewise.
+ (currently_open_class): Ignore hidden classes.
+ (currently_open_derived_class): Likewise.
+ * name-lookup.c (push_to_top_level): Call push_class_stack.
+ (pop_from_top_level): Call pop_class_stack.
+
2006-01-18 Kazu Hirata <kazu@codesourcery.com>
* tree.c (find_tree_t, find_tree): Remove.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 86dbcca..bd89b55 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -60,6 +60,10 @@ typedef struct class_stack_node {
/* If were defining TYPE, the names used in this class. */
splay_tree names_used;
+
+ /* Nonzero if this class is no longer open, because of a call to
+ push_to_top_level. */
+ size_t hidden;
}* class_stack_node_t;
typedef struct vtbl_init_data_s
@@ -5387,6 +5391,8 @@ restore_class_cache (void)
void
pushclass (tree type)
{
+ class_stack_node_t csn;
+
type = TYPE_MAIN_VARIANT (type);
/* Make sure there is enough room for the new entry on the stack. */
@@ -5399,10 +5405,12 @@ pushclass (tree type)
}
/* Insert a new entry on the class stack. */
- current_class_stack[current_class_depth].name = current_class_name;
- current_class_stack[current_class_depth].type = current_class_type;
- current_class_stack[current_class_depth].access = current_access_specifier;
- current_class_stack[current_class_depth].names_used = 0;
+ csn = current_class_stack + current_class_depth;
+ csn->name = current_class_name;
+ csn->type = current_class_type;
+ csn->access = current_access_specifier;
+ csn->names_used = 0;
+ csn->hidden = 0;
current_class_depth++;
/* Now set up the new type. */
@@ -5459,6 +5467,24 @@ popclass (void)
splay_tree_delete (current_class_stack[current_class_depth].names_used);
}
+/* Mark the top of the class stack as hidden. */
+
+void
+push_class_stack (void)
+{
+ if (current_class_depth)
+ ++current_class_stack[current_class_depth - 1].hidden;
+}
+
+/* Mark the top of the class stack as un-hidden. */
+
+void
+pop_class_stack (void)
+{
+ if (current_class_depth)
+ --current_class_stack[current_class_depth - 1].hidden;
+}
+
/* Returns 1 if current_class_type is either T or a nested type of T.
We start looking from 1 because entry 0 is from global scope, and has
no type. */
@@ -5469,10 +5495,14 @@ currently_open_class (tree t)
int i;
if (current_class_type && same_type_p (t, current_class_type))
return 1;
- for (i = 1; i < current_class_depth; ++i)
- if (current_class_stack[i].type
- && same_type_p (current_class_stack [i].type, t))
- return 1;
+ for (i = current_class_depth - 1; i > 0; --i)
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ if (current_class_stack[i].type
+ && same_type_p (current_class_stack [i].type, t))
+ return 1;
+ }
return 0;
}
@@ -5496,8 +5526,12 @@ currently_open_derived_class (tree t)
return current_class_type;
for (i = current_class_depth - 1; i > 0; --i)
- if (DERIVED_FROM_P (t, current_class_stack[i].type))
- return current_class_stack[i].type;
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ if (DERIVED_FROM_P (t, current_class_stack[i].type))
+ return current_class_stack[i].type;
+ }
return NULL_TREE;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bcd115d..1c66e11 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3748,6 +3748,8 @@ extern tree cp_fold_obj_type_ref (tree, tree);
extern void set_linkage_according_to_type (tree, tree);
extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
+extern void push_class_stack (void);
+extern void pop_class_stack (void);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 4a6c627..02fc272 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4938,6 +4938,7 @@ push_to_top_level (void)
current_lang_base = VEC_alloc (tree, gc, 10);
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
+ push_class_stack ();
skip_evaluation = 0;
timevar_pop (TV_NAME_LOOKUP);
}
@@ -4953,6 +4954,7 @@ pop_from_top_level (void)
/* Clear out class-level bindings cache. */
if (previous_class_level)
invalidate_class_lookup_cache ();
+ pop_class_stack ();
current_lang_base = 0;