class.c (resolve_address_of_overloaded_function): Do conversion to correct type here, rather than ...

* 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.

From-SVN: r24344
This commit is contained in:
Mark Mitchell 1998-12-16 15:51:21 +00:00 committed by Mark Mitchell
parent 05c32e169c
commit 50714e797c
6 changed files with 97 additions and 70 deletions

View File

@ -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

View File

@ -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 r;
my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0);
r = instantiate_type (lhstype, field, complain);
if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
{
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);
if (! DECL_STATIC_FUNCTION_P (function))
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);

View File

@ -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));

View File

@ -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. */

View File

@ -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

View File

@ -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;
}
};