Commit 3ebc5c52 by Mark Mitchell Committed by Mark Mitchell

class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to intialize a vtable.

	* class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to
	intialize a vtable.
	* cp-tree.h (NAMESPACE_LEVEL): Reformat.
	(lang_decl_flags): Document MEMFUNC_POINTER_TO.  Save four bytes
	by combining TEMPLATE_INFO and LEVEL into a single union.
	(DECL_TEMPLATE_INFO): Reformat.
	(DECL_SAVED_TREE): Document.
	(DECL_TEMPLATE_INJECT): Remove.
	* class.c (finish_struct): Remove code to deal with
	DECL_TEMPLATE_INJECT.
	* decl.c (maybe_process_template_type_declaration): Handle all new
	types in templates uniformly.
	* method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not
	DECL_CONTEXT.
	* pt.c (lookup_template_class): Inject template instantiations of
	forward-declarations.
	(instantiate_class_template): Remove code processing
	DECL_TEMPLATE_INJECT.
	* pt.c (lookup_template_class): Tweak lookup to find member
	templates.
	* pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into
	ASM_CV_QUAL.
	* semantics.c (finish_asm_stmt): Make strings permanent if they're
	used in a template.

From-SVN: r27144
parent c9b2595a
1999-05-25 Mark Mitchell <mark@codesourcery.com>
* class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to
intialize a vtable.
* cp-tree.h (NAMESPACE_LEVEL): Reformat.
(lang_decl_flags): Document MEMFUNC_POINTER_TO. Save four bytes
by combining TEMPLATE_INFO and LEVEL into a single union.
(DECL_TEMPLATE_INFO): Reformat.
(DECL_SAVED_TREE): Document.
(DECL_TEMPLATE_INJECT): Remove.
* class.c (finish_struct): Remove code to deal with
DECL_TEMPLATE_INJECT.
* decl.c (maybe_process_template_type_declaration): Handle all new
types in templates uniformly.
* method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not
DECL_CONTEXT.
* pt.c (lookup_template_class): Inject template instantiations of
forward-declarations.
(instantiate_class_template): Remove code processing
DECL_TEMPLATE_INJECT.
* pt.c (lookup_template_class): Tweak lookup to find member
templates.
* pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into
ASM_CV_QUAL.
* semantics.c (finish_asm_stmt): Make strings permanent if they're
used in a template.
1999-05-25 Jason Merrill <jason@yorick.cygnus.com> 1999-05-25 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (casts_away_constness, casts_away_constness_r): Strip both * typeck.c (casts_away_constness, casts_away_constness_r): Strip both
......
...@@ -2170,9 +2170,14 @@ finish_vtbls (binfo, do_self, t) ...@@ -2170,9 +2170,14 @@ finish_vtbls (binfo, do_self, t)
decl = BINFO_VTABLE (binfo); decl = BINFO_VTABLE (binfo);
context = DECL_CONTEXT (decl); context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = 0; DECL_CONTEXT (decl) = 0;
if (DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, /* We make a copy here in case we need to replace pure
BINFO_VIRTUALS (binfo)); virtual functions with __pure_virtual. We don't want to
mess up BINFO_VIRTUALS when we do this. */
DECL_INITIAL (decl) = copy_list (BINFO_VIRTUALS (binfo));
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
DECL_INITIAL (decl));
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0);
DECL_CONTEXT (decl) = context; DECL_CONTEXT (decl) = context;
} }
...@@ -4197,24 +4202,6 @@ finish_struct (t, attributes, warn_anon) ...@@ -4197,24 +4202,6 @@ finish_struct (t, attributes, warn_anon)
if (processing_template_decl) if (processing_template_decl)
{ {
tree d = getdecls ();
for (; d; d = TREE_CHAIN (d))
{
/* If this is the decl for the class or one of the template
parms, we've seen all the injected decls. */
if ((TREE_CODE (d) == TYPE_DECL
&& (TREE_TYPE (d) == t
|| TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM
|| TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM))
|| TREE_CODE (d) == CONST_DECL)
break;
/* Don't inject cache decls. */
else if (IDENTIFIER_TEMPLATE (DECL_NAME (d)))
continue;
DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))
= tree_cons (NULL_TREE, d,
DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
}
finish_struct_methods (t); finish_struct_methods (t);
TYPE_SIZE (t) = integer_zero_node; TYPE_SIZE (t) = integer_zero_node;
} }
......
...@@ -1136,7 +1136,8 @@ struct lang_type ...@@ -1136,7 +1136,8 @@ struct lang_type
&& TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE) && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE)
/* The binding level associated with the namespace. */ /* The binding level associated with the namespace. */
#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level) #define NAMESPACE_LEVEL(NODE) \
(DECL_LANG_SPECIFIC(NODE)->decl_flags.u.level)
/* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or /* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or
...@@ -1180,9 +1181,19 @@ struct lang_decl_flags ...@@ -1180,9 +1181,19 @@ struct lang_decl_flags
tree access; tree access;
tree context; tree context;
/* In a template FUNCTION_DECL, this is DECL_SAVED_TREE.
In a non-template FUNCTION_DECL, this is DECL_MEMFUNC_POINTER_TO.
In a FIELD_DECL, this is DECL_MEMFUNC_POINTING_TO. */
tree memfunc_pointer_to; tree memfunc_pointer_to;
tree template_info;
struct binding_level *level; union {
/* In a FUNCTION_DECL, this is DECL_TEMPLATE_INFO. */
tree template_info;
/* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL. */
struct binding_level *level;
} u;
}; };
struct lang_decl struct lang_decl
...@@ -1392,7 +1403,8 @@ struct lang_decl ...@@ -1392,7 +1403,8 @@ struct lang_decl
#define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to) #define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to)
/* For a VAR_DECL or FUNCTION_DECL: template-specific information. */ /* For a VAR_DECL or FUNCTION_DECL: template-specific information. */
#define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info) #define DECL_TEMPLATE_INFO(NODE) \
(DECL_LANG_SPECIFIC(NODE)->decl_flags.u.template_info)
/* Template information for a RECORD_TYPE or UNION_TYPE. */ /* Template information for a RECORD_TYPE or UNION_TYPE. */
#define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info) #define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info)
...@@ -1475,7 +1487,10 @@ struct lang_decl ...@@ -1475,7 +1487,10 @@ struct lang_decl
the class definition is complete. */ the class definition is complete. */
#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
/* In a template FUNCTION_DECL, the tree structure that will be
substituted into to obtain instantiations. */
#define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) #define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE)
#define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) #define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE)
#define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
#define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
...@@ -1898,7 +1913,6 @@ extern int flag_new_for_scope; ...@@ -1898,7 +1913,6 @@ extern int flag_new_for_scope;
This list is not used for static variable templates. */ This list is not used for static variable templates. */
#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) #define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE)
#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE)
/* Nonzero for a DECL which is actually a template parameter. */ /* Nonzero for a DECL which is actually a template parameter. */
#define DECL_TEMPLATE_PARM_P(NODE) \ #define DECL_TEMPLATE_PARM_P(NODE) \
......
...@@ -2783,25 +2783,7 @@ maybe_process_template_type_declaration (type, globalize, b) ...@@ -2783,25 +2783,7 @@ maybe_process_template_type_declaration (type, globalize, b)
|| TREE_CODE (type) == ENUMERAL_TYPE, 0); || TREE_CODE (type) == ENUMERAL_TYPE, 0);
if (/* If !GLOBALIZE then we are looking at a definition. if (processing_template_decl)
It may not be a primary template. (For example, in:
template <class T>
struct S1 { class S2 {}; }
we have to push_template_decl for S2.) */
(processing_template_decl && !globalize)
/* If we are declaring a friend template class, we will
have GLOBALIZE set, since something like:
template <class T>
struct S1 {
template <class U>
friend class S2;
};
declares S2 to be at global scope. */
|| PROCESSING_REAL_TEMPLATE_DECL_P ())
{ {
/* This may change after the call to /* This may change after the call to
push_template_decl_real, but we want the original value. */ push_template_decl_real, but we want the original value. */
......
...@@ -999,8 +999,8 @@ build_overload_identifier (name) ...@@ -999,8 +999,8 @@ build_overload_identifier (name)
&& CLASS_TYPE_P (TREE_TYPE (name)) && CLASS_TYPE_P (TREE_TYPE (name))
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
&& (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))) && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
|| (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE || (TREE_CODE (CP_DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
(TREE_TYPE (name)))) (TREE_TYPE (name))))
== FUNCTION_DECL))) == FUNCTION_DECL)))
{ {
/* NAME is the TYPE_DECL for a template specialization. */ /* NAME is the TYPE_DECL for a template specialization. */
......
...@@ -3613,12 +3613,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -3613,12 +3613,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
{ {
if (context) if (context)
push_decl_namespace (context); push_decl_namespace (context);
if (current_class_type != NULL_TREE) template = lookup_name (d1, /*prefer_type=*/0);
template = template = maybe_get_template_decl_from_type_decl (template);
maybe_get_template_decl_from_type_decl
(IDENTIFIER_CLASS_VALUE (d1));
if (template == NULL_TREE)
template = lookup_name_nonclass (d1);
if (context) if (context)
pop_decl_namespace (); pop_decl_namespace ();
} }
...@@ -3834,24 +3830,35 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -3834,24 +3830,35 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
if (found) if (found)
found = TREE_VALUE (found); found = TREE_VALUE (found);
} }
if (found) if (found)
{ {
pop_momentary (); pop_momentary ();
return found; return found;
} }
/* Since we didn't find the type, we'll have to create it.
Since we'll be saving this type on the
DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent. */
push_obstacks (&permanent_obstack, &permanent_obstack);
/* This type is a "partial instantiation" if any of the template /* This type is a "partial instantiation" if any of the template
arguments still inolve template parameters. Note that we set arguments still inolve template parameters. Note that we set
IS_PARTIAL_INSTANTIATION for partial specializations as IS_PARTIAL_INSTANTIATION for partial specializations as
well. */ well. */
is_partial_instantiation = uses_template_parms (arglist); is_partial_instantiation = uses_template_parms (arglist);
if (!is_partial_instantiation
&& !PRIMARY_TEMPLATE_P (template)
&& TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
{
pop_momentary ();
found = xref_tag_from_type (TREE_TYPE (template),
DECL_NAME (template),
/*globalize=*/1);
return found;
}
/* Since we didn't find the type, we'll have to create it.
Since we'll be saving this type on the
DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent. */
push_obstacks (&permanent_obstack, &permanent_obstack);
/* Create the type. */ /* Create the type. */
if (TREE_CODE (template_type) == ENUMERAL_TYPE) if (TREE_CODE (template_type) == ENUMERAL_TYPE)
{ {
...@@ -5111,23 +5118,6 @@ instantiate_class_template (type) ...@@ -5111,23 +5118,6 @@ instantiate_class_template (type)
--processing_template_decl; --processing_template_decl;
} }
/* This does injection for friend functions. */
if (!processing_template_decl)
{
t = tsubst (DECL_TEMPLATE_INJECT (template), args,
/*complain=*/1, NULL_TREE);
for (; t; t = TREE_CHAIN (t))
{
tree d = TREE_VALUE (t);
if (TREE_CODE (d) == TYPE_DECL)
/* Already injected. */;
else
pushdecl (d);
}
}
for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
if (TREE_CODE (t) == FIELD_DECL) if (TREE_CODE (t) == FIELD_DECL)
{ {
...@@ -7200,7 +7190,7 @@ tsubst_expr (t, args, complain, in_decl) ...@@ -7200,7 +7190,7 @@ tsubst_expr (t, args, complain, in_decl)
case ASM_STMT: case ASM_STMT:
lineno = TREE_COMPLEXITY (t); lineno = TREE_COMPLEXITY (t);
finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, complain, in_decl), finish_asm_stmt (ASM_CV_QUAL (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl), tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl), tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl), tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
......
...@@ -718,7 +718,7 @@ finish_compound_stmt (has_no_scope, compound_stmt) ...@@ -718,7 +718,7 @@ finish_compound_stmt (has_no_scope, compound_stmt)
void void
finish_asm_stmt (cv_qualifier, string, output_operands, finish_asm_stmt (cv_qualifier, string, output_operands,
input_operands, clobbers) input_operands, clobbers)
tree cv_qualifier; tree cv_qualifier;
tree string; tree string;
tree output_operands; tree output_operands;
...@@ -726,7 +726,20 @@ finish_asm_stmt (cv_qualifier, string, output_operands, ...@@ -726,7 +726,20 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
tree clobbers; tree clobbers;
{ {
if (TREE_CHAIN (string)) if (TREE_CHAIN (string))
string = combine_strings (string); {
if (processing_template_decl)
{
/* We need to build the combined string on the permanent
obstack so that we can use it during instantiations. */
push_obstacks_nochange ();
end_temporary_allocation ();
}
string = combine_strings (string);
if (processing_template_decl)
pop_obstacks ();
}
if (processing_template_decl) if (processing_template_decl)
{ {
......
// Build don't link:
// Origin: "Weidmann, Nicholas" <nicholas.weidmann@swx.ch>
// Skip if not target: i?86-*-linux*
template<int i> int foo(int v)
{
__asm__ __volatile__("addl %1, %0" : "=a" (v) : "b" (i));
return v;
}
int bar(int i)
{
return foo<123>(i);
}
// Build don't link:
// Origin: "Weidmann, Nicholas" <nicholas.weidmann@swx.ch>
// Skip if not target: i?86-*-linux*
typedef void (function_ptr)(int);
void foo(int)
{
}
template<function_ptr ptr> void doit(int i)
{
__asm__("pushl %0\n\t"
"call *%1\n\t"
"popl %0"
:
: "a" (i), "b" (ptr));
}
void bar()
{
doit<foo>(123);
}
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <int I>
struct S {
struct T* x;
};
template struct S<2>;
T* t;
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
// Special g++ Options: -Wno-non-template-friend
template<int I>
class C {
friend void f(struct X *);
};
template class C<0>;
class D {
friend void f(struct X*);
};
// Build don't link:
// Origin: <Corey Kosak> kosak@cs.cmu.edu
struct moo {
template<bool x> struct cow {};
template<bool x>
struct moo2 {
void func(cow<x> &c) { }
};
};
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