This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH to cleanup pt.c a little bit



This patch just fixes an error message, and removes some dead code in
determine_specialization.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-09-14  Mark Mitchell  <mark@markmitchell.com>

	* pt.c (check_specialization_scope): Fix spelling error.
	(check_explicit_specialization): Remove code to handle explicit
	specializations in class scope; they are now correctly diagnosed
	as errors.

Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.203
diff -c -p -r1.203 pt.c
*** pt.c	1998/09/09 02:14:55	1.203
--- pt.c	1998/09/14 16:57:46
*************** check_specialization_scope ()
*** 605,611 ****
       explicitly specialize a class member template if its enclosing
       class templates are not explicitly specialized as well.  */
    if (current_template_parms) 
!     cp_error ("enclosing class templates are not explicit specialized");
  }
  
  /* We've just seen template <>. */
--- 605,611 ----
       explicitly specialize a class member template if its enclosing
       class templates are not explicitly specialized as well.  */
    if (current_template_parms) 
!     cp_error ("enclosing class templates are not explicitly specialized");
  }
  
  /* We've just seen template <>. */
*************** determine_specialization (template_id, d
*** 1031,1045 ****
     
     FLAGS is a bitmask consisting of the following flags: 
  
-    1: We are being called by finish_struct.  (We are unable to
-       determine what template is specialized by an in-class
-       declaration until the class definition is complete, so
-       finish_struct_methods calls this function again later to finish
-       the job.)
     2: The function has a definition.
     4: The function is a friend.
-    8: The function is known to be a specialization of a member
-       template. 
  
     The TEMPLATE_COUNT is the number of references to qualifying
     template classes that appeared in the name of the function.  For
--- 1031,1038 ----
*************** check_explicit_specialization (declarato
*** 1070,1195 ****
       int template_count;
       int flags;
  {
-   int finish_member = flags & 1;
    int have_def = flags & 2;
    int is_friend = flags & 4;
    int specialization = 0;
    int explicit_instantiation = 0;
!   int member_specialization = flags & 8;
  
    tree ctype = DECL_CLASS_CONTEXT (decl);
    tree dname = DECL_NAME (decl);
  
!   if (!finish_member)
      {
!       if (processing_specialization) 
! 	{
! 	  /* The last template header was of the form template <>.  */
  	  
! 	  if (template_header_count > template_count) 
! 	    {
! 	      /* There were more template headers than qualifying template
! 		 classes.  */
! 	      if (template_header_count - template_count > 1)
! 		/* There shouldn't be that many template parameter
  		   lists.  There can be at most one parameter list for
  		   every qualifying class, plus one for the function
  		   itself.  */
! 		cp_error ("too many template parameter lists in declaration of `%D'", decl);
  
! 	      SET_DECL_TEMPLATE_SPECIALIZATION (decl);
! 	      if (ctype)
! 		member_specialization = 1;
! 	      else
! 		specialization = 1;
! 	    }
! 	  else if (template_header_count == template_count)
! 	    {
! 	      /* The counts are equal.  So, this might be a
! 		 specialization, but it is not a specialization of a
! 		 member template.  It might be something like
  		 
! 		 template <class T> struct S { 
! 	         void f(int i); 
! 		 };
! 		 template <>
! 		 void S<int>::f(int i) {}  */
! 	      specialization = 1;
! 	      SET_DECL_TEMPLATE_SPECIALIZATION (decl);
! 	    }
! 	  else 
! 	    {
! 	      /* This cannot be an explicit specialization.  There are not
! 		 enough headers for all of the qualifying classes.  For
! 		 example, we might have:
! 	     
! 		 template <>
! 		 void S<int>::T<char>::f();
! 
! 		 But, we're missing another template <>.  */
! 	      cp_error("too few template parameter lists in declaration of `%D'", decl);
! 	      return decl;
! 	    } 
  	}
!       else if (processing_explicit_instantiation)
  	{
! 	  if (template_header_count)
! 	    cp_error ("template parameter list used in explicit instantiation");
  	  
! 	  if (have_def)
! 	    cp_error ("definition provided for explicit instantiation");
  
! 	  explicit_instantiation = 1;
! 	}
!       else if (ctype != NULL_TREE
! 	       && !TYPE_BEING_DEFINED (ctype)
! 	       && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)
! 	       && !is_friend)
! 	{
! 	  /* This case catches outdated code that looks like this:
  
! 	     template <class T> struct S { void f(); };
! 	     void S<int>::f() {} // Missing template <>
  
! 	     We disable this check when the type is being defined to
! 	     avoid complaining about default compiler-generated
! 	     constructors, destructors, and assignment operators.
! 	     Since the type is an instantiation, not a specialization,
! 	     these are the only functions that can be defined before
! 	     the class is complete.  */
  
  	  /* If they said
  	       template <class T> void S<int>::f() {}
  	     that's bogus.  */
! 	  if (template_header_count)
! 	    {
! 	      cp_error ("template parameters specified in specialization");
! 	      return decl;
! 	    }
! 
! 	  if (pedantic)
! 	    cp_pedwarn
! 	      ("explicit specialization not preceded by `template <>'");
! 	  specialization = 1;
! 	  SET_DECL_TEMPLATE_SPECIALIZATION (decl);
  	}
!       else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
  	{
! 	  if (is_friend)
! 	    /* This could be something like:
  
! 	         template <class T> void f(T);
! 		 class S { friend void f<>(int); }  */
! 	    specialization = 1;
! 	  else
! 	    {
! 	      /* This case handles bogus declarations like template <>
! 		 template <class T> void f<int>(); */
! 
! 	      cp_error ("template-id `%D' in declaration of primary template",
! 			declarator);
! 	      return decl;
! 	    }
  	}
      }
  
--- 1063,1184 ----
       int template_count;
       int flags;
  {
    int have_def = flags & 2;
    int is_friend = flags & 4;
    int specialization = 0;
    int explicit_instantiation = 0;
!   int member_specialization = 0;
  
    tree ctype = DECL_CLASS_CONTEXT (decl);
    tree dname = DECL_NAME (decl);
  
!   if (processing_specialization) 
      {
!       /* The last template header was of the form template <>.  */
  	  
!       if (template_header_count > template_count) 
! 	{
! 	  /* There were more template headers than qualifying template
! 	     classes.  */
! 	  if (template_header_count - template_count > 1)
! 	    /* There shouldn't be that many template parameter
  		   lists.  There can be at most one parameter list for
  		   every qualifying class, plus one for the function
  		   itself.  */
! 	    cp_error ("too many template parameter lists in declaration of `%D'", decl);
  
! 	  SET_DECL_TEMPLATE_SPECIALIZATION (decl);
! 	  if (ctype)
! 	    member_specialization = 1;
! 	  else
! 	    specialization = 1;
! 	}
!       else if (template_header_count == template_count)
! 	{
! 	  /* The counts are equal.  So, this might be a
! 	     specialization, but it is not a specialization of a
! 	     member template.  It might be something like
  		 
! 	     template <class T> struct S { 
! 	     void f(int i); 
! 	     };
! 	     template <>
! 	     void S<int>::f(int i) {}  */
! 	  specialization = 1;
! 	  SET_DECL_TEMPLATE_SPECIALIZATION (decl);
  	}
!       else 
  	{
! 	  /* This cannot be an explicit specialization.  There are not
! 	     enough headers for all of the qualifying classes.  For
! 	     example, we might have:
! 	     
! 	     template <>
! 	     void S<int>::T<char>::f();
! 
! 	     But, we're missing another template <>.  */
! 	  cp_error("too few template parameter lists in declaration of `%D'", decl);
! 	  return decl;
! 	} 
!     }
!   else if (processing_explicit_instantiation)
!     {
!       if (template_header_count)
! 	cp_error ("template parameter list used in explicit instantiation");
  	  
!       if (have_def)
! 	cp_error ("definition provided for explicit instantiation");
  
!       explicit_instantiation = 1;
!     }
!   else if (ctype != NULL_TREE
! 	   && !TYPE_BEING_DEFINED (ctype)
! 	   && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)
! 	   && !is_friend)
!     {
!       /* This case catches outdated code that looks like this:
  
! 	 template <class T> struct S { void f(); };
! 	 void S<int>::f() {} // Missing template <>
  
! 	 We disable this check when the type is being defined to
! 	 avoid complaining about default compiler-generated
! 	 constructors, destructors, and assignment operators.
! 	 Since the type is an instantiation, not a specialization,
! 	 these are the only functions that can be defined before
! 	 the class is complete.  */
  
  	  /* If they said
  	       template <class T> void S<int>::f() {}
  	     that's bogus.  */
!       if (template_header_count)
! 	{
! 	  cp_error ("template parameters specified in specialization");
! 	  return decl;
  	}
! 
!       if (pedantic)
! 	cp_pedwarn
! 	  ("explicit specialization not preceded by `template <>'");
!       specialization = 1;
!       SET_DECL_TEMPLATE_SPECIALIZATION (decl);
!     }
!   else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
!     {
!       if (is_friend)
! 	/* This could be something like:
! 
! 	   template <class T> void f(T);
! 	   class S { friend void f<>(int); }  */
! 	specialization = 1;
!       else
  	{
! 	  /* This case handles bogus declarations like template <>
! 	     template <class T> void f<int>(); */
  
! 	  cp_error ("template-id `%D' in declaration of primary template",
! 		    declarator);
! 	  return decl;
  	}
      }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]