#include "config.h"
#include "system.h"
#include "obstack.h"
-
#include "tree.h"
#include "flags.h"
#include "cp-tree.h"
+#include "tree-inline.h"
#include "decl.h"
#include "parse.h"
#include "lex.h"
(for a function or static data member), or a TYPE (for a class)
indicating what we are hoping to instantiate. */
static tree pending_templates;
-static tree *template_tail = &pending_templates;
-
-static tree maybe_templates;
-static tree *maybe_template_tail = &maybe_templates;
+static tree last_pending_template;
int processing_template_parmlist;
static int template_header_count;
#define UNIFY_ALLOW_OUTER_LEVEL 16
#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
+#define UNIFY_ALLOW_MAX_CORRECTION 128
#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
virtual, or a base class of a virtual
static void regenerate_decl_from_template PARAMS ((tree, tree));
static tree most_specialized PARAMS ((tree, tree, tree));
static tree most_specialized_class PARAMS ((tree, tree));
-static void set_mangled_name_for_template_decl PARAMS ((tree));
static int template_class_depth_real PARAMS ((tree, int));
static tree tsubst_aggr_type PARAMS ((tree, tree, int, tree, int));
static tree tsubst_decl PARAMS ((tree, tree, tree));
init_pt ()
{
ggc_add_tree_root (&pending_templates, 1);
- ggc_add_tree_root (&maybe_templates, 1);
ggc_add_tree_root (&saved_trees, 1);
ggc_add_tree_root (¤t_tinst_level, 1);
}
/* This is just an ordinary non-member function. Nothing can
be a specialization of that. */
continue;
+ else if (DECL_ARTIFICIAL (fn))
+ /* Cannot specialize functions that are created implicitly. */
+ continue;
else
{
tree decl_arg_types;
Here, S<int>::f is a non-template, but S<int> is a
template class. If FN has the same type as DECL, we
might be in business. */
+
+ if (!DECL_TEMPLATE_INFO (fn))
+ /* Its enclosing class is an explicit specialization
+ of a template class. This is not a candidate. */
+ continue;
+
if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
TREE_TYPE (TREE_TYPE (fn))))
/* The return types differ. */
TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
- /* Mangle the function name appropriately. Note that we do
- not mangle specializations of non-template member
- functions of template classes, e.g. with
-
- template <class T> struct S { void f(); }
-
- and given the specialization
-
- template <> void S<int>::f() {}
-
- we do not mangle S<int>::f() here. That's because it's
- just an ordinary member function and doesn't need special
- treatment. We do this here so that the ordinary,
- non-template, name-mangling algorithm will not be used
- later. */
- if ((is_member_template (tmpl) || ctype == NULL_TREE)
- && name_mangling_version >= 1)
- set_mangled_name_for_template_decl (decl);
-
if (is_friend && !have_def)
/* This is not really a declaration of a specialization.
It's just the name of an instantiation. But, it's not
my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
/* is a const-param */
parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
- PARM, 0, NULL_TREE);
+ PARM, 0, NULL);
/* [temp.param]
/* Figure out what error message to issue. */
if (TREE_CODE (decl) == FUNCTION_DECL)
- msg = "default argument for template parameter in function template `%D'";
+ msg = "default template arguments may not be used in function templates";
else if (is_partial)
- msg = "default argument in partial specialization `%D'";
+ msg = "default template arguments may not be used in partial specializations";
else
msg = "default argument for template parameter for class enclosing `%D'";
}
else if (INTEGRAL_TYPE_P (expr_type)
|| TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type)
- /* The next two are g++ extensions. */
- || TREE_CODE (expr_type) == REAL_TYPE
- || TREE_CODE (expr_type) == COMPLEX_TYPE)
+ || TYPE_PTRMEMFUNC_P (expr_type))
{
if (! TREE_CONSTANT (expr))
{
return expr;
- case REAL_TYPE:
- case COMPLEX_TYPE:
- /* These are g++ extensions. */
- if (TREE_CODE (expr_type) != TREE_CODE (type))
- return error_mark_node;
-
- expr = digest_init (type, expr, (tree*) 0);
-
- if (TREE_CODE (expr) != REAL_CST)
- goto non_constant;
-
- return expr;
-
case POINTER_TYPE:
{
tree type_pointed_to = TREE_TYPE (type);
tree t = no_linkage_check (val);
if (t)
{
- if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
+ if (TYPE_ANONYMOUS_P (t))
cp_pedwarn
("template-argument `%T' uses anonymous type", val);
else
tree ti = (TYPE_P (d)
? CLASSTYPE_TEMPLATE_INFO (d)
: DECL_TEMPLATE_INFO (d));
+ tree pt;
int level;
if (TI_PENDING_TEMPLATE_FLAG (ti))
if (level)
push_tinst_level (d);
- *template_tail = tree_cons (current_tinst_level, d, NULL_TREE);
- template_tail = &TREE_CHAIN (*template_tail);
+ pt = tree_cons (current_tinst_level, d, NULL_TREE);
+ if (last_pending_template)
+ TREE_CHAIN (last_pending_template) = pt;
+ else
+ pending_templates = pt;
+
+ last_pending_template = pt;
+
TI_PENDING_TEMPLATE_FLAG (ti) = 1;
if (level)
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
+ /* Consider an example where a template template parameter declared as
+
+ template <class T, class U = std::allocator<T> > class TT
+
+ The template parameter level of T and U are one level larger than
+ of TT. To proper process the default argument of U, say when an
+ instantiation `TT<int>' is seen, we need to build the full
+ arguments containing {int} as the innermost level. Outer levels
+ can be obtained from `current_template_args ()'. */
+
+ if (processing_template_decl)
+ arglist = add_to_template_args (current_template_args (), arglist);
+
arglist2 = coerce_template_parms (parmlist, arglist, template,
complain, /*require_all_args=*/1);
if (arglist2 == error_mark_node)
return error_mark_node;
- parm = copy_template_template_parm (TREE_TYPE (template), arglist2);
- TYPE_SIZE (parm) = 0;
+ parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
return parm;
}
else
is set up. */
if (TREE_CODE (t) != ENUMERAL_TYPE)
DECL_NAME (type_decl) = classtype_mangled_name (t);
- DECL_ASSEMBLER_NAME (type_decl) = DECL_NAME (type_decl);
if (!is_partial_instantiation)
{
- DECL_ASSEMBLER_NAME (type_decl) = mangle_decl (type_decl);
-
/* For backwards compatibility; code that uses
-fexternal-templates expects looking up a template to
instantiate it. I think DDD still relies on this.
= DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (decl));
}
- /* The mangled name for the NEW_FRIEND is incorrect. The call to
- tsubst will have resulted in a call to
- set_mangled_name_for_template_decl. But, the function is not a
- template instantiation and should not be mangled like one.
- Therefore, we remangle the function name. We don't have to do
- this if the NEW_FRIEND is a template since
- set_mangled_name_for_template_decl doesn't do anything if the
- function declaration still uses template arguments. */
+ /* The mangled name for the NEW_FRIEND is incorrect. The function
+ is not a template instantiation and should not be mangled like
+ one. Therefore, we forget the mangling here; we'll recompute it
+ later if we need it. */
if (TREE_CODE (new_friend) != TEMPLATE_DECL)
{
- set_mangled_name_for_decl (new_friend);
- DECL_RTL (new_friend) = 0;
- make_decl_rtl (new_friend, NULL_PTR);
+ SET_DECL_RTL (new_friend, NULL_RTX);
+ SET_DECL_ASSEMBLER_NAME (new_friend, NULL_TREE);
}
if (DECL_NAMESPACE_SCOPE_P (new_friend))
{
CLASSTYPE_INTERFACE_ONLY (type) = interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown);
- CLASSTYPE_VTABLE_NEEDS_WRITING (type)
- = (! CLASSTYPE_INTERFACE_ONLY (type)
- && CLASSTYPE_INTERFACE_KNOWN (type));
}
else
{
CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(type, CLASSTYPE_INTERFACE_UNKNOWN (pattern));
- CLASSTYPE_VTABLE_NEEDS_WRITING (type)
- = (! CLASSTYPE_INTERFACE_ONLY (type)
- && CLASSTYPE_INTERFACE_KNOWN (type));
}
}
else
{
SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
- CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
}
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
- TYPE_VEC_DELETE_TAKES_SIZE (type) = TYPE_VEC_DELETE_TAKES_SIZE (pattern);
TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern);
TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);
TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern);
maybe_fold_nontype_arg (arg)
tree arg;
{
- /* If we're not in a template, ARG is already as simple as it's going to
- get, and trying to reprocess the trees will break. */
- if (! processing_template_decl)
- return arg;
-
- if (!TYPE_P (arg) && !uses_template_parms (arg))
+ if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
{
/* Sometimes, one of the args was an expression involving a
template constant parameter, like N - 1. Now that we've
fool build_expr_from_tree() into building an actual
tree. */
- int saved_processing_template_decl = processing_template_decl;
- processing_template_decl = 0;
- arg = fold (build_expr_from_tree (arg));
- processing_template_decl = saved_processing_template_decl;
+ /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
+ as simple as it's going to get, and trying to reprocess
+ the trees will break. */
+ if (!TREE_TYPE (arg))
+ {
+ int saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ arg = build_expr_from_tree (arg);
+ processing_template_decl = saved_processing_template_decl;
+ }
+
+ arg = fold (arg);
}
return arg;
}
TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), i));
TREE_VEC_ELT (new_vec, i)
- = build_tree_list (tsubst (default_value, args, complain,
- NULL_TREE),
+ = build_tree_list (maybe_fold_nontype_arg (
+ tsubst_expr (default_value, args, complain,
+ NULL_TREE)),
tsubst (parm_decl, args, complain,
NULL_TREE));
}
r = copy_decl (t);
DECL_USE_TEMPLATE (r) = 0;
TREE_TYPE (r) = type;
+ /* Clear out the mangled name and RTL for the instantiation. */
+ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
+ SET_DECL_RTL (r, NULL_RTX);
DECL_CONTEXT (r) = ctx;
DECL_VIRTUAL_CONTEXT (r)
TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
}
- /* Set up the DECL_TEMPLATE_INFO for R and compute its mangled
- name. There's no need to do this in the special friend
- case mentioned above where GEN_TMPL is NULL. */
+ /* Set up the DECL_TEMPLATE_INFO for R. There's no need to do
+ this in the special friend case mentioned above where
+ GEN_TMPL is NULL. */
if (gen_tmpl)
{
DECL_TEMPLATE_INFO (r)
SET_DECL_IMPLICIT_INSTANTIATION (r);
register_specialization (r, gen_tmpl, argvec);
- /* Set the mangled name for R. */
- if (DECL_DESTRUCTOR_P (t))
- set_mangled_name_for_decl (r);
- else
- {
- /* Instantiations of template functions must be mangled
- specially, in order to conform to 14.5.5.1
- [temp.over.link]. */
- tree tmpl = DECL_TI_TEMPLATE (t);
-
- /* TMPL will be NULL if this is a specialization of a
- member function of a template class. */
- if (name_mangling_version < 1
- || tmpl == NULL_TREE
- || (member && !is_member_template (tmpl)
- && !DECL_TEMPLATE_INFO (tmpl)))
- set_mangled_name_for_decl (r);
- else
- set_mangled_name_for_template_decl (r);
- }
-
- DECL_RTL (r) = 0;
- make_decl_rtl (r, NULL_PTR);
-
- /* Like grokfndecl. If we don't do this, pushdecl will
- mess up our TREE_CHAIN because it doesn't find a
- previous decl. Sigh. */
- if (member
- && ! uses_template_parms (r)
- && (IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r))
- == NULL_TREE))
- SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r);
-
/* We're not supposed to instantiate default arguments
until they are called, for a template. But, for a
declaration like:
DECL_CONTEXT (r) = NULL_TREE;
if (PROMOTE_PROTOTYPES
- && (TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
+ && INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
DECL_ARG_TYPE (r) = integer_type_node;
if (TREE_CHAIN (t))
DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
/*complain=*/1, in_decl);
TREE_CHAIN (r) = NULL_TREE;
- if (TREE_CODE (type) == VOID_TYPE)
- cp_error_at ("instantiation of `%D' as type void", r);
+ if (VOID_TYPE_P (type))
+ cp_error_at ("instantiation of `%D' as type `%T'", r, type);
}
break;
ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
/*complain=*/1,
in_decl, /*entering_scope=*/1);
+ else if (DECL_NAMESPACE_SCOPE_P (t))
+ ctx = DECL_CONTEXT (t);
else
{
/* Subsequent calls to pushdecl will fill this in. */
ctx = NULL_TREE;
- if (!DECL_NAMESPACE_SCOPE_P (t))
- local_p = 1;
+ local_p = 1;
}
/* Check to see if we already have this specialization. */
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
DECL_CONTEXT (r) = ctx;
+ /* Clear out the mangled name and RTL for the instantiation. */
+ SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
+ SET_DECL_RTL (r, NULL_RTX);
/* Don't try to expand the initializer until someone tries to use
this variable; otherwise we run into circular dependencies. */
DECL_INITIAL (r) = NULL_TREE;
- DECL_RTL (r) = 0;
+ SET_DECL_RTL (r, NULL_RTX);
DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
/* For __PRETTY_FUNCTION__ we have to adjust the initializer. */
if (DECL_PRETTY_FUNCTION_P (r))
{
- DECL_INITIAL (r) = tsubst (DECL_INITIAL (t),
- args,
- /*complain=*/1,
- NULL_TREE);
+ const char *const name = (*decl_printable_name)
+ (current_function_decl, 2);
+ DECL_INITIAL (r) = cp_fname_init (name);
TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
}
register_local_specialization (r, t);
TREE_CHAIN (r) = NULL_TREE;
- if (TREE_CODE (r) == VAR_DECL && TREE_CODE (type) == VOID_TYPE)
- cp_error_at ("instantiation of `%D' as type void", r);
+ if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
+ cp_error_at ("instantiation of `%D' as type `%T'", r, type);
}
break;
case ERROR_MARK:
case IDENTIFIER_NODE:
- case OP_IDENTIFIER:
case VOID_TYPE:
case REAL_TYPE:
case COMPLEX_TYPE:
}
else
{
- r = copy_node (t);
+ r = copy_type (t);
TEMPLATE_TYPE_PARM_INDEX (r)
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
r, levels);
return TREE_TYPE (e1);
}
- case FUNCTION_NAME:
- {
- const char *name;
- int len;
- tree type;
- tree str;
-
- /* This code should match declare_hidden_char_array in
- c-common.c. */
- name = (*decl_printable_name) (current_function_decl, 2);
- len = strlen (name) + 1;
- type = build_array_type (char_type_node,
- build_index_type (size_int (len)));
- str = build_string (len, name);
- TREE_TYPE (str) = type;
- return str;
- }
-
default:
sorry ("use of `%s' in template",
tree_code_name [(int) TREE_CODE (t)]);
case LOOKUP_EXPR:
{
- /* We must tsbust into a LOOKUP_EXPR in case the names to
+ /* We must tsubst into a LOOKUP_EXPR in case the names to
which it refers is a conversion operator; in that case the
name will change. We avoid making unnecessary copies,
however. */
in_decl),
tsubst (TREE_TYPE (t), args, complain, in_decl));
- case FUNCTION_NAME:
- return tsubst (t, args, complain, in_decl);
-
default:
return t;
}
int complain;
tree in_decl;
{
- tree stmt;
+ tree stmt, tmp;
if (t == NULL_TREE || t == error_mark_node)
return t;
if (processing_template_decl)
return tsubst_copy (t, args, complain, in_decl);
+ if (!statement_code_p (TREE_CODE (t)))
+ return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+
switch (TREE_CODE (t))
{
case RETURN_INIT:
finish_named_return_value
(TREE_OPERAND (t, 0),
tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl));
- tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
break;
case CTOR_INITIALIZER:
base_init_list
= tsubst_initializer_list (TREE_OPERAND (t, 1), args);
setup_vtbl_ptr (member_init_list, base_init_list);
- tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
break;
}
args, complain, in_decl));
break;
+ case USING_STMT:
+ prep_stmt (t);
+ do_using_directive (tsubst_expr (USING_STMT_NAMESPACE (t),
+ args, complain, in_decl));
+ break;
+
case DECL_STMT:
{
tree decl;
decl = DECL_STMT_DECL (t);
if (TREE_CODE (decl) == LABEL_DECL)
finish_label_decl (DECL_NAME (decl));
+ else if (TREE_CODE (decl) == USING_DECL)
+ {
+ tree scope = DECL_INITIAL (decl);
+ tree name = DECL_NAME (decl);
+
+ scope = tsubst_expr (scope, args, complain, in_decl);
+ do_local_using_decl (build_nt (SCOPE_REF, scope, name));
+ }
else
{
init = DECL_INITIAL (decl);
decl = tsubst (decl, args, complain, in_decl);
- init = tsubst_expr (init, args, complain, in_decl);
+ if (DECL_PRETTY_FUNCTION_P (decl))
+ init = DECL_INITIAL (decl);
+ else
+ init = tsubst_expr (init, args, complain, in_decl);
if (decl != error_mark_node)
{
if (TREE_CODE (decl) != TYPE_DECL)
cp_finish_decl (decl, init, NULL_TREE, 0);
}
}
- return decl;
+
+ /* A DECL_STMT can also be used as an expression, in the condition
+ clause of a if/for/while construct. If we aren't followed by
+ another statement, return our decl. */
+ if (TREE_CHAIN (t) == NULL_TREE)
+ return decl;
}
+ break;
case FOR_STMT:
{
- tree tmp;
prep_stmt (t);
stmt = begin_for_stmt ();
- for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
- tsubst_expr (tmp, args, complain, in_decl);
+ tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
finish_for_init_stmt (stmt);
finish_for_cond (tsubst_expr (FOR_COND (t), args,
complain, in_decl),
case IF_STMT:
{
- tree tmp;
-
prep_stmt (t);
stmt = begin_if_stmt ();
finish_if_stmt_cond (tsubst_expr (IF_COND (t),
case COMPOUND_STMT:
{
- tree substmt;
-
prep_stmt (t);
stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
- for (substmt = COMPOUND_BODY (t);
- substmt != NULL_TREE;
- substmt = TREE_CHAIN (substmt))
- tsubst_expr (substmt, args, complain, in_decl);
- return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
+ tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+ finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
}
break;
case GOTO_STMT:
prep_stmt (t);
- t = GOTO_DESTINATION (t);
- if (TREE_CODE (t) != LABEL_DECL)
+ tmp = GOTO_DESTINATION (t);
+ if (TREE_CODE (tmp) != LABEL_DECL)
/* Computed goto's must be tsubst'd into. On the other hand,
non-computed gotos must not be; the identifier in question
will have no binding. */
- t = tsubst_expr (t, args, complain, in_decl);
+ tmp = tsubst_expr (tmp, args, complain, in_decl);
else
- t = DECL_NAME (t);
- finish_goto_stmt (t);
+ tmp = DECL_NAME (tmp);
+ finish_goto_stmt (tmp);
break;
case ASM_STMT:
}
else
{
- tree handler;
-
if (FN_TRY_BLOCK_P (t))
stmt = begin_function_try_block ();
else
else
finish_try_block (stmt);
- handler = TRY_HANDLERS (t);
- for (; handler; handler = TREE_CHAIN (handler))
- tsubst_expr (handler, args, complain, in_decl);
+ tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
if (FN_TRY_BLOCK_P (t))
finish_function_handler_sequence (stmt);
else
case HANDLER:
{
tree decl;
- tree blocks;
prep_stmt (t);
stmt = begin_handler ();
}
else
decl = NULL_TREE;
- blocks = finish_handler_parms (decl, stmt);
+ finish_handler_parms (decl, stmt);
tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
- finish_handler (blocks, stmt);
+ finish_handler (stmt);
}
break;
case TAG_DEFN:
prep_stmt (t);
- t = TREE_TYPE (t);
- tsubst (t, args, complain, NULL_TREE);
+ tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
break;
+ case CTOR_STMT:
+ add_stmt (copy_node (t));
+ break;
+
default:
- return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+ abort ();
}
- return NULL_TREE;
+
+ return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
}
/* TMPL is a TEMPLATE_DECL for a cloned constructor or destructor.
qualified at this point.
UNIFY_ALLOW_OUTER_LESS_CV_QUAL:
This is the outermost level of a deduction, and PARM can be less CV
- qualified at this point. */
+ qualified at this point.
+ UNIFY_ALLOW_MAX_CORRECTION:
+ This is an INTEGER_TYPE's maximum value. Used if the range may
+ have been derived from a size specification, such as an array size.
+ If the size was given by a nontype template parameter N, the maximum
+ value will have the form N-1. The flag says that we can (and indeed
+ must) unify N with (ARG + 1), an exception to the normal rules on
+ folding PARM. */
static int
unify (tparms, targs, parm, arg, strict)
return 1;
if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
- && TYPE_P (arg) && !CP_TYPE_CONST_P (arg))
+ && TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
strict &= ~UNIFY_ALLOW_DERIVED;
strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
+ strict &= ~UNIFY_ALLOW_MAX_CORRECTION;
switch (TREE_CODE (parm))
{
level of pointers. */
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
+ if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
+ && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+ {
+ /* Avoid getting confused about cv-quals; don't recurse here.
+ Pointers to members should really be just OFFSET_TYPE, not
+ this two-level nonsense... */
+
+ parm = TREE_TYPE (parm);
+ arg = TREE_TYPE (arg);
+ goto offset;
+ }
+
return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), strict);
}
return 1;
if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
&& unify (tparms, targs, TYPE_MAX_VALUE (parm),
- TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER))
+ TYPE_MAX_VALUE (arg),
+ UNIFY_ALLOW_INTEGER | UNIFY_ALLOW_MAX_CORRECTION))
return 1;
}
/* We have already checked cv-qualification at the top of the
DEDUCE_EXACT, 0, -1);
case OFFSET_TYPE:
+ offset:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
return 1;
case MINUS_EXPR:
- if (TREE_CODE (TREE_OPERAND (parm, 1)) == INTEGER_CST)
+ if (tree_int_cst_equal (TREE_OPERAND (parm, 1), integer_one_node)
+ && (strict_in & UNIFY_ALLOW_MAX_CORRECTION))
{
/* We handle this case specially, since it comes up with
arrays. In particular, something like:
do_decl_instantiation (declspecs, declarator, storage)
tree declspecs, declarator, storage;
{
- tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE);
+ tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL);
tree result = NULL_TREE;
int extern_p = 0;
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
- CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
if (! extern_p)
{
functions, this is not so. See tsubst_friend_function for
details. */
DECL_TI_TEMPLATE (new_decl) = DECL_TI_TEMPLATE (decl);
- DECL_ASSEMBLER_NAME (new_decl) = DECL_ASSEMBLER_NAME (decl);
- DECL_RTL (new_decl) = DECL_RTL (decl);
+ COPY_DECL_ASSEMBLER_NAME (decl, new_decl);
+ COPY_DECL_RTL (decl, new_decl);
DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl);
/* Call duplicate decls to merge the old and new declarations. */
if (pattern_defined)
{
- repo_template_used (d);
+ /* Let the repository code that this template definition is
+ available.
+
+ The repository doesn't need to know about cloned functions
+ because they never actually show up in the object file. It
+ does need to know about the clones; those are the symbols
+ that the linker will be emitting error messages about. */
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (d)
+ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (d))
+ {
+ tree t;
+
+ for (t = TREE_CHAIN (d);
+ t && DECL_CLONED_FUNCTION_P (t);
+ t = TREE_CHAIN (t))
+ repo_template_used (t);
+ }
+ else
+ repo_template_used (d);
if (flag_external_templates && ! DECL_INTERFACE_KNOWN (d))
{
import_export_decl (d);
}
- /* We need to set up DECL_INITIAL regardless, if
- the variable is initialized in the class body. */
- if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d))
- ;
+ if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d)
+ && DECL_INITIAL (d) == NULL_TREE)
+ /* We should have set up DECL_INITIAL in instantiate_class_template. */
+ abort ();
/* Reject all external templates except inline functions. */
else if (DECL_INTERFACE_KNOWN (d)
&& ! DECL_NOT_REALLY_EXTERN (d)
- && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d)))
+ && ! (TREE_CODE (d) == FUNCTION_DECL
+ && DECL_INLINE (d)))
goto out;
/* Defer all other templates, unless we have been explicitly
forbidden from doing so. We restore the source position here
member function or static data member of a class template
shall be present in every translation unit in which it is
explicitly instantiated. */
- cp_error ("explicit instantiation of `%D' but no definition available",
- d);
+ cp_pedwarn
+ ("explicit instantiation of `%D' but no definition available", d);
add_pending_template (d);
goto out;
/* Set up context. */
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
- /* We already set up __FUNCTION__, etc., so we don't want to do
- it again now. */
- function_name_declared_p = 1;
-
/* Substitute into the body of the function. */
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
/*complain=*/1, tmpl);
instantiate_pending_templates ()
{
tree *t;
+ tree last = NULL_TREE;
int instantiated_something = 0;
int reconsider;
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = TREE_CHAIN (*t);
- else
- t = &TREE_CHAIN (*t);
+ else
+ {
+ last = *t;
+ t = &TREE_CHAIN (*t);
+ }
}
else
{
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
*t = TREE_CHAIN (*t);
- else
- t = &TREE_CHAIN (*t);
+ else
+ {
+ last = *t;
+ t = &TREE_CHAIN (*t);
+ }
}
tinst_depth = 0;
current_tinst_level = NULL_TREE;
}
- template_tail = t;
-
- /* Go through the things that are template instantiations if we are
- using guiding declarations. */
- t = &maybe_templates;
- while (*t)
- {
- tree template;
- tree fn;
- tree args;
-
- fn = TREE_VALUE (*t);
-
- if (DECL_INITIAL (fn))
- /* If the FN is already defined, then it was either already
- instantiated or, even though guiding declarations were
- allowed, a non-template definition was provided. */
- ;
- else
- {
- template = TREE_PURPOSE (*t);
- args = get_bindings (template, fn, NULL_TREE);
- fn = instantiate_template (template, args);
- instantiate_decl (fn, /*defer_ok=*/0);
- reconsider = 1;
- }
-
- /* Remove this entry from the chain. */
- *t = TREE_CHAIN (*t);
- }
- maybe_template_tail = t;
+ last_pending_template = last;
}
while (reconsider);
return fn_type;
}
-/* Set the DECL_ASSEMBLER_NAME for DECL, which is a FUNCTION_DECL that
- is either an instantiation or specialization of a template
- function. */
-
-static void
-set_mangled_name_for_template_decl (decl)
- tree decl;
-{
- my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0);
- my_friendly_assert (DECL_TEMPLATE_INFO (decl) != NULL_TREE, 0);
-
- /* Under the new ABI, we don't need special machinery. */
- set_mangled_name_for_decl (decl);
-}
-
/* Return truthvalue if we're processing a template different from
the last one involved in diagnostics. */
int
return 0;
else if (TYPE_PTRMEMFUNC_P (type))
return 0;
- else if (!pedantic && TREE_CODE (type) == REAL_TYPE)
- return 0; /* GNU extension */
- else if (!pedantic && TREE_CODE (type) == COMPLEX_TYPE)
- return 0; /* GNU extension */
else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return 0;
else if (TREE_CODE (type) == TYPENAME_TYPE)