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:
parent
d9b7db1265
commit
c353b8e3fb
@ -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
|
||||||
|
@ -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. */
|
||||||
;
|
;
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
70
gcc/cp/pt.c
70
gcc/cp/pt.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user