Commit 874503bc by Mark Mitchell

class.c (instantiate_type): Handle pointer-to-members where the member is a template.

	* class.c (instantiate_type): Handle pointer-to-members where the
	member is a template.
	* init.c (build_offset_ref): Likewise.
	* typeck.c (build_unary_op): Likewise.

From-SVN: r20269
parent dfdfa60f
...@@ -5092,6 +5092,21 @@ instantiate_type (lhstype, rhs, complain) ...@@ -5092,6 +5092,21 @@ instantiate_type (lhstype, rhs, complain)
return rhs; return rhs;
} }
case SCOPE_REF:
{
/* This can happen if we are forming a pointer-to-member for a
member template. */
tree template_id_expr = TREE_OPERAND (rhs, 1);
tree name;
my_friendly_assert (TREE_CODE (template_id_expr) == TEMPLATE_ID_EXPR,
0);
explicit_targs = TREE_OPERAND (template_id_expr, 1);
name = TREE_OPERAND (template_id_expr, 0);
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
rhs = lookup_fnfields (TYPE_BINFO (TREE_OPERAND (rhs, 0)), name, 1);
goto overload;
}
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
{ {
explicit_targs = TREE_OPERAND (rhs, 1); explicit_targs = TREE_OPERAND (rhs, 1);
...@@ -5101,6 +5116,7 @@ instantiate_type (lhstype, rhs, complain) ...@@ -5101,6 +5116,7 @@ instantiate_type (lhstype, rhs, complain)
my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401); my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
case OVERLOAD: case OVERLOAD:
overload:
{ {
tree elem, elems; tree elem, elems;
...@@ -5112,7 +5128,8 @@ instantiate_type (lhstype, rhs, complain) ...@@ -5112,7 +5128,8 @@ instantiate_type (lhstype, rhs, complain)
if (lhstype == error_mark_node) if (lhstype == error_mark_node)
return lhstype; return lhstype;
if (TREE_CODE (lhstype) != FUNCTION_TYPE) if (TREE_CODE (lhstype) != FUNCTION_TYPE
&& TREE_CODE (lhstype) != METHOD_TYPE)
{ {
rhs = DECL_NAME (OVL_FUNCTION (rhs)); rhs = DECL_NAME (OVL_FUNCTION (rhs));
if (complain) if (complain)
......
...@@ -1615,14 +1615,15 @@ build_offset_ref (type, name) ...@@ -1615,14 +1615,15 @@ build_offset_ref (type, name)
int dtor = 0; int dtor = 0;
/* class templates can come in as TEMPLATE_DECLs here. */ /* class templates can come in as TEMPLATE_DECLs here. */
if (TREE_CODE (name) != IDENTIFIER_NODE) if (TREE_CODE (name) == TEMPLATE_DECL)
return name; return name;
if (type == std_node) if (type == std_node)
return do_scoped_id (name, 0); return do_scoped_id (name, 0);
if (processing_template_decl || uses_template_parms (type)) if (processing_template_decl || uses_template_parms (type)
return build_min_nt (SCOPE_REF, type, name); || TREE_CODE (name) == TEMPLATE_ID_EXPR)
return build_min (SCOPE_REF, unknown_type_node, type, name);
/* Handle namespace names fully here. */ /* Handle namespace names fully here. */
if (TREE_CODE (type) == NAMESPACE_DECL) if (TREE_CODE (type) == NAMESPACE_DECL)
......
...@@ -4560,7 +4560,9 @@ build_unary_op (code, xarg, noconvert) ...@@ -4560,7 +4560,9 @@ build_unary_op (code, xarg, noconvert)
return build1 (ADDR_EXPR, unknown_type_node, arg); return build1 (ADDR_EXPR, unknown_type_node, arg);
} }
if (TREE_CODE (arg) == OVERLOAD) if (TREE_CODE (arg) == OVERLOAD
|| (TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 1)) == TEMPLATE_ID_EXPR))
return build1 (ADDR_EXPR, unknown_type_node, arg); return build1 (ADDR_EXPR, unknown_type_node, arg);
else if (TREE_CODE (arg) == TREE_LIST) else if (TREE_CODE (arg) == TREE_LIST)
{ {
......
// Build don't run:
class foo
{
public:
template<class T>
T bar() {}
};
int
main()
{
foo f;
int (foo::*s)() = &foo::template bar<int>;
}
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