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> Wed Dec 16 16:33:58 1998 Dave Brolley <brolley@cygnus.com>
* lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus * 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 are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
interoperability with most_specialized_instantiation. */ interoperability with most_specialized_instantiation. */
tree matches = NULL_TREE; tree matches = NULL_TREE;
tree fn;
/* By the time we get here, we should be seeing only real /* By the time we get here, we should be seeing only real
pointer-to-member types, not the internal POINTER_TYPE to 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; return error_mark_node;
} }
/* Good, exactly one match. */ /* Good, exactly one match. Now, convert it to the correct type. */
return TREE_PURPOSE (matches); 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 /* This function will instantiate the type of the expression given in
@ -5291,33 +5304,31 @@ instantiate_type (lhstype, rhs, complain)
case COMPONENT_REF: case COMPONENT_REF:
{ {
tree field = TREE_OPERAND (rhs, 1); 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); tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
if (function == error_mark_node) tree fn = TREE_VALUE (field);
return error_mark_node; if (TREE_CODE (fn) == OVERLOAD)
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185); fn = OVL_FUNCTION (fn);
if (TREE_CODE (fn) == FUNCTION_DECL)
if (! DECL_STATIC_FUNCTION_P (function))
{ {
tree t = TREE_TYPE (TREE_OPERAND (rhs, 0)); cp_error ("object-dependent reference `%E' can only be used in a call",
if (TYPE_MAIN_VARIANT (t) == current_class_type) DECL_NAME (fn));
t = constructor_name (t); cp_error (" to form a pointer to member function, say `&%T::%E'",
t, DECL_NAME (fn));
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;
} }
else
mark_used (function); cp_error ("object-dependent reference can only be used in a call");
return function; return error_mark_node;
} }
/* I could not trigger this code. MvL */ return r;
my_friendly_abort (980326);
return rhs;
} }
case OFFSET_REF: case OFFSET_REF:
@ -5469,27 +5480,7 @@ instantiate_type (lhstype, rhs, complain)
return rhs; return rhs;
case ADDR_EXPR: case ADDR_EXPR:
{ return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
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;
case ENTRY_VALUE_EXPR: case ENTRY_VALUE_EXPR:
my_friendly_abort (184); my_friendly_abort (184);

View File

@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */
Usage of DECL_LANG_FLAG_?: Usage of DECL_LANG_FLAG_?:
0: DECL_ERROR_REPORTED (in VAR_DECL). 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). 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
2: DECL_THIS_EXTERN (in VAR_DECL or 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_SPECIALIZATIONS(NODE) DECL_SIZE(NODE)
#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE) #define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE)
/* Nonzero for TEMPLATE_DECL nodes that represents template template /* Nonzero for a DECL which is actually a template parameter. */
parameters */ #define DECL_TEMPLATE_PARM_P(NODE) \
DECL_LANG_FLAG_0 (NODE)
#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL && TREE_TYPE (NODE) \ (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
&& TREE_CODE (TREE_TYPE (NODE)) == TEMPLATE_TEMPLATE_PARM)
#define DECL_FUNCTION_TEMPLATE_P(NODE) \ #define DECL_FUNCTION_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \ (TREE_CODE (NODE) == TEMPLATE_DECL \
@ -3070,7 +3072,6 @@ extern void do_pushlevel PROTO((void));
extern int is_member_template PROTO((tree)); extern int is_member_template PROTO((tree));
extern int template_parms_equal PROTO((tree, tree)); extern int template_parms_equal PROTO((tree, tree));
extern int comp_template_parms 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 template_class_depth PROTO((tree));
extern int is_specialization_of PROTO((tree, tree)); extern int is_specialization_of PROTO((tree, tree));
extern int comp_template_args 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); register tree name = DECL_ASSEMBLER_NAME (x);
int need_new_binding = 1; int need_new_binding = 1;
if (current_function_decl && x != current_function_decl if (DECL_TEMPLATE_PARM_P (x))
/* A local declaration for a function doesn't constitute nesting. */ /* Template parameters have no context; they are not X::T even
&& (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x)) when declared within a class or namespace. */
/* Don't change DECL_CONTEXT of virtual methods. */ ;
&& (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) else
&& !DECL_CONTEXT (x)) {
DECL_CONTEXT (x) = current_function_decl; if (current_function_decl && x != current_function_decl
if (!DECL_CONTEXT (x)) /* A local declaration for a function doesn't constitute
DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); 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 /* Type are looked up using the DECL_NAME, as that is what the rest of the
compiler wants to use. */ compiler wants to use. */

View File

@ -3051,16 +3051,7 @@ do_identifier (token, parsing, args)
cp_error ("enum `%D' is private", id); cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */ /* protected is OK, since it's an enum of `this'. */
} }
if (!processing_template_decl if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
/* 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))
id = DECL_INITIAL (id); id = DECL_INITIAL (id);
} }
else 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;
}
};