Commit e1467ff2 by Mark Mitchell Committed by Jason Merrill

call.c (add_template_candidate_real): New function.

	* call.c (add_template_candidate_real): New function.
	(add_template_candidate): Use it.
	(add_template_conv_candidate): Likewise.
	(joust): Pass extra argument to more_specialized.
	* class.c (instantiate_type): Handle a single FUNCTION_DECL.
	(is_local_class): Remove.
	(finish_struct): Check TI_PENDING_SPECIALIZATION_FLAG.
	* cp-tree.h (is_local_class): Remove.
	(perform_array_to_pointer_conversion): Likewise.
	(finish_member_template_decl): Add.
	(check_explicit_specialization): Return a tree, not an int.
	(more_specialized): Take additional argument.
	(get_bindings): Likewise.
	(TI_PENDING_SPECIALIZATION_FLAG): New macro.
	* cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.
	(perform_array_to_pointer_conversion): Remove.
	* decl.c (saved_scope): Add processing_specialization,
	processing_explicit_instantiation fields.
	(maybe_push_to_top_level): Save them.
	(pop_from_top_level): Restore them.
	(grokfndecl): Use new return value from
	check_explicit_specialization.
	(start_decl): Don't check flag_guiding_decls before pushing
	decls.
	(cp_finish_decl): Remove previous (bogus) change.
	(grok_declarator): Use decl_function_context rather than
	is_local_class.
	* decl2.c (finish_file): Pass extra argument to get_bindings.
	(build_expr_from_tree): Let build_x_component_ref check
	validity of arguments rather than doing it here.
	* lex.c (cons_up_default_function): Remove code fooling with
	processing_specialization, processing_explicit_instantiation
	flags, as that is now done in {maybe_push_top,pop_from}_top_level.
	* method.c (build_overload_identifier): Mangle local classes in
	template functions correctly.
	* parse.y (finish_member_template_decl): Move to pt.c.
	* pt.c (finish_member_template_decl): Moved here from parse.y.
	(print_candidates): New function.
	(determine_specialization): Change interface.  Properly look for
	most specialized versions of template candidates.
	(check_explicit_specialization): Fully process explicit
	instantiations.
	(push_template_decl): Avoid looking at CLASSTYPE fields in
	FUNCTION_DECLS.
	(determine_overloaded_function): Remove.
	(convert_nontype_argument): Change name from
	convert_nontype_parameter.  Use determine_overloaded_function
	instead of instantiate_type.
	(mangle_class_name_for_template): Handle type contexts as well as
	function contexts.
	(classtype_mangled_name): Likewise.
	(lookup_template_class): Likewise.
	(tsubst): Likewise.
	(more_specialized): Take explict template arguments as a
	parameter.
	(most_specialized): Likewise.
	(get_bindings): Likewise.  Check that return types match before
	proclaiming a function a match.
	(do_decl_instantiation): Remove code searching for function to
	instantiate; that is now done in check_explicit_specialization.
	(add_maybe_template): Pass extra argument to get_bindings.
	* tree.c (really_overloaded_fn): Use is_overloaded_fn to simplify
	implementation.
	* typeck.c (build_component_ref): Check for invalid arguments.

From-SVN: r17512
parent c3499f00
Tue Jan 27 16:42:21 1998 Mark Mitchell <mmitchell@usa.net>
* call.c (add_template_candidate_real): New function.
(add_template_candidate): Use it.
(add_template_conv_candidate): Likewise.
(joust): Pass extra argument to more_specialized.
* class.c (instantiate_type): Handle a single FUNCTION_DECL.
(is_local_class): Remove.
(finish_struct): Check TI_PENDING_SPECIALIZATION_FLAG.
* cp-tree.h (is_local_class): Remove.
(perform_array_to_pointer_conversion): Likewise.
(finish_member_template_decl): Add.
(check_explicit_specialization): Return a tree, not an int.
(more_specialized): Take additional argument.
(get_bindings): Likewise.
* cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes.
(perform_array_to_pointer_conversion): Remove.
* decl.c (saved_scope): Add processing_specialization,
processing_explicit_instantiation fields.
(maybe_push_to_top_level): Save them.
(pop_from_top_level): Restore them.
(grokfndecl): Use new return value from
check_explicit_specialization.
(start_decl): Don't check flag_guiding_decls before pushing
decls.
(cp_finish_decl): Remove previous (bogus) change.
(grok_declarator): Use decl_function_context rather than
is_local_class.
* decl2.c (finish_file): Pass extra argument to get_bindings.
(build_expr_from_tree): Let build_x_component_ref check
validity of arguments rather than doing it here.
* lex.c (cons_up_default_function): Remove code fooling with
processing_specialization, processing_explicit_instantiation
flags, as that is now done in {maybe_push_top,pop_from}_top_level.
* method.c (build_overload_identifier): Mangle local classes in
template functions correctly.
* parse.y (finish_member_template_decl): Move to pt.c.
* pt.c (finish_member_template_decl): Moved here from parse.y.
(print_candidates): New function.
(determine_specialization): Change interface. Properly look for
most specialized versions of template candidates.
(check_explicit_specialization): Fully process explicit
instantiations.
(push_template_decl): Avoid looking at CLASSTYPE fields in
FUNCTION_DECLS.
(determine_overloaded_function): Remove.
(convert_nontype_argument): Change name from
convert_nontype_parameter. Use determine_overloaded_function
instead of instantiate_type.
(mangle_class_name_for_template): Handle type contexts as well as
function contexts.
(classtype_mangled_name): Likewise.
(lookup_template_class): Likewise.
(tsubst): Likewise.
(more_specialized): Take explict template arguments as a
parameter.
(most_specialized): Likewise.
(get_bindings): Likewise. Check that return types match before
proclaiming a function a match.
(do_decl_instantiation): Remove code searching for function to
instantiate; that is now done in check_explicit_specialization.
(add_maybe_template): Pass extra argument to get_bindings.
* tree.c (really_overloaded_fn): Use is_overloaded_fn to simplify
implementation.
* typeck.c (build_component_ref): Check for invalid arguments.
Tue Jan 27 01:44:02 1998 Jason Merrill <jason@yorick.cygnus.com>
* expr.c (cplus_expand_expr, AGGR_INIT_EXPR): Don't check that
......
......@@ -159,7 +159,7 @@
* The name of a class is now implicitly declared in its own scope; A::A
refers to A.
* Local classes are now supported, though not inside templates.
* Local classes are now supported.
* __attribute__ can now be attached to types as well as declarations.
......
......@@ -4149,20 +4149,25 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
return candidates;
}
/* If TMPL can be successfully instantiated as indicated by
EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES.
TMPL is the template. EXPLICIT_TARGS are any explicit template arguments.
ARGLIST is the arguments provided at the call-site. The RETURN_TYPE
is the desired type for conversion operators. FLAGS are as for
add_function_candidate. */
static struct z_candidate *
add_template_candidate (candidates, tmpl, explicit_targs,
arglist, return_type, flags)
TMPL is the template. EXPLICIT_TARGS are any explicit template
arguments. ARGLIST is the arguments provided at the call-site.
The RETURN_TYPE is the desired type for conversion operators. If
OBJ is NULL_TREE, FLAGS are as for add_function_candidate. If an
OBJ is supplied, FLAGS are ignored, and OBJ is as for
add_conv_candidate. */
static struct z_candidate*
add_template_candidate_real (candidates, tmpl, explicit_targs,
arglist, return_type, flags,
obj)
struct z_candidate *candidates;
tree tmpl, explicit_targs, arglist, return_type;
int flags;
tree obj;
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_scratch_vec (ntparms);
......@@ -4180,35 +4185,58 @@ add_template_candidate (candidates, tmpl, explicit_targs,
if (fn == error_mark_node)
return candidates;
cand = add_function_candidate (candidates, fn, arglist, flags);
cand->template = DECL_TEMPLATE_INFO (fn);
if (obj != NULL_TREE)
/* Aha, this is a conversion function. */
cand = add_conv_candidate (candidates, fn, obj, arglist);
else
cand = add_function_candidate (candidates, fn, arglist, flags);
if (DECL_TI_TEMPLATE (fn) != tmpl)
/* This situation can occur if a member template of a template
class is specialized. Then, instantiate_template might return
an instantiation of the specialization, in which case the
DECL_TI_TEMPLATE field will point at the original
specialization. For example:
template <class T> struct S { template <class U> void f(U);
template <> void f(int) {}; };
S<double> sd;
sd.f(3);
Here, TMPL will be template <class U> S<double>::f(U).
And, instantiate template will give us the specialization
template <> S<double>::f(int). But, the DECL_TI_TEMPLATE field
for this will point at template <class T> template <> S<T>::f(int),
so that we can find the definition. For the purposes of
overload resolution, however, we want the original TMPL. */
cand->template = tree_cons (tmpl, targs, NULL_TREE);
else
cand->template = DECL_TEMPLATE_INFO (fn);
return cand;
}
static struct z_candidate *
add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
add_template_candidate (candidates, tmpl, explicit_targs,
arglist, return_type, flags)
struct z_candidate *candidates;
tree tmpl, obj, arglist, return_type;
tree tmpl, explicit_targs, arglist, return_type;
int flags;
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_scratch_vec (ntparms);
struct z_candidate *cand;
int i;
tree fn;
return
add_template_candidate_real (candidates, tmpl, explicit_targs,
arglist, return_type, flags, NULL_TREE);
}
i = fn_type_unification (tmpl, NULL_TREE, targs, arglist, return_type, 0);
if (i != 0)
return candidates;
fn = instantiate_template (tmpl, targs);
if (fn == error_mark_node)
return candidates;
cand = add_conv_candidate (candidates, fn, obj, arglist);
cand->template = DECL_TEMPLATE_INFO (fn);
return cand;
static struct z_candidate *
add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
struct z_candidate *candidates;
tree tmpl, obj, arglist, return_type;
{
return
add_template_candidate_real (candidates, tmpl, NULL_TREE, arglist,
return_type, 0, obj);
}
......@@ -4360,6 +4388,12 @@ build_user_type_conversion_1 (totype, expr, flags)
ics = implicit_conversion
(totype, TREE_TYPE (TREE_TYPE (fn)), 0, convflags);
else
/* Here, the template conversion operator result must
precisely match the TOTYPE. (FIXME: Actually, we're
supposed to do some simple conversions here; see
[temp.deduct.conv].). If the result of the conversion
operator is not actually TOTYPE, then
add_template_candidate will fail below. */
ics = implicit_conversion (totype, totype, 0, convflags);
if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics))
......@@ -6273,7 +6307,8 @@ joust (cand1, cand2)
return -1;
else if (cand1->template && cand2->template)
winner = more_specialized
(TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template));
(TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
NULL_TREE);
/* or, if not that,
the context is an initialization by user-defined conversion (see
......
......@@ -4504,6 +4504,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
{
tree spec_args;
tree fn;
int pending_specialization;
if (uses_template_parms (t))
/* If t is a template class, and x is a specialization, then x
......@@ -4527,11 +4528,12 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
else
spec_args = DECL_TI_ARGS (fn);
pending_specialization
= TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn));
check_explicit_specialization
(lookup_template_function (DECL_NAME (fn), spec_args),
fn, 0, 1 | (8 * (int) TREE_CHAIN (DECL_TEMPLATE_INFO (fn))));
TREE_CHAIN (DECL_TEMPLATE_INFO (fn)) = NULL_TREE;
fn, 0, 1 | (8 * pending_specialization));
TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn)) = 0;
/* Now, the assembler name will be correct for fn, so we
make its RTL. */
......@@ -5423,6 +5425,16 @@ instantiate_type (lhstype, rhs, complain)
case ERROR_MARK:
return error_mark_node;
case FUNCTION_DECL:
if (!comptypes (lhstype, TREE_TYPE (rhs), 1))
{
if (complain)
cp_error ("%D is not of type %T", rhs, lhstype);
return error_mark_node;
}
else
return rhs;
default:
my_friendly_abort (185);
return error_mark_node;
......@@ -5505,21 +5517,3 @@ build_self_reference ()
pushdecl_class_level (value);
return value;
}
/* Returns non-zero iff the TYPE is a local class; i.e., if it is
declared in a function context, or within a local class. */
int
is_local_class (type)
tree type;
{
if (type == NULL_TREE || TYPE_CONTEXT (type) == NULL_TREE)
return 0;
if (TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
return 1;
return is_local_class (TYPE_CONTEXT (type));
}
......@@ -1098,6 +1098,10 @@ struct lang_decl
#define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE))
#define TI_USES_TEMPLATE_PARMS(NODE) TREE_LANG_FLAG_0 (NODE)
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
/* TI_PENDING_SPECIALIZATION_FLAG on a template-info node indicates
that the template is a specialization of a member template, but
that we don't yet know which one. */
#define TI_PENDING_SPECIALIZATION_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
......@@ -1992,7 +1996,6 @@ extern void maybe_push_cache_obstack PROTO((void));
extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *));
extern tree build_self_reference PROTO((void));
extern void warn_hidden PROTO((tree));
extern int is_local_class PROTO((tree));
/* in cvt.c */
extern tree convert_to_reference PROTO((tree, tree, int, int, tree));
......@@ -2009,7 +2012,6 @@ extern tree build_expr_type_conversion PROTO((int, tree, int));
extern int build_default_binary_type_conversion PROTO((enum tree_code, tree *, tree *));
extern tree type_promotes_to PROTO((tree));
extern tree perform_qualification_conversions PROTO((tree, tree));
extern tree perform_array_to_pointer_conversion PROTO((tree));
/* decl.c */
/* resume_binding_level */
......@@ -2325,6 +2327,7 @@ extern tree tsubst_copy PROTO ((tree, tree, int, tree));
extern tree tsubst_chain PROTO((tree, tree));
extern void begin_member_template_processing PROTO((tree));
extern void end_member_template_processing PROTO((void));
extern tree finish_member_template_decl PROTO((tree, tree));
extern void begin_template_parm_list PROTO((void));
extern void begin_specialization PROTO((void));
extern void reset_specialization PROTO((void));
......@@ -2332,7 +2335,7 @@ extern void end_specialization PROTO((void));
extern void begin_explicit_instantiation PROTO((void));
extern void end_explicit_instantiation PROTO((void));
extern tree determine_specialization PROTO((tree, tree, tree *, int, int));
extern int check_explicit_specialization PROTO((tree, tree, int, int));
extern tree check_explicit_specialization PROTO((tree, tree, int, int));
extern tree process_template_parm PROTO((tree, tree));
extern tree end_template_parm_list PROTO((tree));
extern void end_template_decl PROTO((void));
......@@ -2348,21 +2351,21 @@ extern int fn_type_unification PROTO((tree, tree, tree, tree, t
extern int type_unification PROTO((tree, tree *, tree, tree, tree, int *, int, int));
struct tinst_level *tinst_for_decl PROTO((void));
extern void mark_decl_instantiated PROTO((tree, int));
extern int more_specialized PROTO((tree, tree));
extern int more_specialized PROTO((tree, tree, tree));
extern void mark_class_instantiated PROTO((tree, int));
extern void do_decl_instantiation PROTO((tree, tree, tree));
extern void do_type_instantiation PROTO((tree, tree));
extern tree instantiate_decl PROTO((tree));
extern tree lookup_nested_type_by_name PROTO((tree, tree));
extern tree do_poplevel PROTO((void));
extern tree get_bindings PROTO((tree, tree));
extern tree get_bindings PROTO((tree, tree, tree));
/* CONT ... */
extern void add_tree PROTO((tree));
extern void begin_tree PROTO((void));
extern void end_tree PROTO((void));
extern void add_maybe_template PROTO((tree, tree));
extern void pop_tinst_level PROTO((void));
extern tree most_specialized PROTO((tree, tree));
extern tree most_specialized PROTO((tree, tree, tree));
extern tree most_specialized_class PROTO((tree, tree));
extern int more_specialized_class PROTO((tree, tree));
extern void do_pushlevel PROTO((void));
......
......@@ -1689,127 +1689,17 @@ type_promotes_to (type)
closely. Although they are used only in pt.c at the moment, they
should presumably be used everywhere in the future. */
/* Attempt to perform qualification conversions on EXPR to convert it
to TYPE. Return the resulting expression, or error_mark_node if
the conversion was impossible. */
tree
perform_qualification_conversions (type, expr)
tree type;
tree expr;
{
tree expr_type = TREE_TYPE (expr);
tree t1;
tree t2;
int j;
int all_have_const = 1;
if (comptypes (type, expr_type, 1))
/* The two types are already the same, so there is nothing to do. */
return expr;
j = 0;
t1 = expr_type;
t2 = type;
while (1)
{
if (TREE_CODE (type) != TREE_CODE (expr_type))
return error_mark_node;
if (j > 0
&& TREE_CODE (type) == POINTER_TYPE)
{
if (TYPE_READONLY (t1) > TYPE_READONLY (t2)
|| TYPE_VOLATILE (t1) > TYPE_VOLATILE (t2))
/* For every j>0, if const is in cv1,j the const is in
cv2,j, and similarly for volatile. */
return error_mark_node;
}
if (!all_have_const
&& (TYPE_READONLY (t1) != TYPE_READONLY (t2)
|| TYPE_READONLY (t1) != TYPE_READONLY (t2)))
/* If the cv1,j and cv2,j are different, then const is in every
cv2,k for 0<k<j. */
return error_mark_node;
if (j > 0 && !TYPE_READONLY (t2))
all_have_const = 0;
if (TREE_CODE (type) != POINTER_TYPE)
{
if (j == 0)
/* The two things to be converted weren't even pointer
types. */
return error_mark_node;
if (TYPE_PTRMEMFUNC_P (type))
{
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
}
if (comptypes (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2), 1))
return build1 (NOP_EXPR, type, expr);
else
/* The pointers were not similar. */
return error_mark_node;
}
if (TYPE_PTRMEM_P (type)
&& !comptypes (TYPE_OFFSET_BASETYPE (TREE_TYPE (t1)),
TYPE_OFFSET_BASETYPE (TREE_TYPE (t2)),
1))
/* One type is X::* and the other is Y::*. */
return error_mark_node;
if (TYPE_PTRMEM_P (type))
{
t1 = TREE_TYPE (TREE_TYPE (t1));
t2 = TREE_TYPE (TREE_TYPE (t2));
}
else
{
t1 = TREE_TYPE (t1);
t2 = TREE_TYPE (t2);
}
}
}
/* Perform array-to-pointer conversion on EXPR, if appropriate.
Return the converted expression, or EXPR if no
conversion was performed, or error_mark_node if the conversion was
attempted, but failed. (For example, if an attempt is made to take
the address of a non-addressable object.) */
tree
perform_array_to_pointer_conversion (expr)
tree expr;
{
tree result = expr;
if (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE)
{
tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
/* This section is copied from decay_conversion. */
if (TREE_CODE (expr) == VAR_DECL)
{
/* ??? This is not really quite correct
in that the type of the operand of ADDR_EXPR
is not the target type of the type of the ADDR_EXPR itself.
Question is, can this lossage be avoided? */
result = build1 (ADDR_EXPR, type, expr);
if (mark_addressable (expr) == 0)
return error_mark_node;
TREE_CONSTANT (result) = staticp (expr);
TREE_SIDE_EFFECTS (result) = 0; /* Default would be, same as
EXPR. */
}
else
/* This way is better for a COMPONENT_REF since it can
simplify the offset for a component. */
result = build_unary_op (ADDR_EXPR, expr, 1);
}
return result;
if (comp_ptr_ttypes (type, TREE_TYPE(expr)))
return build1 (NOP_EXPR, type, expr);
else
return error_mark_node;
}
......@@ -1835,6 +1835,8 @@ struct saved_scope {
tree template_parms;
HOST_WIDE_INT processing_template_decl;
tree previous_class_type, previous_class_values;
int processing_specialization;
int processing_explicit_instantiation;
};
static struct saved_scope *current_saved_scope;
......@@ -1933,6 +1935,8 @@ maybe_push_to_top_level (pseudo)
s->processing_template_decl = processing_template_decl;
s->previous_class_type = previous_class_type;
s->previous_class_values = previous_class_values;
s->processing_specialization = processing_specialization;
s->processing_explicit_instantiation = processing_explicit_instantiation;
current_class_name = current_class_type = NULL_TREE;
current_function_decl = NULL_TREE;
......@@ -1945,6 +1949,8 @@ maybe_push_to_top_level (pseudo)
named_labels = NULL_TREE;
minimal_parse_mode = 0;
previous_class_type = previous_class_values = NULL_TREE;
processing_specialization = 0;
processing_explicit_instantiation = 0;
if (!pseudo)
{
current_template_parms = NULL_TREE;
......@@ -2011,6 +2017,8 @@ pop_from_top_level ()
processing_template_decl = s->processing_template_decl;
previous_class_type = s->previous_class_type;
previous_class_values = s->previous_class_values;
processing_specialization = s->processing_specialization;
processing_explicit_instantiation = s->processing_explicit_instantiation;
free (s);
......@@ -6144,8 +6152,7 @@ start_decl (declarator, declspecs, initialized)
/* The declaration of template specializations does not affect
the functions available for overload resolution, so we do not
call pushdecl. */
|| (!flag_guiding_decls
&& TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_TEMPLATE_SPECIALIZATION (decl)))
tem = decl;
else
......@@ -6487,6 +6494,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl))
{
tree stmt = DECL_VINDEX (decl);
/* If the decl is declaring a member of a local class (in a
template function), there will be no associated stmt. */
if (stmt != NULL_TREE)
{
DECL_VINDEX (decl) = NULL_TREE;
......@@ -6778,11 +6787,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|| TREE_CODE (decl) == RESULT_DECL)
{
/* ??? FIXME: What about nested classes? */
/* We check for FUNCTION_DECL here so that member functions of
local classes, which will have internal linkage, are not
given bizarre names by make_decl_rtl. */
int toplev = toplevel_bindings_p () || pseudo_global_level_p ()
|| TREE_CODE (decl) == FUNCTION_DECL;
int toplev = toplevel_bindings_p () || pseudo_global_level_p ();
int was_temp
= (TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (type)
&& allocation_temporary_p ());
......@@ -7491,10 +7496,10 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
grokclassfn (ctype, declarator, decl, flags, quals);
check_explicit_specialization (orig_declarator, decl,
template_count,
funcdef_flag ? 2 :
(friendp ? 3 : 0));
decl = check_explicit_specialization (orig_declarator, decl,
template_count,
funcdef_flag ? 2 :
(friendp ? 3 : 0));
if (check)
{
......@@ -7538,10 +7543,10 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (ctype != NULL_TREE)
grokclassfn (ctype, cname, decl, flags, quals);
check_explicit_specialization (orig_declarator, decl,
template_count,
funcdef_flag ? 2 :
(friendp ? 3 : 0));
decl = check_explicit_specialization (orig_declarator, decl,
template_count,
funcdef_flag ? 2 :
(friendp ? 3 : 0));
if (ctype != NULL_TREE && check)
{
......@@ -9666,6 +9671,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
int publicp = 0;
tree function_context;
/* We catch the others as conflicts with the builtin
typedefs. */
......@@ -9715,7 +9721,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
publicp = (! friendp || ! staticp) && !is_local_class (ctype);
function_context = (ctype != NULL_TREE) ?
hack_decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
publicp = (! friendp || ! staticp)
&& function_context == NULL_TREE;
decl = grokfndecl (ctype, type,
TREE_CODE (declarator) != TEMPLATE_ID_EXPR
? declarator : dname,
......@@ -9725,6 +9734,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
funcdef_flag, template_count);
if (decl == NULL_TREE)
return NULL_TREE;
if (function_context != NULL_TREE
&& DECL_THIS_INLINE (function_context)
&& TREE_PUBLIC (function_context))
/* We just declared a member of a local class in an
extern inline function. Give such an entity comdat
linkage. */
{
comdat_linkage (decl);
DECL_INTERFACE_KNOWN (decl) = 1;
}
#if 0
/* This clobbers the attrs stored in `decl' from `attrlist'. */
/* The decl and setting of decl_machine_attr is also turned off. */
......@@ -12494,7 +12513,7 @@ finish_function (lineno, call_poplevel, nested)
can_reach_end = 0;
if (DECL_CONTEXT (fndecl) != NULL_TREE
&& is_local_class (DECL_CONTEXT (fndecl)))
&& hack_decl_function_context (fndecl))
/* Trick rest_of_compilation into not deferring output of this
function, even if it is inline, since the rtl_obstack for
this function is the function_obstack of the enclosing
......
......@@ -2940,7 +2940,7 @@ finish_file ()
continue;
fn = TREE_PURPOSE (fnname);
args = get_bindings (fn, decl);
args = get_bindings (fn, decl, NULL_TREE);
fn = instantiate_template (fn, args);
instantiate_decl (fn);
}
......@@ -3605,21 +3605,10 @@ build_expr_from_tree (t)
}
case COMPONENT_REF:
{
tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
if (object != NULL_TREE
&& TREE_CODE (object) == TEMPLATE_DECL)
{
cp_error ("invalid use of %D", object);
object = error_mark_node;
}
return build_x_component_ref
(object,
TREE_OPERAND (t, 1), NULL_TREE, 1);
}
return build_x_component_ref
(build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1), NULL_TREE, 1);
case THROW_EXPR:
return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
......
......@@ -1661,7 +1661,7 @@ fndecl_as_string (fndecl, print_ret_type_p)
return decl_as_string (fndecl, print_ret_type_p);
}
/* Same, but handtype a _TYPE.
/* Same, but handle a _TYPE.
Called from convert_to_reference, mangle_class_name_for_template,
build_unary_op, and GNU_xref_decl. */
......
......@@ -1998,22 +1998,10 @@ cons_up_default_function (type, full_name, kind)
{
tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
int saved_processing_specialization;
int saved_processing_explicit_instantiation;
if (retref)
declarator = build_parse_node (ADDR_EXPR, declarator);
/* The following is in case we're generating the default
implementation in the midst of handling a specialization. */
saved_processing_specialization = processing_specialization;
saved_processing_explicit_instantiation =
processing_explicit_instantiation;
processing_specialization = 0;
processing_explicit_instantiation = 0;
fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
processing_specialization = saved_processing_specialization;
processing_explicit_instantiation =
saved_processing_explicit_instantiation;
}
if (fn == void_type_node)
......
......@@ -758,7 +758,10 @@ build_overload_identifier (name)
if (TREE_CODE (name) == TYPE_DECL
&& IS_AGGR_TYPE (TREE_TYPE (name))
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))))
&& (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
|| (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
(TREE_TYPE (name))))
== FUNCTION_DECL)))
{
tree template, parmlist, arglist, tname;
template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -78,7 +78,6 @@ static int processing_template_arg;
extern int arg_looking_for_template;
static tree empty_parms PROTO((void));
static tree finish_member_template_decl PROTO((tree, tree));
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */
int have_extern_spec;
......@@ -101,31 +100,6 @@ empty_parms ()
return parms;
}
static tree
finish_member_template_decl (template_arguments, decl)
tree template_arguments;
tree decl;
{
if (template_arguments)
end_template_decl();
else
end_specialization();
if (decl && DECL_TEMPLATE_INFO (decl) &&
!DECL_TEMPLATE_SPECIALIZATION (decl))
{
check_member_template (DECL_TI_TEMPLATE (decl));
return DECL_TI_TEMPLATE (decl);
}
if (decl)
return decl;
cp_error ("invalid member template declaration");
return NULL_TREE;
}
%}
%start program
......
......@@ -1316,16 +1316,8 @@ int
really_overloaded_fn (x)
tree x;
{
if (TREE_CODE (x) == TEMPLATE_ID_EXPR
|| DECL_FUNCTION_TEMPLATE_P (x))
return 1;
if (TREE_CODE (x) == TREE_LIST
&& (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
|| DECL_FUNCTION_TEMPLATE_P (TREE_VALUE (x))))
return 1;
return 0;
return TREE_CODE (x) != FUNCTION_DECL
&& is_overloaded_fn (x);
}
tree
......
......@@ -1823,6 +1823,11 @@ build_component_ref (datum, component, basetype_path, protect)
build_component_ref (TREE_OPERAND (datum, 2), component,
basetype_path, protect));
case TEMPLATE_DECL:
cp_error ("invalid use of %D", datum);
datum = error_mark_node;
break;
default:
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment