aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>1998-06-07 12:13:54 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-06-07 12:13:54 +0000
commit874503bcad9c38fb673b43bcdc09e6d4658fe62a (patch)
tree6c03d69c022263d9aa94cd9a9e6ae9a38cde6cfb /gcc
parentdfdfa60f540afcfb54a599ce9a59770225d11ce6 (diff)
downloadgcc-874503bcad9c38fb673b43bcdc09e6d4658fe62a.zip
gcc-874503bcad9c38fb673b43bcdc09e6d4658fe62a.tar.gz
gcc-874503bcad9c38fb673b43bcdc09e6d4658fe62a.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/class.c19
-rw-r--r--gcc/cp/init.c7
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C16
4 files changed, 41 insertions, 5 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 900253d..c1f58bd 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5092,6 +5092,21 @@ instantiate_type (lhstype, rhs, complain)
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:
{
explicit_targs = TREE_OPERAND (rhs, 1);
@@ -5101,6 +5116,7 @@ instantiate_type (lhstype, rhs, complain)
my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
case OVERLOAD:
+ overload:
{
tree elem, elems;
@@ -5112,7 +5128,8 @@ instantiate_type (lhstype, rhs, complain)
if (lhstype == error_mark_node)
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));
if (complain)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 4eca6b6..b7b74c0 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1615,14 +1615,15 @@ build_offset_ref (type, name)
int dtor = 0;
/* class templates can come in as TEMPLATE_DECLs here. */
- if (TREE_CODE (name) != IDENTIFIER_NODE)
+ if (TREE_CODE (name) == TEMPLATE_DECL)
return name;
if (type == std_node)
return do_scoped_id (name, 0);
- if (processing_template_decl || uses_template_parms (type))
- return build_min_nt (SCOPE_REF, type, name);
+ if (processing_template_decl || uses_template_parms (type)
+ || TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ return build_min (SCOPE_REF, unknown_type_node, type, name);
/* Handle namespace names fully here. */
if (TREE_CODE (type) == NAMESPACE_DECL)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 785c33b..f394f40 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4560,7 +4560,9 @@ build_unary_op (code, xarg, noconvert)
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);
else if (TREE_CODE (arg) == TREE_LIST)
{
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C
new file mode 100644
index 0000000..3cd9c2b
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C
@@ -0,0 +1,16 @@
+// Build don't run:
+
+class foo
+{
+public:
+ template<class T>
+ T bar() {}
+};
+
+int
+main()
+{
+ foo f;
+
+ int (foo::*s)() = &foo::template bar<int>;
+}