Commit 93cdc044 by Jason Merrill Committed by Jason Merrill

pt.c (tsubst, [...]): Support member class templates.

	* pt.c (tsubst, TEMPLATE_DECL): Support member class templates.
	(tsubst, *_PARM): Support multiple levels of template classes.
	(instantiate_class_template): Look up the pattern from the
	original template.
	(lookup_template_class): Handle getting a template for d1.
	(push_template_decl): Correct setting of 'primary'.
	(reduce_template_parm_level): Add 'levels' parm.
	(finish_member_template_decl): Support member class templates.
	(template_class_depth): Handle multiple levels.
	* parse.y (component_decl_1, fn.def2): Remove member template case.
	(component_decl): Add member template cases.
	* decl2.c (check_member_template): We now handle member template
	classes.
	* decl.c (pushtag): Handle member templates.
	* method.c (do_inline_function_hair): Don't touch
	IDENTIFIER_GLOBAL_VALUE.
	* init.c (build_offset_ref): If name isn't an identifier, just
	return it.
	* spew.c (yylex): Handle PTYPENAME like TYPENAME.
	* typeck.c (get_delta_difference): Do adjust for conversions to
	and from virtual base.

From-SVN: r18280
parent a7b4c0ac
Fri Feb 27 02:25:16 1998 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (tsubst, TEMPLATE_DECL): Support member class templates.
(tsubst, *_PARM): Support multiple levels of template classes.
(instantiate_class_template): Look up the pattern from the
original template.
(lookup_template_class): Handle getting a template for d1.
(push_template_decl): Correct setting of 'primary'.
(reduce_template_parm_level): Add 'levels' parm.
(finish_member_template_decl): Support member class templates.
(template_class_depth): Handle multiple levels.
* parse.y (component_decl_1, fn.def2): Remove member template case.
(component_decl): Add member template cases.
* decl2.c (check_member_template): We now handle member template
classes.
* decl.c (pushtag): Handle member templates.
* method.c (do_inline_function_hair): Don't touch
IDENTIFIER_GLOBAL_VALUE.
* init.c (build_offset_ref): If name isn't an identifier, just
return it.
* spew.c (yylex): Handle PTYPENAME like TYPENAME.
* typeck.c (get_delta_difference): Do adjust for conversions to
and from virtual base.
Wed Feb 25 09:51:29 1998 Jason Merrill <jason@yorick.cygnus.com> Wed Feb 25 09:51:29 1998 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (get_delta_difference): Give hard error for conversion * typeck.c (get_delta_difference): Give hard error for conversion
......
...@@ -1439,12 +1439,9 @@ extern int flag_new_for_scope; ...@@ -1439,12 +1439,9 @@ extern int flag_new_for_scope;
(TREE_CODE (NODE) == TEMPLATE_DECL \ (TREE_CODE (NODE) == TEMPLATE_DECL \
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL) && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
/* A `primary' template is one which depends on no tbemplate parameters /* A `primary' template is one that has its own template header. A
except those specified in its parameter list. So, a template member function of a class template is a template, but not primary.
member of a non-template class is primary, and every global A member template is primary. */
function template is primary, but a member function of a template
class is not primary, neither is a member template of a template
class. */
#define PRIMARY_TEMPLATE_P(NODE) \ #define PRIMARY_TEMPLATE_P(NODE) \
(TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) == (NODE)) (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) == (NODE))
......
...@@ -2179,47 +2179,43 @@ pushtag (name, type, globalize) ...@@ -2179,47 +2179,43 @@ pushtag (name, type, globalize)
/* Do C++ gratuitous typedefing. */ /* Do C++ gratuitous typedefing. */
if (IDENTIFIER_TYPE_VALUE (name) != type) if (IDENTIFIER_TYPE_VALUE (name) != type)
{ {
register tree d; register tree d = NULL_TREE;
int newdecl = 0; int newdecl = 0, in_class = 0;
if (b->parm_flag != 2
|| TYPE_SIZE (current_class_type) != NULL_TREE)
{
d = lookup_nested_type (type, c_decl);
if (d == NULL_TREE) if ((b->pseudo_global && b->level_chain->parm_flag == 2)
{ || b->parm_flag == 2)
newdecl = 1; in_class = 1;
d = build_decl (TYPE_DECL, name, type);
SET_DECL_ARTIFICIAL (d);
set_identifier_type_value_with_scope (name, type, b);
}
else
d = TYPE_MAIN_DECL (d);
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
d = push_template_decl (d);
if (b->parm_flag == 2)
d = pushdecl_class_level (d);
else
d = pushdecl_with_scope (d, b);
}
else else
d = lookup_nested_type (type, c_decl);
if (d == NULL_TREE)
{ {
/* Make nested declarations go into class-level scope. */
newdecl = 1; newdecl = 1;
d = build_decl (TYPE_DECL, name, type); d = build_decl (TYPE_DECL, name, type);
SET_DECL_ARTIFICIAL (d); SET_DECL_ARTIFICIAL (d);
TYPE_NAME (type) = d; if (! in_class)
DECL_CONTEXT (d) = context; set_identifier_type_value_with_scope (name, type, b);
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type)) }
d = push_template_decl (d); else
d = TYPE_MAIN_DECL (d);
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
d = pushdecl_class_level (d); if (! globalize && processing_template_decl
&& IS_AGGR_TYPE (type))
{
d = push_template_decl (d);
if (b->pseudo_global && b->level_chain->parm_flag == 2)
pushdecl_with_scope (CLASSTYPE_TI_TEMPLATE (type),
b->level_chain);
} }
if (b->parm_flag == 2)
d = pushdecl_class_level (d);
else
d = pushdecl_with_scope (d, b);
if (newdecl) if (newdecl)
{ {
if (ANON_AGGRNAME_P (name)) if (ANON_AGGRNAME_P (name))
......
...@@ -1395,9 +1395,6 @@ check_member_template (tmpl) ...@@ -1395,9 +1395,6 @@ check_member_template (tmpl)
A local class shall not have member templates. */ A local class shall not have member templates. */
cp_error ("declaration of of member template `%#D' in local class", cp_error ("declaration of of member template `%#D' in local class",
decl); decl);
/* We don't handle member template classes yet. */
sorry ("member templates classes");
} }
else else
cp_error ("template declaration of `%#D'", decl); cp_error ("template declaration of `%#D'", decl);
......
...@@ -1836,6 +1836,9 @@ build_offset_ref (type, name) ...@@ -1836,6 +1836,9 @@ build_offset_ref (type, name)
tree basebinfo = NULL_TREE; tree basebinfo = NULL_TREE;
int dtor = 0; int dtor = 0;
if (TREE_CODE (name) != IDENTIFIER_NODE)
return name;
if (type == std_node) if (type == std_node)
return do_scoped_id (name, 0); return do_scoped_id (name, 0);
......
...@@ -151,11 +151,6 @@ do_inline_function_hair (type, friend_list) ...@@ -151,11 +151,6 @@ do_inline_function_hair (type, friend_list)
DECL_CONTEXT (args) = method; DECL_CONTEXT (args) = method;
args = TREE_CHAIN (args); args = TREE_CHAIN (args);
} }
/* Allow this decl to be seen in global scope. Don't do this for
local class methods, though. */
if (! current_function_decl)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
} }
method = TREE_CHAIN (method); method = TREE_CHAIN (method);
} }
...@@ -174,10 +169,6 @@ do_inline_function_hair (type, friend_list) ...@@ -174,10 +169,6 @@ do_inline_function_hair (type, friend_list)
DECL_CONTEXT (args) = fndecl; DECL_CONTEXT (args) = fndecl;
args = TREE_CHAIN (args); args = TREE_CHAIN (args);
} }
/* Allow this decl to be seen in global scope */
if (! current_function_decl)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
} }
friend_list = TREE_CHAIN (friend_list); friend_list = TREE_CHAIN (friend_list);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -769,8 +769,6 @@ fn.def2: ...@@ -769,8 +769,6 @@ fn.def2:
$$ = start_method (specs, $2); goto rest_of_mdef; } $$ = start_method (specs, $2); goto rest_of_mdef; }
| constructor_declarator | constructor_declarator
{ $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; }
| template_header fn.def2
{ $$ = finish_member_template_decl ($1, $2); }
; ;
return_id: return_id:
...@@ -2760,6 +2758,14 @@ component_decl: ...@@ -2760,6 +2758,14 @@ component_decl:
| extension component_decl | extension component_decl
{ $$ = $2; { $$ = $2;
pedantic = $<itype>1; } pedantic = $<itype>1; }
| template_header component_decl
{ $$ = finish_member_template_decl ($1, $2); }
| template_header typed_declspecs ';'
{
shadow_tag ($2.t);
note_list_got_semicolon ($2.t);
$$ = finish_member_template_decl ($1, $2.t);
}
; ;
component_decl_1: component_decl_1:
...@@ -2799,8 +2805,6 @@ component_decl_1: ...@@ -2799,8 +2805,6 @@ component_decl_1:
build_tree_list ($3, NULL_TREE)); } build_tree_list ($3, NULL_TREE)); }
| using_decl | using_decl
{ $$ = do_class_using_decl ($1); } { $$ = do_class_using_decl ($1); }
| template_header component_decl_1
{ $$ = finish_member_template_decl ($1, $2); }
/* The case of exactly one component is handled directly by component_decl. */ /* The case of exactly one component is handled directly by component_decl. */
/* ??? Huh? ^^^ */ /* ??? Huh? ^^^ */
......
...@@ -99,12 +99,24 @@ finish_member_template_decl (template_parameters, decl) ...@@ -99,12 +99,24 @@ finish_member_template_decl (template_parameters, decl)
tree decl; tree decl;
{ {
if (template_parameters) if (template_parameters)
end_template_decl(); end_template_decl ();
else else
end_specialization(); end_specialization ();
if (decl && DECL_TEMPLATE_INFO (decl) && if (decl == NULL_TREE || decl == void_type_node)
!DECL_TEMPLATE_SPECIALIZATION (decl)) return NULL_TREE;
else if (TREE_CODE (decl) == TREE_LIST)
{
decl = TREE_VALUE (decl);
if (IS_AGGR_TYPE (decl) && CLASSTYPE_TEMPLATE_INFO (decl))
{
tree tmpl = CLASSTYPE_TI_TEMPLATE (decl);
check_member_template (tmpl);
return tmpl;
}
}
else if (DECL_TEMPLATE_INFO (decl) &&
!DECL_TEMPLATE_SPECIALIZATION (decl))
{ {
check_member_template (DECL_TI_TEMPLATE (decl)); check_member_template (DECL_TI_TEMPLATE (decl));
return DECL_TI_TEMPLATE (decl); return DECL_TI_TEMPLATE (decl);
...@@ -130,14 +142,14 @@ int ...@@ -130,14 +142,14 @@ int
template_class_depth (type) template_class_depth (type)
tree type; tree type;
{ {
int depth = 0; int depth;
/* Note: this implementation will be broken when we have nested for (depth = 0; type && TREE_CODE (type) != FUNCTION_DECL;
template classes. Presumably we will have to wrap this if type = TYPE_CONTEXT (type))
statement a loop. */ if (CLASSTYPE_TEMPLATE_INFO (type)
if (CLASSTYPE_TEMPLATE_INFO (type) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
&& uses_template_parms (CLASSTYPE_TI_ARGS (type))) && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
++depth; ++depth;
return depth; return depth;
} }
...@@ -1047,18 +1059,19 @@ build_template_parm_index (index, level, orig_level, decl, type) ...@@ -1047,18 +1059,19 @@ build_template_parm_index (index, level, orig_level, decl, type)
/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose /* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose
TEMPLATE_PARM_LEVEL has been decreased by one. If such a TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a
TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a
new one is created. */ new one is created. */
static tree static tree
reduce_template_parm_level (index, type) reduce_template_parm_level (index, type, levels)
tree index; tree index;
tree type; tree type;
int levels;
{ {
if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
|| (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
!= TEMPLATE_PARM_LEVEL (index) - 1)) != TEMPLATE_PARM_LEVEL (index) - levels))
{ {
tree decl tree decl
= build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)), = build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)),
...@@ -1066,7 +1079,7 @@ reduce_template_parm_level (index, type) ...@@ -1066,7 +1079,7 @@ reduce_template_parm_level (index, type)
type); type);
tree t tree t
= build_template_parm_index (TEMPLATE_PARM_IDX (index), = build_template_parm_index (TEMPLATE_PARM_IDX (index),
TEMPLATE_PARM_LEVEL (index) - 1, TEMPLATE_PARM_LEVEL (index) - levels,
TEMPLATE_PARM_ORIG_LEVEL (index), TEMPLATE_PARM_ORIG_LEVEL (index),
decl, type); decl, type);
TEMPLATE_PARM_DESCENDANTS (index) = t; TEMPLATE_PARM_DESCENDANTS (index) = t;
...@@ -1313,16 +1326,19 @@ push_template_decl (decl) ...@@ -1313,16 +1326,19 @@ push_template_decl (decl)
is assumed to be a member of the class. */ is assumed to be a member of the class. */
ctx = current_class_type; ctx = current_class_type;
if ((! ctx /* For determining whether this is a primary template or not, we're really
|| (TREE_CODE_CLASS (TREE_CODE (ctx)) == 't' interested in the lexical context, not the true context. */
&& template_class_depth (ctx) == 0)) if (is_friend)
/* At this point, we know that the DECL is not a member of some info = DECL_CLASS_CONTEXT (decl);
template class. However, a friend function declared in a else
template class is still not primary, since, in general it can info = ctx;
depend on the template parameters of the enclosing class. */
&& !(is_friend if (info && TREE_CODE (info) == FUNCTION_DECL)
&& DECL_CLASS_CONTEXT (decl) primary = 0;
&& template_class_depth (DECL_CLASS_CONTEXT (decl)) > 0)) else if (! info
|| (TYPE_BEING_DEFINED (info) && template_header_count
&& ! processing_specialization)
|| (template_header_count > template_class_depth (info)))
primary = 1; primary = 1;
else else
primary = 0; primary = 0;
...@@ -2376,6 +2392,13 @@ lookup_template_class (d1, arglist, in_decl, context) ...@@ -2376,6 +2392,13 @@ lookup_template_class (d1, arglist, in_decl, context)
template = CLASSTYPE_TI_TEMPLATE (d1); template = CLASSTYPE_TI_TEMPLATE (d1);
d1 = DECL_NAME (template); d1 = DECL_NAME (template);
} }
else if (TREE_CODE (d1) == TEMPLATE_DECL
&& TREE_CODE (DECL_RESULT (d1)) == TYPE_DECL)
{
template = d1;
d1 = DECL_NAME (template);
context = DECL_CONTEXT (template);
}
else else
my_friendly_abort (272); my_friendly_abort (272);
...@@ -2928,6 +2951,13 @@ instantiate_class_template (type) ...@@ -2928,6 +2951,13 @@ instantiate_class_template (type)
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279); my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
args = TI_ARGS (template_info); args = TI_ARGS (template_info);
if (DECL_TEMPLATE_INFO (template))
{
args = add_to_template_args (DECL_TI_ARGS (template), args);
while (DECL_TEMPLATE_INFO (template))
template = DECL_TI_TEMPLATE (template);
}
t = most_specialized_class t = most_specialized_class
(DECL_TEMPLATE_SPECIALIZATIONS (template), args); (DECL_TEMPLATE_SPECIALIZATIONS (template), args);
...@@ -3391,6 +3421,7 @@ tsubst (t, args, in_decl) ...@@ -3391,6 +3421,7 @@ tsubst (t, args, in_decl)
{ {
int idx; int idx;
int level; int level;
int levels;
tree r = NULL_TREE; tree r = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_TYPE_PARM if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
...@@ -3411,12 +3442,17 @@ tsubst (t, args, in_decl) ...@@ -3411,12 +3442,17 @@ tsubst (t, args, in_decl)
if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
{ {
if (TREE_VEC_LENGTH (args) >= level - 1) levels = TREE_VEC_LENGTH (args);
if (level <= levels)
arg = TREE_VEC_ELT arg = TREE_VEC_ELT
(TREE_VEC_ELT (args, level - 1), idx); (TREE_VEC_ELT (args, level - 1), idx);
} }
else if (level == 1) else
arg = TREE_VEC_ELT (args, idx); {
levels = 1;
if (level == 1)
arg = TREE_VEC_ELT (args, idx);
}
if (arg != NULL_TREE) if (arg != NULL_TREE)
{ {
...@@ -3470,14 +3506,14 @@ tsubst (t, args, in_decl) ...@@ -3470,14 +3506,14 @@ tsubst (t, args, in_decl)
r = copy_node (t); r = copy_node (t);
TEMPLATE_TYPE_PARM_INDEX (r) TEMPLATE_TYPE_PARM_INDEX (r)
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t), = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
r); r, levels);
TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r); TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
TYPE_MAIN_VARIANT (r) = r; TYPE_MAIN_VARIANT (r) = r;
TYPE_POINTER_TO (r) = NULL_TREE; TYPE_POINTER_TO (r) = NULL_TREE;
break; break;
case TEMPLATE_PARM_INDEX: case TEMPLATE_PARM_INDEX:
r = reduce_template_parm_level (t, TREE_TYPE (t)); r = reduce_template_parm_level (t, TREE_TYPE (t), levels);
break; break;
default: default:
...@@ -3493,23 +3529,15 @@ tsubst (t, args, in_decl) ...@@ -3493,23 +3529,15 @@ tsubst (t, args, in_decl)
of a template class. */ of a template class. */
tree tmpl; tree tmpl;
tree decl = DECL_TEMPLATE_RESULT (t); tree decl = DECL_TEMPLATE_RESULT (t);
tree new_decl;
tree parms; tree parms;
tree* new_parms; tree* new_parms;
tree spec; tree spec;
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL
{ && TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
if (TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM) /* There is no tsubst'ing to be done in a template template
/* There is no tsubst'ing to be done in a template template parameter. */
parameter. */ return t;
return t;
/* This must be a member template class. We don't handle
this case yet. */
sorry ("member template classes");
return t;
}
/* We might already have an instance of this template. */ /* We might already have an instance of this template. */
spec = retrieve_specialization (t, args); spec = retrieve_specialization (t, args);
...@@ -3531,10 +3559,22 @@ tsubst (t, args, in_decl) ...@@ -3531,10 +3559,22 @@ tsubst (t, args, in_decl)
DECL_CLASS_CONTEXT (tmpl) = tsubst (DECL_CLASS_CONTEXT (t), DECL_CLASS_CONTEXT (tmpl) = tsubst (DECL_CLASS_CONTEXT (t),
args, in_decl); args, in_decl);
DECL_TEMPLATE_INFO (tmpl) = build_tree_list (t, args); DECL_TEMPLATE_INFO (tmpl) = build_tree_list (t, args);
new_decl = tsubst (decl, args, in_decl);
DECL_RESULT (tmpl) = new_decl; if (TREE_CODE (decl) == TYPE_DECL)
DECL_TI_TEMPLATE (new_decl) = tmpl; {
TREE_TYPE (tmpl) = TREE_TYPE (new_decl); tree new_type = tsubst (TREE_TYPE (t), args, in_decl);
TREE_TYPE (tmpl) = new_type;
CLASSTYPE_TI_TEMPLATE (new_type) = tmpl;
DECL_RESULT (tmpl) = TYPE_MAIN_DECL (new_type);
}
else
{
tree new_decl = tsubst (decl, args, in_decl);
DECL_RESULT (tmpl) = new_decl;
DECL_TI_TEMPLATE (new_decl) = tmpl;
TREE_TYPE (tmpl) = TREE_TYPE (new_decl);
}
DECL_TEMPLATE_INSTANTIATIONS (tmpl) = NULL_TREE; DECL_TEMPLATE_INSTANTIATIONS (tmpl) = NULL_TREE;
SET_DECL_IMPLICIT_INSTANTIATION (tmpl); SET_DECL_IMPLICIT_INSTANTIATION (tmpl);
...@@ -3572,6 +3612,12 @@ tsubst (t, args, in_decl) ...@@ -3572,6 +3612,12 @@ tsubst (t, args, in_decl)
NULL_TREE); NULL_TREE);
} }
if (PRIMARY_TEMPLATE_P (t))
TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (tmpl)) = tmpl;
if (TREE_CODE (decl) == TYPE_DECL)
return tmpl;
/* What should we do with the specializations of this member /* What should we do with the specializations of this member
template? Are they specializations of this new template, template? Are they specializations of this new template,
or instantiations of the templates they previously were? or instantiations of the templates they previously were?
......
...@@ -313,6 +313,7 @@ yylex () ...@@ -313,6 +313,7 @@ yylex ()
case TYPENAME: case TYPENAME:
case SELFNAME: case SELFNAME:
case NSNAME: case NSNAME:
case PTYPENAME:
lastiddecl = trrr; lastiddecl = trrr;
if (got_scope) if (got_scope)
tmp_token.yylval.ttype = trrr; tmp_token.yylval.ttype = trrr;
...@@ -320,7 +321,6 @@ yylex () ...@@ -320,7 +321,6 @@ yylex ()
case PFUNCNAME: case PFUNCNAME:
case IDENTIFIER: case IDENTIFIER:
case PTYPENAME:
lastiddecl = trrr; lastiddecl = trrr;
break; break;
......
...@@ -6304,8 +6304,16 @@ get_delta_difference (from, to, force) ...@@ -6304,8 +6304,16 @@ get_delta_difference (from, to, force)
return delta; return delta;
} }
binfo = get_binfo (to, from, 1); binfo = get_binfo (to, from, 1);
if (binfo == 0 || binfo == error_mark_node || TREE_VIA_VIRTUAL (binfo)) if (binfo == 0 || binfo == error_mark_node)
return delta; return delta;
if (TREE_VIA_VIRTUAL (binfo))
{
binfo = binfo_member (BINFO_TYPE (binfo),
CLASSTYPE_VBASECLASSES (from));
cp_warning ("pointer to member cast to virtual base `%T'",
BINFO_TYPE (binfo));
warning (" will only work if you are very careful");
}
delta = BINFO_OFFSET (binfo); delta = BINFO_OFFSET (binfo);
delta = cp_convert (ptrdiff_type_node, delta); delta = cp_convert (ptrdiff_type_node, delta);
...@@ -6325,7 +6333,6 @@ get_delta_difference (from, to, force) ...@@ -6325,7 +6333,6 @@ get_delta_difference (from, to, force)
else else
cp_error ("pointer to member conversion from virtual base `%T'", cp_error ("pointer to member conversion from virtual base `%T'",
BINFO_TYPE (binfo)); BINFO_TYPE (binfo));
return delta;
} }
return BINFO_OFFSET (binfo); return BINFO_OFFSET (binfo);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment