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:
parent
05c32e169c
commit
50714e797c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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. */
|
||||
|
|
11
gcc/cp/lex.c
11
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue