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