class.c (add_method): Just check processing_template_decl to determine whether or not we are within a...

* class.c (add_method): Just check processing_template_decl to
	determine whether or not we are within a template.
	* decl2.c (maybe_retrofit_in_chrg): Likewise.
	* init.c (decl_constant_value): Check the type of the declaration,
	not TREE_READONLY.
	* name-lookup.c (maybe_push_to_top_level): Rename to ...
	(push_to_top_level): ... this.
	* name-lookup.h (maybe_push_to_top_level): Do not declare it.
	* pt.c (push_template_decl_real): Reorder condition for speed.
	(convert_template_argument): Use dependency-checking functions in
	place of uses_template_parms.
	(lookup_template_class): Avoid calling uses_template_parms more
	than once.
	(uses_template_parms): Reimplement, using dependency-checking
	functions.
	(instantiate_class_template): Use push_to_top_level, not
	maybe_push_to_top_level.
	(type_unification_real): Simplify.
	(type_dependent_expression_p): Handle OFFSET_REFs and
	TEMPLATE_DECLs.
	(any_dependent_template_arguments_p): Handle multiple levels of
	template argument.
	* semantics.c (expand_or_defer_fn): Do not check
	uses_template_parms for template instantiations.
	* typeck.c (comptypes): Avoid calling cp_type_quals.

From-SVN: r76647
This commit is contained in:
Mark Mitchell 2004-01-26 17:41:50 +00:00 committed by Mark Mitchell
parent d9b7db1265
commit c353b8e3fb
9 changed files with 104 additions and 44 deletions

View File

@ -1,3 +1,31 @@
2004-01-26 Mark Mitchell <mark@codesourcery.com>
* class.c (add_method): Just check processing_template_decl to
determine whether or not we are within a template.
* decl2.c (maybe_retrofit_in_chrg): Likewise.
* init.c (decl_constant_value): Check the type of the declaration,
not TREE_READONLY.
* name-lookup.c (maybe_push_to_top_level): Rename to ...
(push_to_top_level): ... this.
* name-lookup.h (maybe_push_to_top_level): Do not declare it.
* pt.c (push_template_decl_real): Reorder condition for speed.
(convert_template_argument): Use dependency-checking functions in
place of uses_template_parms.
(lookup_template_class): Avoid calling uses_template_parms more
than once.
(uses_template_parms): Reimplement, using dependency-checking
functions.
(instantiate_class_template): Use push_to_top_level, not
maybe_push_to_top_level.
(type_unification_real): Simplify.
(type_dependent_expression_p): Handle OFFSET_REFs and
TEMPLATE_DECLs.
(any_dependent_template_arguments_p): Handle multiple levels of
template argument.
* semantics.c (expand_or_defer_fn): Do not check
uses_template_parms for template instantiations.
* typeck.c (comptypes): Avoid calling cp_type_quals.
2004-01-25 Mark Mitchell <mark@codesourcery.com>
PR c++/13833

View File

@ -866,7 +866,7 @@ add_method (tree type, tree method, int error_p)
}
}
if (template_class_depth (type))
if (processing_template_decl)
/* TYPE is a template class. Don't issue any errors now; wait
until instantiation time to complain. */
;

View File

@ -229,7 +229,7 @@ maybe_retrofit_in_chrg (tree fn)
/* When processing templates we can't know, in general, whether or
not we're going to have virtual baseclasses. */
if (uses_template_parms (fn))
if (processing_template_decl)
return;
/* We don't need an in-charge parameter for constructors that don't

View File

@ -1610,8 +1610,12 @@ decl_constant_value (tree decl)
TREE_OPERAND (decl, 0), d1, d2);
}
if (TREE_READONLY_DECL_P (decl)
&& ! TREE_THIS_VOLATILE (decl)
if (DECL_P (decl)
&& (/* Enumeration constants are constant. */
TREE_CODE (decl) == CONST_DECL
/* And so are variables with a 'const' type -- unless they
are also 'volatile'. */
|| CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
/* This is invalid if initial value is not constant.

View File

@ -4688,7 +4688,7 @@ store_bindings (tree names, cxx_saved_binding *old_bindings)
}
void
maybe_push_to_top_level (int pseudo)
push_to_top_level (void)
{
struct saved_scope *s;
struct cp_binding_level *b;
@ -4723,7 +4723,7 @@ maybe_push_to_top_level (int pseudo)
inserted into namespace level, finish_file wouldn't find them
when doing pending instantiations. Therefore, don't stop at
namespace level, but continue until :: . */
if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms))
if (global_scope_p (b))
break;
old_bindings = store_bindings (b->names, old_bindings);
@ -4751,12 +4751,6 @@ maybe_push_to_top_level (int pseudo)
timevar_pop (TV_NAME_LOOKUP);
}
void
push_to_top_level (void)
{
maybe_push_to_top_level (0);
}
void
pop_from_top_level (void)
{

View File

@ -264,7 +264,6 @@ extern void print_binding_stack (void);
extern void print_binding_level (cxx_scope *);
extern void push_to_top_level (void);
extern void pop_from_top_level (void);
extern void maybe_push_to_top_level (int);
extern void pop_everything (void);
extern void keep_next_level (bool);
extern bool is_ancestor (tree, tree);

View File

@ -2909,10 +2909,10 @@ push_template_decl_real (tree decl, int is_friend)
else
tmpl = DECL_TI_TEMPLATE (decl);
if (is_member_template (tmpl)
&& DECL_FUNCTION_TEMPLATE_P (tmpl)
if (DECL_FUNCTION_TEMPLATE_P (tmpl)
&& DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
&& DECL_TEMPLATE_SPECIALIZATION (decl))
&& DECL_TEMPLATE_SPECIALIZATION (decl)
&& is_member_template (tmpl))
{
tree new_tmpl;
@ -4275,11 +4275,7 @@ lookup_template_class (tree d1,
template,
complain, /*require_all_args=*/1);
if (arglist == error_mark_node
|| (!uses_template_parms (INNERMOST_TEMPLATE_ARGS (arglist))
&& check_instantiated_args (template,
INNERMOST_TEMPLATE_ARGS (arglist),
complain)))
if (arglist == error_mark_node)
/* We were unable to bind the arguments. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@ -4340,6 +4336,14 @@ lookup_template_class (tree d1,
well. */
is_partial_instantiation = uses_template_parms (arglist);
/* If the deduced arguments are invalid, then the binding
failed. */
if (!is_partial_instantiation
&& check_instantiated_args (template,
INNERMOST_TEMPLATE_ARGS (arglist),
complain))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
if (!is_partial_instantiation
&& !PRIMARY_TEMPLATE_P (template)
&& TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
@ -4717,7 +4721,34 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data, htab_t visited)
int
uses_template_parms (tree t)
{
return for_each_template_parm (t, 0, 0, NULL);
bool dependent_p;
int saved_processing_template_decl;
saved_processing_template_decl = processing_template_decl;
if (!saved_processing_template_decl)
processing_template_decl = 1;
if (TYPE_P (t))
dependent_p = dependent_type_p (t);
else if (TREE_CODE (t) == TREE_VEC)
dependent_p = any_dependent_template_arguments_p (t);
else if (TREE_CODE (t) == TREE_LIST)
dependent_p = (uses_template_parms (TREE_VALUE (t))
|| uses_template_parms (TREE_CHAIN (t)));
else if (DECL_P (t)
|| EXPR_P (t)
|| TREE_CODE (t) == TEMPLATE_PARM_INDEX
|| TREE_CODE (t) == OVERLOAD
|| TREE_CODE (t) == BASELINK
|| TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
dependent_p = (type_dependent_expression_p (t)
|| value_dependent_expression_p (t));
else if (t == error_mark_node)
dependent_p = false;
else
abort ();
processing_template_decl = saved_processing_template_decl;
return dependent_p;
}
/* Returns true if T depends on any template parameter with level LEVEL. */
@ -5229,7 +5260,7 @@ instantiate_class_template (tree type)
it now. */
push_deferring_access_checks (dk_no_deferred);
maybe_push_to_top_level (uses_template_parms (type));
push_to_top_level ();
if (t)
{
@ -8952,17 +8983,14 @@ type_unification_real (tree tparms,
corresponds with a function parameter that contains only
non-deducible template parameters and explicitly specified
template parameters. */
if (! uses_template_parms (parm))
if (!uses_template_parms (parm))
{
tree type;
if (!TYPE_P (arg))
type = TREE_TYPE (arg);
else
{
type = arg;
arg = NULL_TREE;
}
type = arg;
if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
{
@ -11767,11 +11795,16 @@ type_dependent_expression_p (tree expression)
(INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
return true;
if (TREE_CODE (expression) == TEMPLATE_DECL
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
return false;
if (TREE_TYPE (expression) == unknown_type_node)
{
if (TREE_CODE (expression) == ADDR_EXPR)
return type_dependent_expression_p (TREE_OPERAND (expression, 0));
if (TREE_CODE (expression) == COMPONENT_REF)
if (TREE_CODE (expression) == COMPONENT_REF
|| TREE_CODE (expression) == OFFSET_REF)
{
if (type_dependent_expression_p (TREE_OPERAND (expression, 0)))
return true;
@ -11847,13 +11880,18 @@ bool
any_dependent_template_arguments_p (tree args)
{
int i;
int j;
if (!args)
return false;
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
{
tree level = TMPL_ARGS_LEVEL (args, i + 1);
for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
if (dependent_template_arg_p (TREE_VEC_ELT (level, j)))
return true;
}
return false;
}

View File

@ -2930,14 +2930,8 @@ void
expand_or_defer_fn (tree fn)
{
/* When the parser calls us after finishing the body of a template
function, we don't really want to expand the body. When we're
processing an in-class definition of an inline function,
PROCESSING_TEMPLATE_DECL will no longer be set here, so we have
to look at the function itself. */
if (processing_template_decl
|| (DECL_LANG_SPECIFIC (fn)
&& DECL_TEMPLATE_INFO (fn)
&& uses_template_parms (DECL_TI_ARGS (fn))))
function, we don't really want to expand the body. */
if (processing_template_decl)
{
/* Normally, collection only occurs in rest_of_compilation. So,
if we don't collect here, we never collect junk generated

View File

@ -963,8 +963,10 @@ comptypes (tree t1, tree t2, int strict)
if (TREE_CODE (t1) != TREE_CODE (t2))
return false;
/* Qualifiers must match. */
if (cp_type_quals (t1) != cp_type_quals (t2))
/* Qualifiers must match. For array types, we will check when we
recur on the array element types. */
if (TREE_CODE (t1) != ARRAY_TYPE
&& TYPE_QUALS (t1) != TYPE_QUALS (t2))
return false;
if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
return false;
@ -973,7 +975,8 @@ comptypes (tree t1, tree t2, int strict)
definition. Note that we already checked for equality of the type
qualifiers (just above). */
if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
if (TREE_CODE (t1) != ARRAY_TYPE
&& TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return true;
if (!(*targetm.comp_type_attributes) (t1, t2))