+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.
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;
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)
/* 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);
#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) \
/* 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,
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;
}
/* <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)
/* 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;
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));
}