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: Remove LOOKUP_EXPR


Nathan and I noticed yesterday that there's no need to create
LOOKUP_EXPRs, thanks to the new parser and the template clean-ups.

So, this patch removes them completely, which saves one tree node per
use of an unqualified name in a template.  I don't have any hard data
about what that does to compile time or memory usage.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-07-15  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.def (LOOKUP_EXPR): Remove.
	* cp-tree.h (cp_id_kind): Add CP_ID_KIND_UNQUALIFIED_DEPENDENT.
	(LOOKUP_EXPR_GLOBAL): Remove.
	(get_bindings): Remove.
	(is_aggr_type_2): Remove.
	* call.c (resolved_scoped_fn_name): Remove support for
	LOOKUP_EXPR.
	* decl.c (grokfndecl): Likewise.
	(grokdeclarator): Likewise.
	* error.c (dump_decl): Likewise.
	(dump_expr): Likewise.
	* friend.c (do_friend): Likewise.
	* init.c (build_offset_ref): Likewise.
	* lex.c (unqualified_fn_lookup_error): Use pedwarn.  Do not create
	LOOKUP_EXPRs 
	* mangle.c (write_expression): Remove support for LOOKUP_EXPR.
	* parser.c (cp_parser_postfix_expression): Modify Koenig lookup
	test.
	* pt.c (get_bindings): Give it internal linkage.
	(check_explicit_specialization): Remove support for LOOKUP_EXPR.
	(lookup_template_function): Likewise.
	(for_each_template_parm_r): Likewise.
	(tsubst_decl): Likewise.
	(tsubst_qualified_id): Handle template template parameters.
	(tsubst_copy): Remove support for LOOKUP_EXPR.
	(tsubst_copy_and_build): Likewise.
	(most_general_template): Likewise.
	(value_dependent_expression_p): Likewise.
	(type_dependent_expression_p): Note that IDENTIFIER_NODEs are
	always dependent.
	* semantics.c (perform_koenig_lookup): Do not create
	IDENTIFIER_NODEs.
	(finish_fname): Likewise.
	(finish_id_expression): Likewise.
	* tree.c (is_aggr_type_2): Remove.
	
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.407
diff -c -5 -p -r1.407 call.c
*** cp/call.c	14 Jul 2003 17:45:07 -0000	1.407
--- cp/call.c	16 Jul 2003 00:02:28 -0000
*************** build_user_type_conversion (tree totype,
*** 2605,2615 ****
    return NULL_TREE;
  }
  
  /* Find the possibly overloaded set of functions corresponding to a
     call of the form SCOPE::NAME (...). NAME might be a
!    TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR.  */
  
  tree
  resolve_scoped_fn_name (tree scope, tree name)
  {
    tree fn = NULL_TREE;
--- 2605,2615 ----
    return NULL_TREE;
  }
  
  /* Find the possibly overloaded set of functions corresponding to a
     call of the form SCOPE::NAME (...). NAME might be a
!    TEMPLATE_ID_EXPR, OVERLOAD, _DECL, or IDENTIFIER_NODE.  */
  
  tree
  resolve_scoped_fn_name (tree scope, tree name)
  {
    tree fn = NULL_TREE;
*************** resolve_scoped_fn_name (tree scope, tree
*** 2621,2632 ****
        template_args = TREE_OPERAND (name, 1);
        name = TREE_OPERAND (name, 0);
      }
    if (TREE_CODE (name) == OVERLOAD)
      name = DECL_NAME (get_first_fn (name));
-   else if (TREE_CODE (name) == LOOKUP_EXPR)
-     name = TREE_OPERAND (name, 0);
    
    if (TREE_CODE (scope) == NAMESPACE_DECL)
      fn = lookup_namespace_name (scope, name);
    else if (!CLASS_TYPE_P (scope))
      {
--- 2621,2630 ----
Index: cp/cp-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.def,v
retrieving revision 1.76
diff -c -5 -p -r1.76 cp-tree.def
*** cp/cp-tree.def	9 Jul 2003 08:47:58 -0000	1.76
--- cp/cp-tree.def	16 Jul 2003 00:02:28 -0000
*************** DEFTREECODE (DEFAULT_ARG, "default_arg",
*** 206,232 ****
  
  /* A template-id, like foo<int>.  The first operand is the template.
     The second is the TREE_LIST or TREE_VEC of explicitly specified
     arguments.  The template will be a FUNCTION_DECL, TEMPLATE_DECL, or
     an OVERLOAD.  If the template-id refers to a member template, the
!    template may be an IDENTIFIER_NODE.  In an uninstantiated template,
!    the template may be a LOOKUP_EXPR.  */
  DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
  
  /* A list-like node for chaining overloading candidates. TREE_TYPE is 
     the original name, and the parameter is the FUNCTION_DECL.  */
  DEFTREECODE (OVERLOAD, "overload", 'x', 0)
  
  /* A generic wrapper for something not tree that we want to include in
     tree structure.  */
  DEFTREECODE (WRAPPER, "wrapper", 'x', 0)
- 
- /* 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)
--- 206,225 ----
  
  /* A template-id, like foo<int>.  The first operand is the template.
     The second is the TREE_LIST or TREE_VEC of explicitly specified
     arguments.  The template will be a FUNCTION_DECL, TEMPLATE_DECL, or
     an OVERLOAD.  If the template-id refers to a member template, the
!    template may be an IDENTIFIER_NODE.  */
  DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
  
  /* A list-like node for chaining overloading candidates. TREE_TYPE is 
     the original name, and the parameter is the FUNCTION_DECL.  */
  DEFTREECODE (OVERLOAD, "overload", 'x', 0)
  
  /* A generic wrapper for something not tree that we want to include in
     tree structure.  */
  DEFTREECODE (WRAPPER, "wrapper", 'x', 0)
  
  /* 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)
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.877
diff -c -5 -p -r1.877 cp-tree.h
*** cp/cp-tree.h	14 Jul 2003 19:05:01 -0000	1.877
--- cp/cp-tree.h	16 Jul 2003 00:02:28 -0000
*************** struct diagnostic_context;
*** 37,47 ****
  /* Usage of TREE_LANG_FLAG_?:
     0: BINFO_MARKED (BINFO nodes).
        IDENTIFIER_MARKED (IDENTIFIER_NODEs)
        NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
        DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
-       LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
        TREE_INDIRECT_USING (in NAMESPACE_DECL).
        ICS_USER_FLAG (in _CONV)
        CLEANUP_P (in TRY_BLOCK)
        AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
        PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
--- 37,46 ----
*************** typedef enum cp_id_kind
*** 357,366 ****
--- 356,367 ----
  {
    /* Not an id at all.  */
    CP_ID_KIND_NONE,
    /* An unqualified-id that is not a template-id.  */
    CP_ID_KIND_UNQUALIFIED,
+   /* An uqualified-id that is a dependent name.  */
+   CP_ID_KIND_UNQUALIFIED_DEPENDENT,
    /* An unqualified template-id.  */
    CP_ID_KIND_TEMPLATE_ID,
    /* A qualified-id.  */
    CP_ID_KIND_QUALIFIED
  } cp_id_kind;
*************** struct lang_decl GTY(())
*** 2255,2272 ****
  
     the FUNCTION_DECL for S<int>::f<double> will have, as its
     DECL_TI_TEMPLATE, `template <class U> S<int>::f<U>'.
  
     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, IDENTIFIER_NODE or OVERLOAD 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); }
  
!    the DECL_TI_TEMPLATE will be a LOOKUP_EXPR for `f' and the
     DECL_TI_ARGS will be {int}.  */
  #define DECL_TI_TEMPLATE(NODE)      TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
  
  /* The template arguments used to obtain this decl from the most
     general form of DECL_TI_TEMPLATE.  For the example given for
--- 2256,2272 ----
  
     the FUNCTION_DECL for S<int>::f<double> will have, as its
     DECL_TI_TEMPLATE, `template <class U> S<int>::f<U>'.
  
     As a special case, for a member friend template of a template
!    class, this value will not be a TEMPLATE_DECL, but rather an
!    IDENTIFIER_NODE or OVERLOAD 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); }
  
!    the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the
     DECL_TI_ARGS will be {int}.  */
  #define DECL_TI_TEMPLATE(NODE)      TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
  
  /* The template arguments used to obtain this decl from the most
     general form of DECL_TI_TEMPLATE.  For the example given for
*************** struct lang_decl GTY(())
*** 2310,2320 ****
     ->u.f.u.saved_language_function)
  
  #define NEW_EXPR_USE_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
  #define DELETE_EXPR_USE_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
  #define DELETE_EXPR_USE_VEC(NODE)	TREE_LANG_FLAG_1 (NODE)
- #define LOOKUP_EXPR_GLOBAL(NODE)	TREE_LANG_FLAG_0 (NODE)
  
  /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
     constructor call, rather than an ordinary function call.  */
  #define AGGR_INIT_VIA_CTOR_P(NODE) \
    TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))
--- 2310,2319 ----
*************** extern void mark_decl_instantiated		(tre
*** 3963,3973 ****
  extern int more_specialized			(tree, tree, int, int);
  extern void mark_class_instantiated		(tree, int);
  extern void do_decl_instantiation		(tree, tree);
  extern void do_type_instantiation		(tree, tree, tsubst_flags_t);
  extern tree instantiate_decl			(tree, int);
- extern tree get_bindings			(tree, tree, tree);
  extern int push_tinst_level			(tree);
  extern void pop_tinst_level			(void);
  extern int more_specialized_class		(tree, tree, tree);
  extern int is_member_template                   (tree);
  extern int comp_template_parms                  (tree, tree);
--- 3962,3971 ----
*************** extern tree get_first_fn			(tree);
*** 4209,4219 ****
  extern int bound_pmf_p				(tree);
  extern tree ovl_cons                            (tree, tree);
  extern tree build_overload                      (tree, tree);
  extern tree function_arg_chain			(tree);
  extern int promotes_to_aggr_type		(tree, enum tree_code);
- extern int is_aggr_type_2			(tree, tree);
  extern const char *cxx_printable_name		(tree, int);
  extern tree build_exception_variant		(tree, tree);
  extern tree bind_template_template_parm		(tree, tree);
  extern tree array_type_nelts_total		(tree);
  extern tree array_type_nelts_top		(tree);
--- 4207,4216 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1089
diff -c -5 -p -r1.1089 decl.c
*** cp/decl.c	14 Jul 2003 19:05:01 -0000	1.1089
--- cp/decl.c	16 Jul 2003 00:02:29 -0000
*************** grokfndecl (tree ctype, 
*** 8980,8990 ****
                my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
                                    == current_class_type, 20001120);
                fns = TREE_OPERAND (fns, 1);
              }
  	  my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE
- 	                      || TREE_CODE (fns) == LOOKUP_EXPR
  	                      || TREE_CODE (fns) == OVERLOAD, 20001120);
  	  DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
  
  	  if (has_default_arg)
  	    {
--- 8980,8989 ----
*************** grokdeclarator (tree declarator,
*** 9801,9813 ****
  	    break;
  
  	  case TEMPLATE_ID_EXPR:
  	      {
  		tree fns = TREE_OPERAND (decl, 0);
- 
- 		if (TREE_CODE (fns) == LOOKUP_EXPR)
- 		  fns = TREE_OPERAND (fns, 0);
  
  		dname = fns;
  		if (TREE_CODE (dname) == COMPONENT_REF)
  		  dname = TREE_OPERAND (dname, 1);
  		if (TREE_CODE (dname) != IDENTIFIER_NODE)
--- 9800,9809 ----
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/error.c,v
retrieving revision 1.223
diff -c -5 -p -r1.223 error.c
*** cp/error.c	14 Jul 2003 17:45:08 -0000	1.223
--- cp/error.c	16 Jul 2003 00:02:29 -0000
*************** dump_decl (tree t, int flags)
*** 954,967 ****
  	  }
  	print_template_argument_list_end (scratch_buffer);
        }
        break;
  
-     case LOOKUP_EXPR:
-       dump_decl (TREE_OPERAND (t, 0), flags);
-       break;
- 
      case LABEL_DECL:
        print_tree_identifier (scratch_buffer, DECL_NAME (t));
        break;
  
      case CONST_DECL:
--- 954,963 ----
*************** dump_expr (tree t, int flags)
*** 1953,1966 ****
      cast:
        dump_type (TREE_TYPE (t), flags);
        output_add_string (scratch_buffer, ">(");
        dump_expr (TREE_OPERAND (t, 0), flags);
        print_right_paren (scratch_buffer);
-       break;
- 
-     case LOOKUP_EXPR:
-       print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0));
        break;
  
      case ARROW_EXPR:
        dump_expr (TREE_OPERAND (t, 0), flags);
        output_add_string (scratch_buffer, "->");
--- 1949,1958 ----
Index: cp/friend.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/friend.c,v
retrieving revision 1.85
diff -c -5 -p -r1.85 friend.c
*** cp/friend.c	7 Jul 2003 19:19:07 -0000	1.85
--- cp/friend.c	16 Jul 2003 00:02:29 -0000
*************** do_friend (tree ctype, tree declarator, 
*** 331,342 ****
    DECL_FRIEND_P (decl) = 1;
  
    if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
      {
        declarator = TREE_OPERAND (declarator, 0);
-       if (TREE_CODE (declarator) == LOOKUP_EXPR)
- 	declarator = TREE_OPERAND (declarator, 0);
        if (is_overloaded_fn (declarator))
  	declarator = DECL_NAME (get_first_fn (declarator));
      }
  
    if (TREE_CODE (decl) != FUNCTION_DECL)
--- 331,340 ----
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.330
diff -c -5 -p -r1.330 init.c
*** cp/init.c	9 Jul 2003 08:47:59 -0000	1.330
--- cp/init.c	16 Jul 2003 00:02:29 -0000
*************** build_offset_ref (tree type, tree name)
*** 1372,1391 ****
  
        if (DECL_P (name))
  	name = DECL_NAME (name);
        else
  	{
! 	  if (TREE_CODE (name) == LOOKUP_EXPR)
! 	    /* This can happen during tsubst'ing.  */
! 	    name = TREE_OPERAND (name, 0);
! 	  else
! 	    {
! 	      if (TREE_CODE (name) == COMPONENT_REF)
! 		name = TREE_OPERAND (name, 1);
! 	      if (TREE_CODE (name) == OVERLOAD)
! 		name = DECL_NAME (OVL_CURRENT (name));
! 	    }
  	}
  
        my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
      }
  
--- 1372,1385 ----
  
        if (DECL_P (name))
  	name = DECL_NAME (name);
        else
  	{
! 	  if (TREE_CODE (name) == COMPONENT_REF)
! 	    name = TREE_OPERAND (name, 1);
! 	  if (TREE_CODE (name) == OVERLOAD)
! 	    name = DECL_NAME (OVL_CURRENT (name));
  	}
  
        my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
      }
  
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.311
diff -c -5 -p -r1.311 lex.c
*** cp/lex.c	14 Jul 2003 10:14:51 -0000	1.311
--- cp/lex.c	16 Jul 2003 00:02:29 -0000
*************** unqualified_fn_lookup_error (tree name)
*** 708,721 ****
      {
        /* In a template, it is invalid to write "f()" or "f(3)" if no
  	 declaration of "f" is available.  Historically, G++ and most
  	 other compilers accepted that usage; explain to the user what
  	 is going wrong.  */
!       (flag_permissive ? warning : error)
! 	("there are no arguments to `%D' that depend on a template "
! 	 "parameter, so a declaration of `%D' must be available", name,
! 	 name);
        
        if (!flag_permissive)
  	{
  	  static bool hint;
  	  if (!hint)
--- 708,720 ----
      {
        /* In a template, it is invalid to write "f()" or "f(3)" if no
  	 declaration of "f" is available.  Historically, G++ and most
  	 other compilers accepted that usage; explain to the user what
  	 is going wrong.  */
!       pedwarn ("there are no arguments to `%D' that depend on a template "
! 	       "parameter, so a declaration of `%D' must be available", 
! 	       name, name);
        
        if (!flag_permissive)
  	{
  	  static bool hint;
  	  if (!hint)
*************** unqualified_fn_lookup_error (tree name)
*** 724,734 ****
  		     "but allowing the use of an undeclared name is "
  		     "deprecated)");
  	      hint = true;
  	    }
  	}
!       return build_min_nt (LOOKUP_EXPR, name);
      }
  
    return unqualified_name_lookup_error (name);
  }
  
--- 723,733 ----
  		     "but allowing the use of an undeclared name is "
  		     "deprecated)");
  	      hint = true;
  	    }
  	}
!       return name;
      }
  
    return unqualified_name_lookup_error (name);
  }
  
Index: cp/mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.84
diff -c -5 -p -r1.84 mangle.c
*** cp/mangle.c	9 Jul 2003 08:48:00 -0000	1.84
--- cp/mangle.c	16 Jul 2003 00:02:29 -0000
*************** write_expression (tree expr)
*** 1924,1935 ****
  	     from the arguments.  */
  	  if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
  	    {
  	      template_args = TREE_OPERAND (member, 1);
  	      member = TREE_OPERAND (member, 0);
- 	      if (TREE_CODE (member) == LOOKUP_EXPR)
- 		member = TREE_OPERAND (member, 0);
  	    }
  	  else
  	    template_args = NULL_TREE;
  	  /* Write out the name of the MEMBER.  */
  	  if (IDENTIFIER_TYPENAME_P (member))
--- 1924,1933 ----
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.83
diff -c -5 -p -r1.83 parser.c
*** cp/parser.c	14 Jul 2003 19:05:02 -0000	1.83
--- cp/parser.c	16 Jul 2003 00:02:30 -0000
*************** cp_parser_postfix_expression (cp_parser 
*** 3436,3446 ****
      mark_used (postfix_expression);
  
    /* Keep looping until the postfix-expression is complete.  */
    while (true)
      {
!       if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE
  	  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
  	/* It is not a Koenig lookup function call.  */
  	postfix_expression 
  	  = unqualified_name_lookup_error (postfix_expression);
        
--- 3436,3447 ----
      mark_used (postfix_expression);
  
    /* Keep looping until the postfix-expression is complete.  */
    while (true)
      {
!       if (idk == CP_ID_KIND_UNQUALIFIED
! 	  && TREE_CODE (postfix_expression) == IDENTIFIER_NODE
  	  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
  	/* It is not a Koenig lookup function call.  */
  	postfix_expression 
  	  = unqualified_name_lookup_error (postfix_expression);
        
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.726
diff -c -5 -p -r1.726 pt.c
*** cp/pt.c	14 Jul 2003 21:32:25 -0000	1.726
--- cp/pt.c	16 Jul 2003 00:02:30 -0000
*************** static tree build_template_decl (tree, t
*** 130,139 ****
--- 130,140 ----
  static int mark_template_parm (tree, void *);
  static int template_parm_this_level_p (tree, void *);
  static tree tsubst_friend_function (tree, tree);
  static tree tsubst_friend_class (tree, tree);
  static int can_complete_type_without_circularity (tree);
+ static tree get_bindings (tree, tree, tree);
  static tree get_bindings_real (tree, tree, tree, int, int, int);
  static int template_decl_level (tree);
  static int check_cv_quals_for_unify (int, tree, tree);
  static tree tsubst_template_arg_vector (tree, tree, tsubst_flags_t);
  static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
*************** check_explicit_specialization (tree decl
*** 1637,1655 ****
  	      ;
  	    }
  
  	  return decl;
  	}
-       else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR)
- 	{
- 	  /* A friend declaration.  We can't do much, because we don't
- 	     know what this resolves to, yet.  */
- 	  my_friendly_assert (is_friend != 0, 0);
- 	  my_friendly_assert (!explicit_instantiation, 0);
- 	  SET_DECL_IMPLICIT_INSTANTIATION (decl);
- 	  return decl;
- 	} 
        else if (ctype != NULL_TREE 
  	       && (TREE_CODE (TREE_OPERAND (declarator, 0)) ==
  		   IDENTIFIER_NODE))
  	{
  	  /* Find the list of functions in ctype that have the same
--- 1638,1647 ----
*************** lookup_template_function (tree fns, tree
*** 3903,3914 ****
      }
  
    my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
  		      || TREE_CODE (fns) == OVERLOAD
  		      || BASELINK_P (fns)
! 		      || TREE_CODE (fns) == IDENTIFIER_NODE
! 		      || TREE_CODE (fns) == LOOKUP_EXPR,
  		      20020730);
  
    if (BASELINK_P (fns))
      {
        BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR,
--- 3895,3905 ----
      }
  
    my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
  		      || TREE_CODE (fns) == OVERLOAD
  		      || BASELINK_P (fns)
! 		      || TREE_CODE (fns) == IDENTIFIER_NODE,
  		      20020730);
  
    if (BASELINK_P (fns))
      {
        BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR,
*************** for_each_template_parm_r (tree* tp, int*
*** 4577,4587 ****
      case STATIC_CAST_EXPR:
      case DYNAMIC_CAST_EXPR:
      case ARROW_EXPR:
      case DOTSTAR_EXPR:
      case TYPEID_EXPR:
-     case LOOKUP_EXPR:
      case PSEUDO_DTOR_EXPR:
        if (!fn)
  	return error_mark_node;
        break;
  
--- 4568,4577 ----
*************** tsubst_decl (tree t, tree args, tree typ
*** 5961,5974 ****
  	         template <class T> struct S { 
  		   friend void f<int>(int, double); 
  		 };
  
  	       Here, the DECL_TI_TEMPLATE for the friend declaration
! 	       will be a LOOKUP_EXPR or an IDENTIFIER_NODE.  We are
! 	       being called from tsubst_friend_function, and we want
! 	       only to create a new decl (R) with appropriate types so
! 	       that we can call determine_specialization.  */
  	    gen_tmpl = NULL_TREE;
  	  }
  
  	if (DECL_CLASS_SCOPE_P (t))
  	  {
--- 5951,5964 ----
  	         template <class T> struct S { 
  		   friend void f<int>(int, double); 
  		 };
  
  	       Here, the DECL_TI_TEMPLATE for the friend declaration
! 	       will be an IDENTIFIER_NODE.  We are being called from
! 	       tsubst_friend_function, and we want only to create a
! 	       new decl (R) with appropriate types so that we can call
! 	       determine_specialization.  */
  	    gen_tmpl = NULL_TREE;
  	  }
  
  	if (DECL_CLASS_SCOPE_P (t))
  	  {
*************** tsubst_qualified_id (tree qualified_id, 
*** 7139,7148 ****
--- 7129,7150 ----
        scope = tsubst (scope, args, complain, in_decl);
        expr = tsubst_copy (name, args, complain, in_decl);
      }
    else
      expr = name;
+ 
+   /* This case can occur while determining which of two templates is
+      the more specialized.  After performing argument deduction, we
+      check that no invalid types are created.  During that phase, we
+      may seem uninstantiated template parameters.  */
+   if (TREE_CODE (scope) == BOUND_TEMPLATE_TEMPLATE_PARM)
+     {
+       if (is_template)
+ 	expr = lookup_template_function (expr, template_args);
+       return build_nt (SCOPE_REF, scope, expr);
+     }
+ 
    if (!BASELINK_P (name) && !DECL_P (expr))
      expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0,
  				  (complain & tf_error) != 0);
    if (DECL_P (expr))
      check_accessibility_of_qualified_id (expr, 
*************** tsubst_qualified_id (tree qualified_id, 
*** 7156,7166 ****
        if (!args && TREE_CODE (expr) == VAR_DECL)
  	expr = DECL_INITIAL (expr);
      }
  
    if (is_template)
!     lookup_template_function (expr, template_args);
  
    if (TYPE_P (scope))
      {
        expr = (adjust_result_of_qualified_name_lookup 
  	      (expr, scope, current_class_type));
--- 7158,7168 ----
        if (!args && TREE_CODE (expr) == VAR_DECL)
  	expr = DECL_INITIAL (expr);
      }
  
    if (is_template)
!     expr = lookup_template_function (expr, template_args);
  
    if (TYPE_P (scope))
      {
        expr = (adjust_result_of_qualified_name_lookup 
  	      (expr, scope, current_class_type));
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 7282,7310 ****
  	}
        else
  	/* Ordinary template template argument.  */
  	return t;
  
-     case LOOKUP_EXPR:
-       {
- 	/* We must tsubst 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, complain, in_decl);
- 
- 	if (id != TREE_OPERAND (t, 0))
- 	  {
- 	    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:
      case STATIC_CAST_EXPR:
      case DYNAMIC_CAST_EXPR:
--- 7284,7293 ----
*************** tsubst_copy_and_build (tree t, 
*** 7903,7950 ****
    if (t == NULL_TREE || t == error_mark_node)
      return t;
  
    switch (TREE_CODE (t))
      {
-     case LOOKUP_EXPR:
      case IDENTIFIER_NODE:
        {
  	tree decl;
- 	tree scope;
  	cp_id_kind idk;
  	tree qualifying_class;
  	bool non_constant_expression_p;
  	const char *error_msg;
  
- 	/* Remember whether this identifier was explicitly qualified
- 	   with "::".  */
- 	if (TREE_CODE (t) == LOOKUP_EXPR && LOOKUP_EXPR_GLOBAL (t))
- 	  scope = global_namespace;
- 	else
- 	  scope = NULL_TREE;
- 	/* Get at the underlying identifier.  */
- 	if (TREE_CODE (t) == LOOKUP_EXPR)
- 	  t = TREE_OPERAND (t, 0);
- 
  	if (IDENTIFIER_TYPENAME_P (t))
  	  {
  	    tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
  	    t = mangle_conv_op_name_for_type (new_type);
  	  }
  
  	/* Look up the name.  */
! 	if (scope == global_namespace)
! 	  decl = IDENTIFIER_GLOBAL_VALUE (t);
! 	else
! 	  decl = lookup_name (t, 0);
  
  	/* By convention, expressions use ERROR_MARK_NODE to indicate
  	   failure, not NULL_TREE.  */
  	if (decl == NULL_TREE)
  	  decl = error_mark_node;
  
! 	decl = finish_id_expression (t, decl, scope,
  				     &idk,
  				     &qualifying_class,
  				     /*constant_expression_p=*/false,
  				     /*allow_non_constant_expression_p=*/false,
  				     &non_constant_expression_p,
--- 7886,7918 ----
    if (t == NULL_TREE || t == error_mark_node)
      return t;
  
    switch (TREE_CODE (t))
      {
      case IDENTIFIER_NODE:
        {
  	tree decl;
  	cp_id_kind idk;
  	tree qualifying_class;
  	bool non_constant_expression_p;
  	const char *error_msg;
  
  	if (IDENTIFIER_TYPENAME_P (t))
  	  {
  	    tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
  	    t = mangle_conv_op_name_for_type (new_type);
  	  }
  
  	/* Look up the name.  */
! 	decl = lookup_name (t, 0);
  
  	/* By convention, expressions use ERROR_MARK_NODE to indicate
  	   failure, not NULL_TREE.  */
  	if (decl == NULL_TREE)
  	  decl = error_mark_node;
  
! 	decl = finish_id_expression (t, decl, NULL_TREE,
  				     &idk,
  				     &qualifying_class,
  				     /*constant_expression_p=*/false,
  				     /*allow_non_constant_expression_p=*/false,
  				     &non_constant_expression_p,
*************** most_general_template (tree decl)
*** 10199,10210 ****
      }
  
    /* Look for more and more general templates.  */
    while (DECL_TEMPLATE_INFO (decl))
      {
!       /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or IDENTIFIER_NODE
! 	 in some cases.  (See cp-tree.h for details.)  */
        if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
  	break;
  
        if (CLASS_TYPE_P (TREE_TYPE (decl))
  	  && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
--- 10167,10178 ----
      }
  
    /* Look for more and more general templates.  */
    while (DECL_TEMPLATE_INFO (decl))
      {
!       /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases.
! 	 (See cp-tree.h for details.)  */
        if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
  	break;
  
        if (CLASS_TYPE_P (TREE_TYPE (decl))
  	  && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
*************** value_dependent_expression_p (tree expre
*** 11489,11499 ****
  {
    if (!processing_template_decl)
      return false;
  
    /* A name declared with a dependent type.  */
!   if (TREE_CODE (expression) == LOOKUP_EXPR
        || (DECL_P (expression) 
  	  && type_dependent_expression_p (expression)))
      return true;
    /* A non-type template parameter.  */
    if ((TREE_CODE (expression) == CONST_DECL
--- 11457,11467 ----
  {
    if (!processing_template_decl)
      return false;
  
    /* A name declared with a dependent type.  */
!   if (TREE_CODE (expression) == IDENTIFIER_NODE
        || (DECL_P (expression) 
  	  && type_dependent_expression_p (expression)))
      return true;
    /* A non-type template parameter.  */
    if ((TREE_CODE (expression) == CONST_DECL
*************** type_dependent_expression_p (tree expres
*** 11591,11600 ****
--- 11559,11572 ----
    if (!processing_template_decl)
      return false;
  
    if (expression == error_mark_node)
      return false;
+ 
+   /* An unresolved name is always dependent.  */
+   if (TREE_CODE (expression) == IDENTIFIER_NODE)
+     return true;
    
    /* Some expression forms are never type-dependent.  */
    if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
        || TREE_CODE (expression) == SIZEOF_EXPR
        || TREE_CODE (expression) == ALIGNOF_EXPR
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.327
diff -c -5 -p -r1.327 semantics.c
*** cp/semantics.c	14 Jul 2003 19:05:02 -0000	1.327
--- cp/semantics.c	16 Jul 2003 00:02:30 -0000
*************** perform_koenig_lookup (tree fn, tree arg
*** 1510,1520 ****
        if (!fn)
  	/* The unqualified name could not be resolved.  */
  	fn = unqualified_fn_lookup_error (identifier);
      }
    else
!     fn = build_min_nt (LOOKUP_EXPR, identifier);
  
    return fn;
  }
  
  /* Generate an expression for `FN (ARGS)'.
--- 1510,1520 ----
        if (!fn)
  	/* The unqualified name could not be resolved.  */
  	fn = unqualified_fn_lookup_error (identifier);
      }
    else
!     fn = identifier;
  
    return fn;
  }
  
  /* Generate an expression for `FN (ARGS)'.
*************** finish_fname (tree id)
*** 1817,1827 ****
  {
    tree decl;
    
    decl = fname_decl (C_RID_CODE (id), id);
    if (processing_template_decl)
!     decl = build_min_nt (LOOKUP_EXPR, DECL_NAME (decl));
    return decl;
  }
  
  /* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
     and DECLARATOR.  Returns nonzero if the function-declaration is
--- 1817,1827 ----
  {
    tree decl;
    
    decl = fname_decl (C_RID_CODE (id), id);
    if (processing_template_decl)
!     decl = DECL_NAME (decl);
    return decl;
  }
  
  /* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
     and DECLARATOR.  Returns nonzero if the function-declaration is
*************** finish_id_expression (tree id_expression
*** 2370,2385 ****
        /* [temp.dep.expr]
  
  	 An id-expression is type-dependent if it contains an
  	 identifier that was declared with a dependent type.
  
- 	 As an optimization, we could choose not to create a
- 	 LOOKUP_EXPR for a name that resolved to a local variable in
- 	 the template function that we are currently declaring; such a
- 	 name cannot ever resolve to anything else.  If we did that we
- 	 would not have to look up these names at instantiation time.
- 
  	 The standard is not very specific about an id-expression that
  	 names a set of overloaded functions.  What if some of them
  	 have dependent types and some of them do not?  Presumably,
  	 such a name should be treated as a dependent name.  */
        /* Assume the name is not dependent.  */
--- 2370,2379 ----
*************** finish_id_expression (tree id_expression
*** 2467,2478 ****
  	  /* Since this name was dependent, the expression isn't
  	     constant -- yet.  No error is issued because it might be
  	     constant when things are instantiated.  */
  	  if (constant_expression_p)
  	    *non_constant_expression_p = true;
! 	  /* Create a LOOKUP_EXPR for other unqualified names.  */
! 	  return build_min_nt (LOOKUP_EXPR, id_expression);
  	}
  
        /* Only certain kinds of names are allowed in constant
  	 expression.  Enumerators have already been handled above.  */
        if (constant_expression_p)
--- 2461,2472 ----
  	  /* Since this name was dependent, the expression isn't
  	     constant -- yet.  No error is issued because it might be
  	     constant when things are instantiated.  */
  	  if (constant_expression_p)
  	    *non_constant_expression_p = true;
! 	  *idk = CP_ID_KIND_UNQUALIFIED_DEPENDENT;
! 	  return id_expression;
  	}
  
        /* Only certain kinds of names are allowed in constant
  	 expression.  Enumerators have already been handled above.  */
        if (constant_expression_p)
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.336
diff -c -5 -p -r1.336 tree.c
*** cp/tree.c	10 Jul 2003 16:47:48 -0000	1.336
--- cp/tree.c	16 Jul 2003 00:02:30 -0000
*************** build_overload (tree decl, tree chain)
*** 986,1002 ****
    if (chain && TREE_CODE (chain) != OVERLOAD)
      chain = ovl_cons (chain, NULL_TREE);
    return ovl_cons (decl, chain);
  }
  
- int
- is_aggr_type_2 (tree t1, tree t2)
- {
-   if (TREE_CODE (t1) != TREE_CODE (t2))
-     return 0;
-   return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
- }
  
  #define PRINT_RING_SIZE 4
  
  const char *
  cxx_printable_name (tree decl, int v)
--- 986,995 ----


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