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 for templates/conversion operators



Here's a patch that improves the handling of LOOKUP_EXPRs to make the
following test case work:

  template<class T>
  class A {
  public:
    operator const T*() const;
    const T* cast() const;
  };
  
  template<class T>
  const T* A<T>::cast() const {
    return operator const T*();
  }
  
  template class A<char>;

I've also improved a copule of error messages.

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

1998-08-02  Mark Mitchell  <mark@markmitchell.com>

	* cp-tree.def (LOOKUP_EXPR): Document.  Remove second argument.
	* cp-tree.h (DECL_TI_TEMPLATE): Improve documentation.
	* lex.c (do_identifier): Don't use a second argument, or a type,
	when building LOOKUP_EXPRs.
	(do_identifier): Likewise.
	(do_scoped_id): Likewise.
	* pt.c (lookup_template_function): Don't needlessly call
	copy_to_permanent or build_min.
	(tsubst_copy): Remove #if 0'd code.  Tsubst into LOOKUP_EXPRs if
	necessary.
	* tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy.

Index: testsuite/g++.old-deja/g++.pt/conv2.C
===================================================================
RCS file: conv2.C
diff -N conv2.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- conv2.C	Sun Aug  2 21:09:51 1998
***************
*** 0 ****
--- 1,15 ----
+ // Build don't link:
+ 
+ template<class T>
+ class A {
+ public:
+   operator const T*() const;
+   const T* cast() const;
+ };
+ 
+ template<class T>
+ const T* A<T>::cast() const {
+   return operator const T*();
+ }
+ 
+ template class A<char>;
Index: cp/cp-tree.def
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.def,v
retrieving revision 1.18
diff -c -p -r1.18 cp-tree.def
*** cp-tree.def	1998/06/12 09:46:58	1.18
--- cp-tree.def	1998/08/03 04:11:05
*************** DEFTREECODE (WRAPPER, "wrapper", 'x', 1)
*** 182,190 ****
  /* A node to remember a source position.  */
  DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
  
  /* A whole bunch of tree codes for the initial, superficial parsing of
     templates.  */
- DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2)
  DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3)
  DEFTREECODE (CAST_EXPR, "cast_expr", '1', 1)
  DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1)
--- 182,195 ----
  /* A node to remember a source position.  */
  DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
  
+ /* Used to represent deferred name lookup for dependent names while
+    parsing a template declaration.  The first argument is an
+    IDENTIFIER_NODE for the name in question.  The TREE_TYPE is
+    unused.  */
+ DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1)
+ 
  /* A whole bunch of tree codes for the initial, superficial parsing of
     templates.  */
  DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3)
  DEFTREECODE (CAST_EXPR, "cast_expr", '1', 1)
  DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1)
Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.105
diff -c -p -r1.105 cp-tree.h
*** cp-tree.h	1998/07/31 15:01:13	1.105
--- cp-tree.h	1998/08/03 04:11:21
*************** struct lang_decl
*** 1265,1272 ****
  
     As a special case, for a member friend template of a template
     class, this value will not be a TEMPLATE_DECL, but rather a
!    LOOKUP_EXPR indicating the name of the template and any explicit
!    template arguments provided.  For example, in:
  
       template <class T> struct S { friend void f<int>(int, double); }
  
--- 1265,1272 ----
  
     As a special case, for a member friend template of a template
     class, this value will not be a TEMPLATE_DECL, but rather a
!    LOOKUP_EXPR or IDENTIFIER_NODE indicating the name of the template
!    and any explicit template arguments provided.  For example, in:
  
       template <class T> struct S { friend void f<int>(int, double); }
  
Index: cp/lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.59
diff -c -p -r1.59 lex.c
*** lex.c	1998/07/27 12:37:16	1.59
--- lex.c	1998/08/03 04:12:19
*************** do_identifier (token, parsing, args)
*** 2891,2897 ****
  	}
  
        if (current_template_parms)
! 	return build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
        else if (IDENTIFIER_OPNAME_P (token))
  	{
  	  if (token != ansi_opname[ERROR_MARK])
--- 2891,2897 ----
  	}
  
        if (current_template_parms)
! 	return build_min_nt (LOOKUP_EXPR, token);
        else if (IDENTIFIER_OPNAME_P (token))
  	{
  	  if (token != ansi_opname[ERROR_MARK])
*************** do_identifier (token, parsing, args)
*** 2988,3008 ****
    else
      id = hack_identifier (id, token);
  
!   if (current_template_parms)
!     {
!       if (is_overloaded_fn (id))
! 	{
! 	  tree t = build_min (LOOKUP_EXPR, unknown_type_node,
! 			      token, get_first_fn (id));
! 	  if (id != IDENTIFIER_NAMESPACE_VALUE (token))
! 	    TREE_OPERAND (t, 1) = error_mark_node;
! 	  id = t;
! 	}
!       else if (! TREE_PERMANENT (id) || TREE_CODE (id) == PARM_DECL
! 	       || TREE_CODE (id) == USING_DECL)
! 	id = build_min (LOOKUP_EXPR, TREE_TYPE (id), token, error_mark_node);
!       /* else just use the decl */
!     }
        
    return id;
  }
--- 2988,2999 ----
    else
      id = hack_identifier (id, token);
  
!   if (current_template_parms
!       && (is_overloaded_fn (id) 
! 	  || !TREE_PERMANENT (id)
! 	  || TREE_CODE (id) == PARM_DECL
! 	  || TREE_CODE (id) == USING_DECL))
!     id = build_min_nt (LOOKUP_EXPR, token);
        
    return id;
  }
*************** do_scoped_id (token, parsing)
*** 3031,3037 ****
      {
        if (processing_template_decl)
  	{
! 	  id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
  	  LOOKUP_EXPR_GLOBAL (id) = 1;
  	  return id;
  	}
--- 3022,3028 ----
      {
        if (processing_template_decl)
  	{
! 	  id = build_min_nt (LOOKUP_EXPR, token);
  	  LOOKUP_EXPR_GLOBAL (id) = 1;
  	  return id;
  	}
*************** do_scoped_id (token, parsing)
*** 3068,3076 ****
      {
        if (is_overloaded_fn (id))
  	{
! 	  id = build_min (LOOKUP_EXPR, unknown_type_node,
! 			  token, get_first_fn (id));
  	  LOOKUP_EXPR_GLOBAL (id) = 1;
  	}
        /* else just use the decl */
      }
--- 3059,3067 ----
      {
        if (is_overloaded_fn (id))
  	{
! 	  id = build_min_nt (LOOKUP_EXPR, token);
  	  LOOKUP_EXPR_GLOBAL (id) = 1;
+ 	  return id;
  	}
        /* else just use the decl */
      }
Index: cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.171
diff -c -p -r1.171 pt.c
*** pt.c	1998/07/31 15:01:17	1.171
--- pt.c	1998/08/03 04:13:20
*************** lookup_template_function (fns, arglist)
*** 2999,3012 ****
        return error_mark_node;
      }
  
-   if (arglist != NULL_TREE && !TREE_PERMANENT (arglist))
-     copy_to_permanent (arglist);
- 
    type = TREE_TYPE (fns);
    if (TREE_CODE (fns) == OVERLOAD || !type)
      type = unknown_type_node;
  
!   return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);  
  }
  
  /* Within the scope of a template class S<T>, the name S gets bound
--- 2999,3012 ----
        return error_mark_node;
      }
  
    type = TREE_TYPE (fns);
    if (TREE_CODE (fns) == OVERLOAD || !type)
      type = unknown_type_node;
  
!   if (processing_template_decl)
!     return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);  
!   else
!     return build (TEMPLATE_ID_EXPR, type, fns, arglist);
  }
  
  /* Within the scope of a template class S<T>, the name S gets bound
*************** tsubst_copy (t, args, in_decl)
*** 5469,5479 ****
        else
  	return t;
  
! #if 0
!     case IDENTIFIER_NODE:
!       return do_identifier (t, 0);
! #endif
!       
      case CAST_EXPR:
      case REINTERPRET_CAST_EXPR:
      case CONST_CAST_EXPR:
--- 5469,5493 ----
        else
  	return t;
  
!     case LOOKUP_EXPR:
!       {
! 	/* We must tsbust into a LOOKUP_EXPR in case the names to
! 	   which it refers is a conversion operator; in that case the
! 	   name will change.  We avoid making unnecessary copies,
! 	   however.  */
! 	
! 	tree id = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl);
! 
! 	if (id != TREE_OPERAND (t, 0))
! 	  {
! 	    tree r = build_nt (LOOKUP_EXPR, id);
! 	    LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t);
! 	    t = r;
! 	  }
! 
! 	return t;
!       }
! 
      case CAST_EXPR:
      case REINTERPRET_CAST_EXPR:
      case CONST_CAST_EXPR:
Index: cp/tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.54
diff -c -p -r1.54 tree.c
*** tree.c	1998/07/27 14:38:08	1.54
--- tree.c	1998/08/03 04:13:28
*************** mapcar (t, func)
*** 1784,1789 ****
--- 1784,1794 ----
        TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
        return t;
  
+     case LOOKUP_EXPR:
+       t = copy_node (t);
+       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
+       return t;
+ 
      case RECORD_TYPE:
        if (TYPE_PTRMEMFUNC_P (t))
  	return build_ptrmemfunc_type
cvs server: Diffing cp/inc


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