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
This commit is contained in:
parent
a7b4c0acc8
commit
93cdc044ea
|
@ -1,3 +1,28 @@
|
|||
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>
|
||||
|
||||
* typeck.c (get_delta_difference): Give hard error for conversion
|
||||
|
|
|
@ -1439,12 +1439,9 @@ extern int flag_new_for_scope;
|
|||
(TREE_CODE (NODE) == TEMPLATE_DECL \
|
||||
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
|
||||
|
||||
/* A `primary' template is one which depends on no tbemplate parameters
|
||||
except those specified in its parameter list. So, a template
|
||||
member of a non-template class is primary, and every global
|
||||
function template is primary, but a member function of a template
|
||||
class is not primary, neither is a member template of a template
|
||||
class. */
|
||||
/* A `primary' template is one that has its own template header. A
|
||||
member function of a class template is a template, but not primary.
|
||||
A member template is primary. */
|
||||
#define PRIMARY_TEMPLATE_P(NODE) \
|
||||
(TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) == (NODE))
|
||||
|
||||
|
|
|
@ -2179,47 +2179,43 @@ pushtag (name, type, globalize)
|
|||
/* Do C++ gratuitous typedefing. */
|
||||
if (IDENTIFIER_TYPE_VALUE (name) != type)
|
||||
{
|
||||
register tree d;
|
||||
int newdecl = 0;
|
||||
|
||||
if (b->parm_flag != 2
|
||||
|| TYPE_SIZE (current_class_type) != NULL_TREE)
|
||||
{
|
||||
d = lookup_nested_type (type, c_decl);
|
||||
register tree d = NULL_TREE;
|
||||
int newdecl = 0, in_class = 0;
|
||||
|
||||
if (d == NULL_TREE)
|
||||
{
|
||||
newdecl = 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);
|
||||
}
|
||||
if ((b->pseudo_global && b->level_chain->parm_flag == 2)
|
||||
|| b->parm_flag == 2)
|
||||
in_class = 1;
|
||||
else
|
||||
d = lookup_nested_type (type, c_decl);
|
||||
|
||||
if (d == NULL_TREE)
|
||||
{
|
||||
/* Make nested declarations go into class-level scope. */
|
||||
newdecl = 1;
|
||||
d = build_decl (TYPE_DECL, name, type);
|
||||
SET_DECL_ARTIFICIAL (d);
|
||||
TYPE_NAME (type) = d;
|
||||
DECL_CONTEXT (d) = context;
|
||||
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
|
||||
d = push_template_decl (d);
|
||||
|
||||
d = pushdecl_class_level (d);
|
||||
if (! in_class)
|
||||
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->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 (ANON_AGGRNAME_P (name))
|
||||
|
|
|
@ -1395,9 +1395,6 @@ check_member_template (tmpl)
|
|||
A local class shall not have member templates. */
|
||||
cp_error ("declaration of of member template `%#D' in local class",
|
||||
decl);
|
||||
|
||||
/* We don't handle member template classes yet. */
|
||||
sorry ("member templates classes");
|
||||
}
|
||||
else
|
||||
cp_error ("template declaration of `%#D'", decl);
|
||||
|
|
|
@ -1836,6 +1836,9 @@ build_offset_ref (type, name)
|
|||
tree basebinfo = NULL_TREE;
|
||||
int dtor = 0;
|
||||
|
||||
if (TREE_CODE (name) != IDENTIFIER_NODE)
|
||||
return name;
|
||||
|
||||
if (type == std_node)
|
||||
return do_scoped_id (name, 0);
|
||||
|
||||
|
|
|
@ -151,11 +151,6 @@ do_inline_function_hair (type, friend_list)
|
|||
DECL_CONTEXT (args) = method;
|
||||
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);
|
||||
}
|
||||
|
@ -174,10 +169,6 @@ do_inline_function_hair (type, friend_list)
|
|||
DECL_CONTEXT (args) = fndecl;
|
||||
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);
|
||||
|
|
6594
gcc/cp/parse.c
6594
gcc/cp/parse.c
File diff suppressed because it is too large
Load Diff
|
@ -769,8 +769,6 @@ fn.def2:
|
|||
$$ = start_method (specs, $2); goto rest_of_mdef; }
|
||||
| constructor_declarator
|
||||
{ $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; }
|
||||
| template_header fn.def2
|
||||
{ $$ = finish_member_template_decl ($1, $2); }
|
||||
;
|
||||
|
||||
return_id:
|
||||
|
@ -2760,6 +2758,14 @@ component_decl:
|
|||
| extension component_decl
|
||||
{ $$ = $2;
|
||||
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:
|
||||
|
@ -2799,8 +2805,6 @@ component_decl_1:
|
|||
build_tree_list ($3, NULL_TREE)); }
|
||||
| using_decl
|
||||
{ $$ = 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. */
|
||||
/* ??? Huh? ^^^ */
|
||||
|
|
140
gcc/cp/pt.c
140
gcc/cp/pt.c
|
@ -99,12 +99,24 @@ finish_member_template_decl (template_parameters, decl)
|
|||
tree decl;
|
||||
{
|
||||
if (template_parameters)
|
||||
end_template_decl();
|
||||
end_template_decl ();
|
||||
else
|
||||
end_specialization();
|
||||
end_specialization ();
|
||||
|
||||
if (decl && DECL_TEMPLATE_INFO (decl) &&
|
||||
!DECL_TEMPLATE_SPECIALIZATION (decl))
|
||||
if (decl == NULL_TREE || decl == void_type_node)
|
||||
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));
|
||||
return DECL_TI_TEMPLATE (decl);
|
||||
|
@ -130,14 +142,14 @@ int
|
|||
template_class_depth (type)
|
||||
tree type;
|
||||
{
|
||||
int depth = 0;
|
||||
int depth;
|
||||
|
||||
/* Note: this implementation will be broken when we have nested
|
||||
template classes. Presumably we will have to wrap this if
|
||||
statement a loop. */
|
||||
if (CLASSTYPE_TEMPLATE_INFO (type)
|
||||
&& uses_template_parms (CLASSTYPE_TI_ARGS (type)))
|
||||
++depth;
|
||||
for (depth = 0; type && TREE_CODE (type) != FUNCTION_DECL;
|
||||
type = TYPE_CONTEXT (type))
|
||||
if (CLASSTYPE_TEMPLATE_INFO (type)
|
||||
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
|
||||
&& uses_template_parms (CLASSTYPE_TI_ARGS (type)))
|
||||
++depth;
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
@ -1047,18 +1059,19 @@ build_template_parm_index (index, level, orig_level, decl, type)
|
|||
|
||||
|
||||
/* 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
|
||||
new one is created. */
|
||||
|
||||
static tree
|
||||
reduce_template_parm_level (index, type)
|
||||
reduce_template_parm_level (index, type, levels)
|
||||
tree index;
|
||||
tree type;
|
||||
int levels;
|
||||
{
|
||||
if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
|
||||
|| (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
|
||||
!= TEMPLATE_PARM_LEVEL (index) - 1))
|
||||
!= TEMPLATE_PARM_LEVEL (index) - levels))
|
||||
{
|
||||
tree decl
|
||||
= build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)),
|
||||
|
@ -1066,7 +1079,7 @@ reduce_template_parm_level (index, type)
|
|||
type);
|
||||
tree t
|
||||
= build_template_parm_index (TEMPLATE_PARM_IDX (index),
|
||||
TEMPLATE_PARM_LEVEL (index) - 1,
|
||||
TEMPLATE_PARM_LEVEL (index) - levels,
|
||||
TEMPLATE_PARM_ORIG_LEVEL (index),
|
||||
decl, type);
|
||||
TEMPLATE_PARM_DESCENDANTS (index) = t;
|
||||
|
@ -1313,16 +1326,19 @@ push_template_decl (decl)
|
|||
is assumed to be a member of the class. */
|
||||
ctx = current_class_type;
|
||||
|
||||
if ((! ctx
|
||||
|| (TREE_CODE_CLASS (TREE_CODE (ctx)) == 't'
|
||||
&& template_class_depth (ctx) == 0))
|
||||
/* At this point, we know that the DECL is not a member of some
|
||||
template class. However, a friend function declared in a
|
||||
template class is still not primary, since, in general it can
|
||||
depend on the template parameters of the enclosing class. */
|
||||
&& !(is_friend
|
||||
&& DECL_CLASS_CONTEXT (decl)
|
||||
&& template_class_depth (DECL_CLASS_CONTEXT (decl)) > 0))
|
||||
/* For determining whether this is a primary template or not, we're really
|
||||
interested in the lexical context, not the true context. */
|
||||
if (is_friend)
|
||||
info = DECL_CLASS_CONTEXT (decl);
|
||||
else
|
||||
info = ctx;
|
||||
|
||||
if (info && TREE_CODE (info) == FUNCTION_DECL)
|
||||
primary = 0;
|
||||
else if (! info
|
||||
|| (TYPE_BEING_DEFINED (info) && template_header_count
|
||||
&& ! processing_specialization)
|
||||
|| (template_header_count > template_class_depth (info)))
|
||||
primary = 1;
|
||||
else
|
||||
primary = 0;
|
||||
|
@ -2376,6 +2392,13 @@ lookup_template_class (d1, arglist, in_decl, context)
|
|||
template = CLASSTYPE_TI_TEMPLATE (d1);
|
||||
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
|
||||
my_friendly_abort (272);
|
||||
|
||||
|
@ -2928,6 +2951,13 @@ instantiate_class_template (type)
|
|||
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
|
||||
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
|
||||
(DECL_TEMPLATE_SPECIALIZATIONS (template), args);
|
||||
|
||||
|
@ -3391,6 +3421,7 @@ tsubst (t, args, in_decl)
|
|||
{
|
||||
int idx;
|
||||
int level;
|
||||
int levels;
|
||||
tree r = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
|
||||
|
@ -3411,12 +3442,17 @@ tsubst (t, args, in_decl)
|
|||
|
||||
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
|
||||
(TREE_VEC_ELT (args, level - 1), idx);
|
||||
}
|
||||
else if (level == 1)
|
||||
arg = TREE_VEC_ELT (args, idx);
|
||||
else
|
||||
{
|
||||
levels = 1;
|
||||
if (level == 1)
|
||||
arg = TREE_VEC_ELT (args, idx);
|
||||
}
|
||||
|
||||
if (arg != NULL_TREE)
|
||||
{
|
||||
|
@ -3470,14 +3506,14 @@ tsubst (t, args, in_decl)
|
|||
r = copy_node (t);
|
||||
TEMPLATE_TYPE_PARM_INDEX (r)
|
||||
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
|
||||
r);
|
||||
r, levels);
|
||||
TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
|
||||
TYPE_MAIN_VARIANT (r) = r;
|
||||
TYPE_POINTER_TO (r) = NULL_TREE;
|
||||
break;
|
||||
|
||||
case TEMPLATE_PARM_INDEX:
|
||||
r = reduce_template_parm_level (t, TREE_TYPE (t));
|
||||
r = reduce_template_parm_level (t, TREE_TYPE (t), levels);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3493,23 +3529,15 @@ tsubst (t, args, in_decl)
|
|||
of a template class. */
|
||||
tree tmpl;
|
||||
tree decl = DECL_TEMPLATE_RESULT (t);
|
||||
tree new_decl;
|
||||
tree parms;
|
||||
tree* new_parms;
|
||||
tree spec;
|
||||
|
||||
if (TREE_CODE (decl) == TYPE_DECL)
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
|
||||
/* There is no tsubst'ing to be done in a template template
|
||||
parameter. */
|
||||
return t;
|
||||
|
||||
/* This must be a member template class. We don't handle
|
||||
this case yet. */
|
||||
sorry ("member template classes");
|
||||
return t;
|
||||
}
|
||||
if (TREE_CODE (decl) == TYPE_DECL
|
||||
&& TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
|
||||
/* There is no tsubst'ing to be done in a template template
|
||||
parameter. */
|
||||
return t;
|
||||
|
||||
/* We might already have an instance of this template. */
|
||||
spec = retrieve_specialization (t, args);
|
||||
|
@ -3531,10 +3559,22 @@ tsubst (t, args, in_decl)
|
|||
DECL_CLASS_CONTEXT (tmpl) = tsubst (DECL_CLASS_CONTEXT (t),
|
||||
args, in_decl);
|
||||
DECL_TEMPLATE_INFO (tmpl) = build_tree_list (t, args);
|
||||
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);
|
||||
|
||||
if (TREE_CODE (decl) == TYPE_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;
|
||||
SET_DECL_IMPLICIT_INSTANTIATION (tmpl);
|
||||
|
||||
|
@ -3572,6 +3612,12 @@ tsubst (t, args, in_decl)
|
|||
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
|
||||
template? Are they specializations of this new template,
|
||||
or instantiations of the templates they previously were?
|
||||
|
|
|
@ -313,6 +313,7 @@ yylex ()
|
|||
case TYPENAME:
|
||||
case SELFNAME:
|
||||
case NSNAME:
|
||||
case PTYPENAME:
|
||||
lastiddecl = trrr;
|
||||
if (got_scope)
|
||||
tmp_token.yylval.ttype = trrr;
|
||||
|
@ -320,7 +321,6 @@ yylex ()
|
|||
|
||||
case PFUNCNAME:
|
||||
case IDENTIFIER:
|
||||
case PTYPENAME:
|
||||
lastiddecl = trrr;
|
||||
break;
|
||||
|
||||
|
|
|
@ -6304,8 +6304,16 @@ get_delta_difference (from, to, force)
|
|||
return delta;
|
||||
}
|
||||
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;
|
||||
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 = cp_convert (ptrdiff_type_node, delta);
|
||||
|
||||
|
@ -6325,7 +6333,6 @@ get_delta_difference (from, to, force)
|
|||
else
|
||||
cp_error ("pointer to member conversion from virtual base `%T'",
|
||||
BINFO_TYPE (binfo));
|
||||
return delta;
|
||||
}
|
||||
|
||||
return BINFO_OFFSET (binfo);
|
||||
|
|
Loading…
Reference in New Issue