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]
Other format: [Raw text]

[C++ PATCH,committed] Fix PR13520 (default template template argumentparsing)


Hi

This patch fixes a 3.4 regression PR13520.  Here the parser correctly
builds tree nodes representing types and non-types that are qualified id
with dependent scope (which are TYPENAME_TYPE and SCOPE_REF, respectively).
However, it fails to handle the template case (which is
UNBOUND_CLASS_TEMPLATE).  This patch updates cp_parser_lookup_name by
adding a new parameter 'is_template' to deal with this situation.
I also update DECL_FUNCTION_TEMPLATE_P and DECL_CLASS_TEMPLATE_P to 
correctly deal with UNBOUND_CLASS_TEMPLATE tree node.

Tested on i686-pc-linux-gnu.  Applied to main trunk as obvious.

--Kriang


2004-01-02  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/13520
	* cp-tree.h (DECL_UNBOUND_CLASS_TEMPLATE_P): New macro.
	(DECL_FUNCTION_TEMPLATE_P): Use it.
	(DECL_CLASS_TEMPLATE_P): Likewise.
	* parser.c (cp_parser_lookup_name): Add is_template parameter.
	(cp_parser_type_parameter): Adjust call to cp_parser_lookup_name.
	(cp_parser_template_name): Likewise.
	(cp_parser_elaborated_type_specifier): Likewise.
	(cp_parser_namespace_name): Likewise.
	(cp_parser_class_name): Likewise.
	(cp_parser_lookup_name_simple): Likewise.

2004-01-02  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/13520
	* g++.dg/template/qualttp22.C: New test.


diff -cprN gcc-main-save/gcc/cp/cp-tree.h gcc-main-new/gcc/cp/cp-tree.h
*** gcc-main-save/gcc/cp/cp-tree.h	Mon Dec 29 17:16:28 2003
--- gcc-main-new/gcc/cp/cp-tree.h	Fri Jan  2 18:09:09 2004
***************
*** 1,6 ****
  /* Definitions for C++ parsing and type checking.
     Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
!    2000, 2001, 2002, 2003 Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
--- 1,6 ----
  /* Definitions for C++ parsing and type checking.
     Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
!    2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
*************** struct lang_decl GTY(())
*** 2720,2732 ****
--- 2720,2739 ----
  #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
    (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
  
+ /* Nonzero if NODE is a TEMPLATE_DECL representing an
+    UNBOUND_CLASS_TEMPLATE tree node.  */
+ #define DECL_UNBOUND_CLASS_TEMPLATE_P(NODE) \
+   (TREE_CODE (NODE) == TEMPLATE_DECL && !DECL_TEMPLATE_RESULT (NODE))
+ 
  #define DECL_FUNCTION_TEMPLATE_P(NODE)  \
    (TREE_CODE (NODE) == TEMPLATE_DECL \
+    && !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \
     && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
  
  /* Nonzero for a DECL that represents a template class.  */
  #define DECL_CLASS_TEMPLATE_P(NODE) \
    (TREE_CODE (NODE) == TEMPLATE_DECL \
+    && !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \
     && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \
     && !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE))
  
diff -cprN gcc-main-save/gcc/cp/parser.c gcc-main-new/gcc/cp/parser.c
*** gcc-main-save/gcc/cp/parser.c	Mon Dec 29 17:17:14 2003
--- gcc-main-new/gcc/cp/parser.c	Fri Jan  2 18:09:22 2004
***************
*** 1,5 ****
  /* C++ Parser.
!    Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
     Written by Mark Mitchell <mark@codesourcery.com>.
  
     This file is part of GCC.
--- 1,5 ----
  /* C++ Parser.
!    Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
     Written by Mark Mitchell <mark@codesourcery.com>.
  
     This file is part of GCC.
*************** static void cp_parser_label_declaration
*** 1621,1627 ****
  /* Utility Routines */
  
  static tree cp_parser_lookup_name
!   (cp_parser *, tree, bool, bool, bool);
  static tree cp_parser_lookup_name_simple
    (cp_parser *, tree);
  static tree cp_parser_maybe_treat_template_as_class
--- 1621,1627 ----
  /* Utility Routines */
  
  static tree cp_parser_lookup_name
!   (cp_parser *, tree, bool, bool, bool, bool);
  static tree cp_parser_lookup_name_simple
    (cp_parser *, tree);
  static tree cp_parser_maybe_treat_template_as_class
*************** cp_parser_type_parameter (cp_parser* par
*** 7660,7665 ****
--- 7660,7667 ----
  	   default-argument.  */
  	if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
  	  {
+ 	    bool is_template;
+ 
  	    /* Consume the `='.  */
  	    cp_lexer_consume_token (parser->lexer);
  	    /* Parse the id-expression.  */
*************** cp_parser_type_parameter (cp_parser* par
*** 7667,7677 ****
  	      = cp_parser_id_expression (parser,
  					 /*template_keyword_p=*/false,
  					 /*check_dependency_p=*/true,
! 					 /*template_p=*/NULL,
  					 /*declarator_p=*/false);
  	    /* Look up the name.  */
  	    default_argument 
! 	      = cp_parser_lookup_name_simple (parser, default_argument);
  	    /* See if the default argument is valid.  */
  	    default_argument
  	      = check_template_template_default_arg (default_argument);
--- 7669,7683 ----
  	      = cp_parser_id_expression (parser,
  					 /*template_keyword_p=*/false,
  					 /*check_dependency_p=*/true,
! 					 /*template_p=*/&is_template,
  					 /*declarator_p=*/false);
  	    /* Look up the name.  */
  	    default_argument 
! 	      = cp_parser_lookup_name (parser, default_argument,
! 				       /*is_type=*/false,
! 				       /*is_template=*/is_template,
! 				       /*is_namespace=*/false,
! 				       /*check_dependency=*/true);
  	    /* See if the default argument is valid.  */
  	    default_argument
  	      = check_template_template_default_arg (default_argument);
*************** cp_parser_template_name (cp_parser* pars
*** 7979,7984 ****
--- 7985,7991 ----
    /* Look up the name.  */
    decl = cp_parser_lookup_name (parser, identifier,
  				/*is_type=*/false,
+ 				/*is_template=*/false,
  				/*is_namespace=*/false,
  				check_dependency_p);
    decl = maybe_get_template_decl_from_type_decl (decl);
*************** cp_parser_elaborated_type_specifier (cp_
*** 8934,8939 ****
--- 8941,8947 ----
  	     cp_parser_lookup_name.  */
  	  decl = cp_parser_lookup_name (parser, identifier, 
  					/*is_type=*/true,
+ 					/*is_template=*/false,
  					/*is_namespace=*/false,
  					/*check_dependency=*/true);
  
*************** cp_parser_namespace_name (cp_parser* par
*** 9206,9211 ****
--- 9214,9220 ----
       operator.)  */
    namespace_decl = cp_parser_lookup_name (parser, identifier,
  					  /*is_type=*/false,
+ 					  /*is_template=*/false,
  					  /*is_namespace=*/true,
  					  /*check_dependency=*/true);
    /* If it's not a namespace, issue an error.  */
*************** cp_parser_class_name (cp_parser *parser,
*** 11414,11419 ****
--- 11423,11429 ----
  	  /* Look up the name.  */
  	  decl = cp_parser_lookup_name (parser, identifier, 
  					type_p,
+ 					/*is_template=*/false,
  					/*is_namespace=*/false,
  					check_dependency_p);
  	}
*************** cp_parser_label_declaration (cp_parser* 
*** 13245,13250 ****
--- 13255,13263 ----
     If IS_TYPE is TRUE, bindings that do not refer to types are
     ignored.
  
+    If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
+    ignored.
+ 
     If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
     are ignored.
  
*************** cp_parser_label_declaration (cp_parser* 
*** 13253,13259 ****
  
  static tree
  cp_parser_lookup_name (cp_parser *parser, tree name, 
! 		       bool is_type, bool is_namespace, bool check_dependency)
  {
    tree decl;
    tree object_type = parser->context->object_type;
--- 13266,13273 ----
  
  static tree
  cp_parser_lookup_name (cp_parser *parser, tree name, 
! 		       bool is_type, bool is_template, bool is_namespace,
! 		       bool check_dependency)
  {
    tree decl;
    tree object_type = parser->context->object_type;
*************** cp_parser_lookup_name (cp_parser *parser
*** 13325,13339 ****
        if ((check_dependency || !CLASS_TYPE_P (parser->scope))
  	   && dependent_p)
  	{
! 	  if (!is_type)
! 	    decl = build_nt (SCOPE_REF, parser->scope, name);
! 	  else
  	    /* The resolution to Core Issue 180 says that `struct A::B'
  	       should be considered a type-name, even if `A' is
  	       dependent.  */
  	    decl = TYPE_NAME (make_typename_type (parser->scope,
  						  name,
  						  /*complain=*/1));
  	}
        else
  	{
--- 13339,13357 ----
        if ((check_dependency || !CLASS_TYPE_P (parser->scope))
  	   && dependent_p)
  	{
! 	  if (is_type)
  	    /* The resolution to Core Issue 180 says that `struct A::B'
  	       should be considered a type-name, even if `A' is
  	       dependent.  */
  	    decl = TYPE_NAME (make_typename_type (parser->scope,
  						  name,
  						  /*complain=*/1));
+ 	  else if (is_template)
+ 	    decl = TYPE_NAME (make_unbound_class_template (parser->scope,
+ 							   name,
+ 							   /*complain=*/1));
+ 	  else
+ 	    decl = build_nt (SCOPE_REF, parser->scope, name);
  	}
        else
  	{
*************** cp_parser_lookup_name (cp_parser *parser
*** 13427,13440 ****
  }
  
  /* Like cp_parser_lookup_name, but for use in the typical case where
!    CHECK_ACCESS is TRUE, IS_TYPE is FALSE, and CHECK_DEPENDENCY is
!    TRUE.  */
  
  static tree
  cp_parser_lookup_name_simple (cp_parser* parser, tree name)
  {
    return cp_parser_lookup_name (parser, name, 
  				/*is_type=*/false,
  				/*is_namespace=*/false,
  				/*check_dependency=*/true);
  }
--- 13445,13459 ----
  }
  
  /* Like cp_parser_lookup_name, but for use in the typical case where
!    CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
!    IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE.  */
  
  static tree
  cp_parser_lookup_name_simple (cp_parser* parser, tree name)
  {
    return cp_parser_lookup_name (parser, name, 
  				/*is_type=*/false,
+ 				/*is_template=*/false,
  				/*is_namespace=*/false,
  				/*check_dependency=*/true);
  }
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/qualttp22.C gcc-main-new/gcc/testsuite/g++.dg/template/qualttp22.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/qualttp22.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/qualttp22.C	Fri Jan  2 17:15:10 2004
***************
*** 0 ****
--- 1,28 ----
+ // { dg-do compile }
+ 
+ // Origin: Philippe Van Deyck <hetadres@email.com>
+ 
+ // PR c++/13520: Default template template argument that is a qualified id
+ // with dependent scope.
+ 
+ template<typename regular_type> class Policy {};
+ 
+ template <typename regular_type, template<typename> class OriginalPolicy>
+ class ChangedPolicy_impl {};
+ 
+ template <template<typename> class OriginalPolicy > class ChangedPolicy {
+ public:
+   template<typename regular_type> class Type : public 
+   ChangedPolicy_impl<regular_type,OriginalPolicy> { };
+ };
+ 
+ template <typename regular_type, template<typename> class Policy1,
+ 	  template<typename> class Policy2
+ 	    = ChangedPolicy<Policy1>::template Type>
+ class Host : public Policy1<regular_type>, public Policy2<regular_type> { };
+ 
+ int main()
+ {
+   Host<void, Policy> h;
+   return 0;
+ }



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