diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/class.c | 83 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/decl.c | 26 | ||||
-rw-r--r-- | gcc/cp/lex.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/shadow1.C | 19 |
6 files changed, 97 insertions, 70 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b994d6e42e5..6a05c558766 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +1998-12-16 Mark Mitchell <mark@markmitchell.com> + + * class.c (resolve_address_of_overloaded_function): Do conversion + to correct type here, rather than ... + (instantiate_type): Here. + + * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro. + (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it. + (decl_template_parm_p): Remove. + * decl.c (pushdecl): Don't set DECL_CONTEXT for a template + paramter. + * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P. + (push_inline_template_parms_recursive): Set it. + (decl_template_parm_p): Remove. + (check_template_shadow): Use DECL_TEMPLATE_PARM_P. + (process_template_parm): Set it. + Wed Dec 16 16:33:58 1998 Dave Brolley <brolley@cygnus.com> * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e3f4544481b..694ac0b22ba 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5025,6 +5025,7 @@ resolve_address_of_overloaded_function (target_type, are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy interoperability with most_specialized_instantiation. */ tree matches = NULL_TREE; + tree fn; /* By the time we get here, we should be seeing only real pointer-to-member types, not the internal POINTER_TYPE to @@ -5212,8 +5213,20 @@ resolve_address_of_overloaded_function (target_type, return error_mark_node; } - /* Good, exactly one match. */ - return TREE_PURPOSE (matches); + /* Good, exactly one match. Now, convert it to the correct type. */ + fn = TREE_PURPOSE (matches); + + if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type)) + return build_unary_op (ADDR_EXPR, fn, 0); + else + { + /* The target must be a REFERENCE_TYPE. Above, build_unary_op + will mark the function as addressed, but here we must do it + explicitly. */ + mark_addressable (fn); + + return fn; + } } /* This function will instantiate the type of the expression given in @@ -5291,33 +5304,31 @@ instantiate_type (lhstype, rhs, complain) case COMPONENT_REF: { tree field = TREE_OPERAND (rhs, 1); - if (TREE_CODE (field) == TREE_LIST) - { - tree function = instantiate_type (lhstype, field, complain); - if (function == error_mark_node) - return error_mark_node; - my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185); + tree r; + + my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0); - if (! DECL_STATIC_FUNCTION_P (function)) + r = instantiate_type (lhstype, field, complain); + + if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)) + { + tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype); + tree fn = TREE_VALUE (field); + if (TREE_CODE (fn) == OVERLOAD) + fn = OVL_FUNCTION (fn); + if (TREE_CODE (fn) == FUNCTION_DECL) { - tree t = TREE_TYPE (TREE_OPERAND (rhs, 0)); - if (TYPE_MAIN_VARIANT (t) == current_class_type) - t = constructor_name (t); - - cp_error ("object-dependent reference to `%D' can only be used in a call", - function); - cp_error (" to form a pointer to member function, say `&%T::%D'", - t, DECL_NAME (function)); - return error_mark_node; + cp_error ("object-dependent reference `%E' can only be used in a call", + DECL_NAME (fn)); + cp_error (" to form a pointer to member function, say `&%T::%E'", + t, DECL_NAME (fn)); } - - mark_used (function); - return function; + else + cp_error ("object-dependent reference can only be used in a call"); + return error_mark_node; } - - /* I could not trigger this code. MvL */ - my_friendly_abort (980326); - return rhs; + + return r; } case OFFSET_REF: @@ -5469,27 +5480,7 @@ instantiate_type (lhstype, rhs, complain) return rhs; case ADDR_EXPR: - { - tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - if (fn == error_mark_node) - return error_mark_node; - mark_addressable (fn); - TREE_OPERAND (rhs, 0) = fn; - TREE_CONSTANT (rhs) = staticp (fn); - if (TYPE_PTRMEMFUNC_P (lhstype)) - { - /* We must use the POINTER_TYPE to METHOD_TYPE on RHS here - so that build_ptrmemfunc knows that RHS we have is not - already a pointer-to-member constant. Instead, it is - just a ADDR_EXPR over a FUNCTION_DECL. */ - TREE_TYPE (rhs) = TYPE_PTRMEMFUNC_FN_TYPE (lhstype); - rhs = build_ptrmemfunc (TREE_TYPE (rhs), rhs, 0); - } - else - /* Here, things our simple; we have exactly what we need. */ - TREE_TYPE (rhs) = lhstype; - } - return rhs; + return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); case ENTRY_VALUE_EXPR: my_friendly_abort (184); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 395b24a2b40..cb55b0635da 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */ Usage of DECL_LANG_FLAG_?: 0: DECL_ERROR_REPORTED (in VAR_DECL). + DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL) 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). @@ -1832,11 +1833,12 @@ extern int flag_new_for_scope; #define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) #define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE) -/* Nonzero for TEMPLATE_DECL nodes that represents template template - parameters */ +/* Nonzero for a DECL which is actually a template parameter. */ +#define DECL_TEMPLATE_PARM_P(NODE) \ + DECL_LANG_FLAG_0 (NODE) + #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ - (TREE_CODE (NODE) == TEMPLATE_DECL && TREE_TYPE (NODE) \ - && TREE_CODE (TREE_TYPE (NODE)) == TEMPLATE_TEMPLATE_PARM) + (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE)) #define DECL_FUNCTION_TEMPLATE_P(NODE) \ (TREE_CODE (NODE) == TEMPLATE_DECL \ @@ -3070,7 +3072,6 @@ extern void do_pushlevel PROTO((void)); extern int is_member_template PROTO((tree)); extern int template_parms_equal PROTO((tree, tree)); extern int comp_template_parms PROTO((tree, tree)); -extern int decl_template_parm_p PROTO((tree)); extern int template_class_depth PROTO((tree)); extern int is_specialization_of PROTO((tree, tree)); extern int comp_template_args PROTO((tree, tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 356293ab97b..79c38f4323f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3514,15 +3514,23 @@ pushdecl (x) register tree name = DECL_ASSEMBLER_NAME (x); int need_new_binding = 1; - if (current_function_decl && x != current_function_decl - /* A local declaration for a function doesn't constitute nesting. */ - && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x)) - /* Don't change DECL_CONTEXT of virtual methods. */ - && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) - && !DECL_CONTEXT (x)) - DECL_CONTEXT (x) = current_function_decl; - if (!DECL_CONTEXT (x)) - DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); + if (DECL_TEMPLATE_PARM_P (x)) + /* Template parameters have no context; they are not X::T even + when declared within a class or namespace. */ + ; + else + { + if (current_function_decl && x != current_function_decl + /* A local declaration for a function doesn't constitute + nesting. */ + && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x)) + /* Don't change DECL_CONTEXT of virtual methods. */ + && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) + && !DECL_CONTEXT (x)) + DECL_CONTEXT (x) = current_function_decl; + if (!DECL_CONTEXT (x)) + DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); + } /* Type are looked up using the DECL_NAME, as that is what the rest of the compiler wants to use. */ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index e6dd29fe31a..d3b01a94520 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -3051,16 +3051,7 @@ do_identifier (token, parsing, args) cp_error ("enum `%D' is private", id); /* protected is OK, since it's an enum of `this'. */ } - if (!processing_template_decl - /* Really, if we're processing a template, we just want to - resolve template parameters, and not enumeration - constants. But, they're hard to tell apart. (Note that - a non-type template parameter may have enumeration type.) - Fortunately, there's no harm in resolving *global* - enumeration constants, since they can't depend on - template parameters. */ - || (TREE_CODE (CP_DECL_CONTEXT (id)) == NAMESPACE_DECL - && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_PARM_INDEX)) + if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) id = DECL_INITIAL (id); } else diff --git a/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C b/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C new file mode 100644 index 00000000000..dfe99c7b22d --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/shadow1.C @@ -0,0 +1,19 @@ +// Build don't link: + +template <class T> +struct S { + typedef T X; + + class C { + typedef T X; + }; +}; + +template <int I> +struct S2 { + enum { A = I }; + + void f() { + int A; + } +}; |