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> 2004-01-25 Mark Mitchell <mark@codesourcery.com>
PR c++/13833 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 /* TYPE is a template class. Don't issue any errors now; wait
until instantiation time to complain. */ 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 /* When processing templates we can't know, in general, whether or
not we're going to have virtual baseclasses. */ not we're going to have virtual baseclasses. */
if (uses_template_parms (fn)) if (processing_template_decl)
return; return;
/* We don't need an in-charge parameter for constructors that don't /* 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); TREE_OPERAND (decl, 0), d1, d2);
} }
if (TREE_READONLY_DECL_P (decl) if (DECL_P (decl)
&& ! TREE_THIS_VOLATILE (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)
&& DECL_INITIAL (decl) != error_mark_node && DECL_INITIAL (decl) != error_mark_node
/* This is invalid if initial value is not constant. /* 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 void
maybe_push_to_top_level (int pseudo) push_to_top_level (void)
{ {
struct saved_scope *s; struct saved_scope *s;
struct cp_binding_level *b; 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 inserted into namespace level, finish_file wouldn't find them
when doing pending instantiations. Therefore, don't stop at when doing pending instantiations. Therefore, don't stop at
namespace level, but continue until :: . */ namespace level, but continue until :: . */
if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms)) if (global_scope_p (b))
break; break;
old_bindings = store_bindings (b->names, old_bindings); old_bindings = store_bindings (b->names, old_bindings);
@ -4751,12 +4751,6 @@ maybe_push_to_top_level (int pseudo)
timevar_pop (TV_NAME_LOOKUP); timevar_pop (TV_NAME_LOOKUP);
} }
void
push_to_top_level (void)
{
maybe_push_to_top_level (0);
}
void void
pop_from_top_level (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 print_binding_level (cxx_scope *);
extern void push_to_top_level (void); extern void push_to_top_level (void);
extern void pop_from_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 pop_everything (void);
extern void keep_next_level (bool); extern void keep_next_level (bool);
extern bool is_ancestor (tree, tree); extern bool is_ancestor (tree, tree);

View File

@ -2909,10 +2909,10 @@ push_template_decl_real (tree decl, int is_friend)
else else
tmpl = DECL_TI_TEMPLATE (decl); tmpl = DECL_TI_TEMPLATE (decl);
if (is_member_template (tmpl) if (DECL_FUNCTION_TEMPLATE_P (tmpl)
&& DECL_FUNCTION_TEMPLATE_P (tmpl)
&& DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
&& DECL_TEMPLATE_SPECIALIZATION (decl)) && DECL_TEMPLATE_SPECIALIZATION (decl)
&& is_member_template (tmpl))
{ {
tree new_tmpl; tree new_tmpl;
@ -4275,11 +4275,7 @@ lookup_template_class (tree d1,
template, template,
complain, /*require_all_args=*/1); complain, /*require_all_args=*/1);
if (arglist == error_mark_node if (arglist == error_mark_node)
|| (!uses_template_parms (INNERMOST_TEMPLATE_ARGS (arglist))
&& check_instantiated_args (template,
INNERMOST_TEMPLATE_ARGS (arglist),
complain)))
/* We were unable to bind the arguments. */ /* We were unable to bind the arguments. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@ -4340,6 +4336,14 @@ lookup_template_class (tree d1,
well. */ well. */
is_partial_instantiation = uses_template_parms (arglist); 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 if (!is_partial_instantiation
&& !PRIMARY_TEMPLATE_P (template) && !PRIMARY_TEMPLATE_P (template)
&& TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL) && 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 int
uses_template_parms (tree t) 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. */ /* Returns true if T depends on any template parameter with level LEVEL. */
@ -5229,7 +5260,7 @@ instantiate_class_template (tree type)
it now. */ it now. */
push_deferring_access_checks (dk_no_deferred); push_deferring_access_checks (dk_no_deferred);
maybe_push_to_top_level (uses_template_parms (type)); push_to_top_level ();
if (t) if (t)
{ {
@ -8959,10 +8990,7 @@ type_unification_real (tree tparms,
if (!TYPE_P (arg)) if (!TYPE_P (arg))
type = TREE_TYPE (arg); type = TREE_TYPE (arg);
else else
{
type = arg; type = arg;
arg = NULL_TREE;
}
if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER) if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
{ {
@ -11767,11 +11795,16 @@ type_dependent_expression_p (tree expression)
(INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
return true; 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_TYPE (expression) == unknown_type_node)
{ {
if (TREE_CODE (expression) == ADDR_EXPR) if (TREE_CODE (expression) == ADDR_EXPR)
return type_dependent_expression_p (TREE_OPERAND (expression, 0)); 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))) if (type_dependent_expression_p (TREE_OPERAND (expression, 0)))
return true; return true;
@ -11847,13 +11880,18 @@ bool
any_dependent_template_arguments_p (tree args) any_dependent_template_arguments_p (tree args)
{ {
int i; int i;
int j;
if (!args) if (!args)
return false; return false;
for (i = 0; i < TREE_VEC_LENGTH (args); ++i) for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (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 true;
}
return false; return false;
} }

View File

@ -2930,14 +2930,8 @@ void
expand_or_defer_fn (tree fn) expand_or_defer_fn (tree fn)
{ {
/* When the parser calls us after finishing the body of a template /* 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 function, we don't really want to expand the body. */
processing an in-class definition of an inline function, if (processing_template_decl)
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))))
{ {
/* Normally, collection only occurs in rest_of_compilation. So, /* Normally, collection only occurs in rest_of_compilation. So,
if we don't collect here, we never collect junk generated 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)) if (TREE_CODE (t1) != TREE_CODE (t2))
return false; return false;
/* Qualifiers must match. */ /* Qualifiers must match. For array types, we will check when we
if (cp_type_quals (t1) != cp_type_quals (t2)) recur on the array element types. */
if (TREE_CODE (t1) != ARRAY_TYPE
&& TYPE_QUALS (t1) != TYPE_QUALS (t2))
return false; return false;
if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
return false; return false;
@ -973,7 +975,8 @@ comptypes (tree t1, tree t2, int strict)
definition. Note that we already checked for equality of the type definition. Note that we already checked for equality of the type
qualifiers (just above). */ 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; return true;
if (!(*targetm.comp_type_attributes) (t1, t2)) if (!(*targetm.comp_type_attributes) (t1, t2))