diff options
author | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-06-07 12:13:54 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-06-07 12:13:54 +0000 |
commit | 874503bcad9c38fb673b43bcdc09e6d4658fe62a (patch) | |
tree | 6c03d69c022263d9aa94cd9a9e6ae9a38cde6cfb /gcc | |
parent | dfdfa60f540afcfb54a599ce9a59770225d11ce6 (diff) | |
download | gcc-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.c | 19 | ||||
-rw-r--r-- | gcc/cp/init.c | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ptrmem1.C | 16 |
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>; +} |