Commit 459c43ad by Mark Mitchell

mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.

	* mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.
	(is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here.
	(find_substitution): Only use the `Sa' substitution for
	std::allocator, not instantiations of it.
	(write_template_prefix): Move comment.  Only use a TREE_LIST to
	represent substitutions for a member template.
	(write_array_type): Mangle array dimensions correctly.
	* optimize.c (maybe_clone_body): Copy more information from the
	cloned function.
	* pt.c (regenerate_decl_from_template): Preserve DECL_USE_TEMPLATE
	on the regenerated declaration.

From-SVN: r34497
parent cbd3488b
2000-06-11 Mark Mitchell <mark@codesourcery.com>
* mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.
(is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here.
(find_substitution): Only use the `Sa' substitution for
std::allocator, not instantiations of it.
(write_template_prefix): Move comment. Only use a TREE_LIST to
represent substitutions for a member template.
(write_array_type): Mangle array dimensions correctly.
* optimize.c (maybe_clone_body): Copy more information from the
cloned function.
* pt.c (regenerate_decl_from_template): Preserve DECL_USE_TEMPLATE
on the regenerated declaration.
2000-06-11 Chip Salzenberg <chip@valinux.com>
Mark Mitchell <mark@codesourcery.com>
* class.c (build_vtable): Clarify comment.
(build_ctor_vtbl_group): Pass the most derived type to
build_vtable.
2000-06-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decl2.c (compare_options): Don't needlessly cast away const-ness.
......
......@@ -673,7 +673,6 @@ get_vfield_offset (binfo)
on method calling is expected to point to a DECL_CONTEXT (fndecl)
object, and not a baseclass of it. */
static tree
get_derived_offset (binfo, type)
tree binfo, type;
......@@ -695,9 +694,9 @@ get_derived_offset (binfo, type)
return size_binop (MINUS_EXPR, offset1, offset2);
}
/* Create a VAR_DECL for a primary or secondary vtable for
CLASS_TYPE. Use NAME for the name of the vtable, and VTABLE_TYPE
for its type. */
/* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
(For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.)
Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */
static tree
build_vtable (class_type, name, vtable_type)
......@@ -6781,7 +6780,7 @@ build_ctor_vtbl_group (binfo, t)
/* Build a version of VTBL (with the wrong type) for use in
constructing the addresses of secondary vtables in the
construction vtable group. */
vtbl = build_vtable (BINFO_TYPE (binfo), id, ptr_type_node);
vtbl = build_vtable (t, id, ptr_type_node);
list = build_tree_list (vtbl, NULL_TREE);
accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
binfo, t, list);
......
......@@ -208,8 +208,8 @@ static tree mangle_special_for_type PARAMS ((tree, const char *));
#define mangled_position() \
obstack_object_size (&G.name_obstack)
/* Non-zero if NODE1__ and NODE2__ are both TREE_LIST nodes and have
the same purpose (context, which may be a type) and value (template
/* Non-zero if NODE1 and NODE2 are both TREE_LIST nodes and have the
same purpose (context, which may be a type) and value (template
decl). See write_template_prefix for more information on what this
is used for. */
#define NESTED_TEMPLATE_MATCH(NODE1, NODE2) \
......@@ -348,12 +348,11 @@ is_std_substitution (node, index)
/* These are not the droids you're looking for. */
return 0;
return
DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
&& TYPE_LANG_SPECIFIC (type)
&& CLASSTYPE_USE_TEMPLATE (type)
&& (DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
== subst_identifiers[index]);
return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
&& TYPE_LANG_SPECIFIC (type)
&& CLASSTYPE_TEMPLATE_INFO (type)
&& (DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
== subst_identifiers[index]));
}
/* Helper function for find_substitution. Returns non-zero if NODE,
......@@ -441,7 +440,9 @@ find_substitution (node)
type = TYPE_P (node) ? node : TREE_TYPE (node);
/* Check for std::allocator. */
if (decl && is_std_substitution (decl, SUBID_ALLOCATOR))
if (decl
&& is_std_substitution (decl, SUBID_ALLOCATOR)
&& !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
{
write_string ("Sa");
return 1;
......@@ -782,32 +783,7 @@ write_prefix (node)
}
/* <template-prefix> ::= <prefix> <template component>
::= <substitution>
Names of templates are substitution candidates. For a nested
template, though, the template name for the innermost name must
have all the outer template levels instantiated. For instance,
consider
template<typename T> struct Outer
{
template<typename U> struct Inner {};
};
The template name for `Inner' in `Outer<int>::Inner<float>' is
`Outer<int>::Inner<U>'. In g++, we don't instantiate the template
levels separately, so there's no TEMPLATE_DECL available for this
(there's only `Outer<T>::Inner<U>').
In order to get the substitutions right, we create a special
TREE_LIST to represent the substitution candidate for a nested
template. The TREE_PURPOSE is the tempate's context, fully
instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner
template.
So, for the example above, `Inner' is represented as a substitution
candidate by a TREE_LIST whose purpose is `Outer<int>' and whose
value is `Outer<T>::Inner<U>'. */
::= <substitution> */
static void
write_template_prefix (node)
......@@ -830,8 +806,32 @@ write_template_prefix (node)
/* Oops, not a template. */
my_friendly_abort (20000524);
/* Build the substitution candidate TREE_LIST. */
substitution = build_tree_list (context, template);
/* For a member template, though, the template name for the
innermost name must have all the outer template levels
instantiated. For instance, consider
template<typename T> struct Outer {
template<typename U> struct Inner {};
};
The template name for `Inner' in `Outer<int>::Inner<float>' is
`Outer<int>::Inner<U>'. In g++, we don't instantiate the template
levels separately, so there's no TEMPLATE_DECL available for this
(there's only `Outer<T>::Inner<U>').
In order to get the substitutions right, we create a special
TREE_LIST to represent the substitution candidate for a nested
template. The TREE_PURPOSE is the template's context, fully
instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner
template.
So, for the example above, `Outer<int>::Inner' is represented as a
substitution candidate by a TREE_LIST whose purpose is `Outer<int>'
and whose value is `Outer<T>::Inner<U>'. */
if (TYPE_P (context))
substitution = build_tree_list (context, template);
else
substitution = template;
if (find_substitution (substitution))
return;
......@@ -1768,7 +1768,12 @@ write_array_type (type)
array. */
max = TYPE_MAX_VALUE (index_type);
if (TREE_CODE (max) == INTEGER_CST)
write_unsigned_number (tree_low_cst (max, 1));
{
/* The ABI specifies that we should mangle the number of
elements in the array, not the largest allowed index. */
max = size_binop (PLUS_EXPR, max, size_one_node);
write_unsigned_number (tree_low_cst (max, 1));
}
else
write_expression (TREE_OPERAND (max, 0));
}
......
......@@ -911,6 +911,10 @@ maybe_clone_body (fn)
DECL_WEAK (clone) = DECL_WEAK (fn);
DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
/* Start processing the function. */
push_to_top_level ();
......
......@@ -9469,6 +9469,7 @@ regenerate_decl_from_template (decl, tmpl)
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);
DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl);
/* Call duplicate decls to merge the old and new declarations. */
duplicate_decls (new_decl, decl);
......
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