Specialization Patch
Mark Mitchell
mmitchell@usa.net
Wed Oct 15 22:25:00 GMT 1997
Yotam --
Here's a fix (I think) for your bug:
template<class T>
class C
{
public:
static const char* say();
};
template <>
const char* C<int>::say()
{ return "I am int"; }
template <>
const char* C<float>::say()
{ return "I am float"; }
Both functions are now defined in the object file.
--
Mark Mitchell mmitchell@usa.net
Stanford University http://www.stanford.edu
Wed Oct 15 22:21:53 1997 Mark Mitchell <mmitchell@usa.net>
* class.c (finish_struct_methods): Fix typo in comment.
* decl.c (duplicate_decls): Handle template specializations
correctly.
* error.c (dump_function_name): Fix printing of specializations of
member functions that are not member templates.
* cp-tree.h (processing_specialization): Make global.
* pt.c (processing_specialization): Likewise.
* lex.c (cons_up_default_function): Save and restore
processing_specialization to avoid confusion.
cvs diff: Diffing .
Index: class.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/class.c,v
retrieving revision 1.8
diff -c -p -r1.8 class.c
*** class.c 1997/09/28 02:56:19 1.8
--- class.c 1997/10/16 04:52:00
*************** finish_struct_methods (t, fn_fields, non
*** 2092,2098 ****
tree f;
tree spec_args;
! /* If there is a template, and t uses template parms, wer
are dealing with a specialization of a member
template in a template class, and we must grab the
template, rather than the function. */
--- 2092,2098 ----
tree f;
tree spec_args;
! /* If there is a template, and t uses template parms, we
are dealing with a specialization of a member
template in a template class, and we must grab the
template, rather than the function. */
Index: cp-tree.h
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.9
diff -c -p -r1.9 cp-tree.h
*** cp-tree.h 1997/10/16 04:35:11 1.9
--- cp-tree.h 1997/10/16 04:47:10
*************** extern tree most_specialized_class PROT
*** 2352,2357 ****
--- 2352,2358 ----
extern int more_specialized_class PROTO((tree, tree));
extern void do_pushlevel PROTO((void));
extern int is_member_template PROTO((tree));
+ extern int processing_specialization;
/* in repo.c */
extern void repo_template_used PROTO((tree));
Index: decl.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/decl.c,v
retrieving revision 1.12
diff -c -p -r1.12 decl.c
*** decl.c 1997/10/16 04:35:11 1.12
--- decl.c 1997/10/16 05:20:58
*************** duplicate_decls (newdecl, olddecl)
*** 2866,2871 ****
--- 2866,2874 ----
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
+ if (DECL_TEMPLATE_INSTANTIATION (olddecl) &&
+ !DECL_TEMPLATE_INSTANTIATION (newdecl))
+ DECL_USE_TEMPLATE (olddecl) = DECL_USE_TEMPLATE (newdecl);
DECL_THIS_INLINE (newdecl) |= DECL_THIS_INLINE (olddecl);
/* If either decl says `inline', this fn is inline, unless its
Index: error.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/error.c,v
retrieving revision 1.11
diff -c -p -r1.11 error.c
*** error.c 1997/09/28 02:56:23 1.11
--- error.c 1997/10/16 05:01:37
*************** dump_function_name (t)
*** 925,931 ****
else
dump_decl (name, 0);
! if (DECL_TEMPLATE_SPECIALIZATION (t) || DECL_IMPLICIT_INSTANTIATION (t))
{
tree args = DECL_TEMPLATE_INFO (t)
? DECL_TI_ARGS (t) : NULL_TREE;
--- 925,933 ----
else
dump_decl (name, 0);
! if (DECL_TEMPLATE_SPECIALIZATION (t)
! || DECL_IMPLICIT_INSTANTIATION (t)
! && (DECL_CLASS_CONTEXT (t) == NULL_TREE || is_member_template(t)))
{
tree args = DECL_TEMPLATE_INFO (t)
? DECL_TI_ARGS (t) : NULL_TREE;
Index: lex.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/lex.c,v
retrieving revision 1.8
diff -c -p -r1.8 lex.c
*** lex.c 1997/10/16 04:35:13 1.8
--- lex.c 1997/10/16 04:53:54
*************** cons_up_default_function (type, full_nam
*** 1988,1997 ****
{
tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
if (retref)
declarator = build_parse_node (ADDR_EXPR, declarator);
!
fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
}
if (fn == void_type_node)
--- 1988,2003 ----
{
tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
+ int saved_processing_specialization;
if (retref)
declarator = build_parse_node (ADDR_EXPR, declarator);
!
! /* The following is in case we're generating the default
! implementation in the midst of handling a specialization. */
! saved_processing_specialization = processing_specialization;
! processing_specialization = 0;
fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
+ processing_specialization = saved_processing_specialization;
}
if (fn == void_type_node)
Index: pt.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/pt.c,v
retrieving revision 1.19
diff -c -p -r1.19 pt.c
*** pt.c 1997/10/16 04:35:14 1.19
--- pt.c 1997/10/16 04:46:29
*************** static tree *maybe_template_tail = &mayb
*** 63,69 ****
int minimal_parse_mode;
! static int processing_specialization;
static int template_header_count;
#define obstack_chunk_alloc xmalloc
--- 63,69 ----
int minimal_parse_mode;
! int processing_specialization;
static int template_header_count;
#define obstack_chunk_alloc xmalloc
cvs diff: Diffing inc
More information about the Gcc-bugs
mailing list