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]

(C++) explicict instantiation patch


Fixes g++.pt/explicit80.C; we were complaining about explicitly
instantiating a class with a nested class which had been explicitly
specialized, though we don't complain about the similar case with
functions.

2000-08-02  Jason Merrill  <jason@redhat.com>

	* pt.c (do_type_instantiation): Add complain parm; don't complain
	if called recursively.
	* cp-tree.h, parse.y: Adjust.

Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.506
diff -c -p -r1.506 cp-tree.h
*** gcc/cp/cp-tree.h	2000/08/02 17:01:12	1.506
--- gcc/cp/cp-tree.h	2000/08/03 21:21:47
*************** extern void mark_decl_instantiated		PARA
*** 4260,4266 ****
  extern int more_specialized			PARAMS ((tree, tree, tree));
  extern void mark_class_instantiated		PARAMS ((tree, int));
  extern void do_decl_instantiation		PARAMS ((tree, tree, tree));
! extern void do_type_instantiation		PARAMS ((tree, tree));
  extern tree instantiate_decl			PARAMS ((tree, int));
  extern tree get_bindings			PARAMS ((tree, tree, tree));
  extern void add_tree				PARAMS ((tree));
--- 4260,4266 ----
  extern int more_specialized			PARAMS ((tree, tree, tree));
  extern void mark_class_instantiated		PARAMS ((tree, int));
  extern void do_decl_instantiation		PARAMS ((tree, tree, tree));
! extern void do_type_instantiation		PARAMS ((tree, tree, int));
  extern tree instantiate_decl			PARAMS ((tree, int));
  extern tree get_bindings			PARAMS ((tree, tree, tree));
  extern void add_tree				PARAMS ((tree));
Index: gcc/cp/parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.187
diff -c -p -r1.187 parse.y
*** gcc/cp/parse.y	2000/07/26 18:15:26	1.187
--- gcc/cp/parse.y	2000/08/03 21:21:52
*************** identifier_defn:
*** 962,968 ****
  
  explicit_instantiation:
  	  TEMPLATE begin_explicit_instantiation typespec ';'
! 		{ do_type_instantiation ($3.t, NULL_TREE);
  		  yyungetc (';', 1); }
            end_explicit_instantiation
  	| TEMPLATE begin_explicit_instantiation typed_declspecs declarator
--- 962,968 ----
  
  explicit_instantiation:
  	  TEMPLATE begin_explicit_instantiation typespec ';'
! 		{ do_type_instantiation ($3.t, NULL_TREE, 1);
  		  yyungetc (';', 1); }
            end_explicit_instantiation
  	| TEMPLATE begin_explicit_instantiation typed_declspecs declarator
*************** explicit_instantiation:
*** 976,982 ****
  		{ do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
            end_explicit_instantiation
  	| SCSPEC TEMPLATE begin_explicit_instantiation typespec ';'
! 		{ do_type_instantiation ($4.t, $1);
  		  yyungetc (';', 1); }
            end_explicit_instantiation
  	| SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs 
--- 976,982 ----
  		{ do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
            end_explicit_instantiation
  	| SCSPEC TEMPLATE begin_explicit_instantiation typespec ';'
! 		{ do_type_instantiation ($4.t, $1, 1);
  		  yyungetc (';', 1); }
            end_explicit_instantiation
  	| SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs 
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.454
diff -c -p -r1.454 pt.c
*** gcc/cp/pt.c	2000/07/28 06:05:10	1.454
--- gcc/cp/pt.c	2000/08/03 21:21:58
*************** mark_class_instantiated (t, extern_p)
*** 9267,9275 ****
      }
  }     
  
  void
! do_type_instantiation (t, storage)
       tree t, storage;
  {
    int extern_p = 0;
    int nomem_p = 0;
--- 9267,9281 ----
      }
  }     
  
+ /* Perform an explicit instantiation of template class T.  STORAGE, if
+    non-null, is the RID for extern, inline or static.  COMPLAIN is
+    non-zero if this is called from the parser, zero if called recursively,
+    since the standard is unclear (as detailed below).  */
+  
  void
! do_type_instantiation (t, storage, complain)
       tree t, storage;
+      int complain;
  {
    int extern_p = 0;
    int nomem_p = 0;
*************** do_type_instantiation (t, storage)
*** 9293,9300 ****
  
    if (!COMPLETE_TYPE_P (t))
      {
!       cp_error ("explicit instantiation of `%#T' before definition of template",
! 		t);
        return;
      }
  
--- 9299,9307 ----
  
    if (!COMPLETE_TYPE_P (t))
      {
!       if (complain)
! 	cp_error ("explicit instantiation of `%#T' before definition of template",
! 		  t);
        return;
      }
  
*************** do_type_instantiation (t, storage)
*** 9324,9331 ****
  
  	 No program shall both explicitly instantiate and explicitly
  	 specialize a template.  */
!       cp_error ("explicit instantiation of `%#T' after", t);
!       cp_error_at ("explicit specialization here", t);
        return;
      }
    else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
--- 9331,9341 ----
  
  	 No program shall both explicitly instantiate and explicitly
  	 specialize a template.  */
!       if (complain)
! 	{
! 	  cp_error ("explicit instantiation of `%#T' after", t);
! 	  cp_error_at ("explicit specialization here", t);
! 	}
        return;
      }
    else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
*************** do_type_instantiation (t, storage)
*** 9339,9345 ****
  	 was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
  	 are we already got marked as an explicit instantion because of the
  	 repo file.  All these cases are OK.  */
!       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository)
  	cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
        /* If we've already instantiated the template, just return now.  */
--- 9349,9356 ----
  	 was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
  	 are we already got marked as an explicit instantion because of the
  	 repo file.  All these cases are OK.  */
!       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
! 	  && complain)
  	cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
        
        /* If we've already instantiated the template, just return now.  */
*************** do_type_instantiation (t, storage)
*** 9398,9404 ****
      for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (IS_AGGR_TYPE (TREE_VALUE (tmp))
  	  && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))
! 	do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage);
    }
  }
  
--- 9409,9415 ----
      for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
        if (IS_AGGR_TYPE (TREE_VALUE (tmp))
  	  && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))
! 	do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage, 0);
    }
  }
  

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