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 for c++/40619


So my last patch makes it straightforward to add the parm index to DECL_LANG_SPECIFIC; there's really no way to figure out the index when we're looking at a late-specified return type without specifically associating it with the parm decl itself.

Adding DECL_LANG_SPECIFIC to parms cuts the memory savings from the last patch in half.

Tested x86_64-pc-linux-gnu, applied to trunk. The last patch is unsuitable for 4.4, so I'm going to do something different there.
2009-07-04  Jason Merrill  <jason@redhat.com>

	PR c++/40619
	* cp-tree.h (struct lang_decl_parm): New.
	(struct lang_decl): Add it.
	(LANG_DECL_PARM_CHECK): New.
	(DECL_PARM_INDEX): New.
	* decl2.c (parm_index): Remove.
	* lex.c (retrofit_lang_decl): Handle parms.
	(cxx_dup_lang_specific_decl): Likewise.
	* mangle.c (write_expression): Adjust.
	* tree.c (cp_tree_equal): Adjust.
	(decl_linkage): Only check DECL_COMDAT for functions and variables.
	* parser.c (cp_parser_parameter_declaration_list): Set
	DECL_PARM_INDEX.
	* pt.c (iterative_hash_template_arg): Hash it.

*** gcc/cp/cp-tree.h
--- gcc/cp/cp-tree.h	2009-07-03 20:53:49.503723830 -0400
*************** struct GTY(()) lang_decl_ns {
*** 1675,1680 ****
--- 1675,1687 ----
    struct cp_binding_level *level;
  };
  
+ /* DECL_LANG_SPECIFIC for parameters.  */
+ 
+ struct GTY(()) lang_decl_parm {
+   struct lang_decl_base base;
+   int index;
+ };
+ 
  /* DECL_LANG_SPECIFIC for all types.  It would be nice to just make this a
     union rather than a struct containing a union as its only field, but
     tree.h declares it as a struct.  */
*************** struct GTY(()) lang_decl {
*** 1685,1690 ****
--- 1692,1698 ----
      struct lang_decl_min GTY((tag ("0"))) min;
      struct lang_decl_fn GTY ((tag ("1"))) fn;
      struct lang_decl_ns GTY((tag ("2"))) ns;
+     struct lang_decl_parm GTY((tag ("3"))) parm;
    } u;
  };
  
*************** struct GTY(()) lang_decl {
*** 1715,1720 ****
--- 1723,1734 ----
       lang_check_failed (__FILE__, __LINE__, __FUNCTION__);		\
     &lt->u.ns; })
  
+ #define LANG_DECL_PARM_CHECK(NODE) __extension__		\
+ ({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);		\
+   if (TREE_CODE (NODE) != PARM_DECL)				\
+     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);	\
+   &lt->u.parm; })
+ 
  #define LANG_DECL_U2_CHECK(NODE, TF) __extension__		\
  ({  struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);		\
      if (lt->u.base.u2sel != TF)					\
*************** struct GTY(()) lang_decl {
*** 1732,1737 ****
--- 1746,1754 ----
  #define LANG_DECL_NS_CHECK(NODE) \
    (&DECL_LANG_SPECIFIC (NODE)->u.ns)
  
+ #define LANG_DECL_PARM_CHECK(NODE) \
+   (&DECL_LANG_SPECIFIC (NODE)->u.parm)
+ 
  #define LANG_DECL_U2_CHECK(NODE, TF) \
    (&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
  
*************** struct GTY(()) lang_decl {
*** 1847,1852 ****
--- 1864,1874 ----
  /* Discriminator for name mangling.  */
  #define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator)
  
+ /* The index of a user-declared parameter in its function, starting at 1.
+    All artificial parameters will have index 0.  */
+ #define DECL_PARM_INDEX(NODE) \
+   (LANG_DECL_PARM_CHECK (NODE)->index)
+ 
  /* Nonzero if the VTT parm has been added to NODE.  */
  #define DECL_HAS_VTT_PARM_P(NODE) \
    (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
*** gcc/cp/decl2.c
--- gcc/cp/decl2.c	2009-07-03 20:46:00.755723720 -0400
*************** mark_used (tree decl)
*** 3910,3936 ****
    processing_template_decl = saved_processing_template_decl;
  }
  
- /* Given function PARM_DECL PARM, return its index in the function's list
-    of parameters, beginning with 1.  */
- 
- int
- parm_index (tree parm)
- {
-   int index;
-   tree arg;
- 
-   for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm));
-        arg;
-        ++index, arg = TREE_CHAIN (arg))
-     {
-       if (DECL_NAME (parm) == DECL_NAME (arg))
- 	break;
-       if (DECL_ARTIFICIAL (arg))
- 	--index;
-     }
- 
-   gcc_assert (arg);
-   return index;
- }
- 
  #include "gt-cp-decl2.h"
--- 3910,3913 ----
*** gcc/cp/lex.c
--- gcc/cp/lex.c	2009-07-03 20:53:32.030724153 -0400
*************** retrofit_lang_decl (tree t)
*** 538,543 ****
--- 538,545 ----
      sel = 1, size = sizeof (struct lang_decl_fn);
    else if (TREE_CODE (t) == NAMESPACE_DECL)
      sel = 2, size = sizeof (struct lang_decl_ns);
+   else if (TREE_CODE (t) == PARM_DECL)
+     sel = 3, size = sizeof (struct lang_decl_parm);
    else if (LANG_DECL_HAS_MIN (t))
      sel = 0, size = sizeof (struct lang_decl_min);
    else
*************** cxx_dup_lang_specific_decl (tree node)
*** 577,582 ****
--- 579,586 ----
      size = sizeof (struct lang_decl_fn);
    else if (TREE_CODE (node) == NAMESPACE_DECL)
      size = sizeof (struct lang_decl_ns);
+   else if (TREE_CODE (node) == PARM_DECL)
+     size = sizeof (struct lang_decl_parm);
    else if (LANG_DECL_HAS_MIN (node))
      size = sizeof (struct lang_decl_min);
    else
*** gcc/cp/mangle.c
--- gcc/cp/mangle.c	2009-07-03 23:50:48.023724261 -0400
*************** write_expression (tree expr)
*** 2199,2205 ****
    else if (code == PARM_DECL)
      {
        /* A function parameter used in a late-specified return type.  */
!       int index = parm_index (expr);
        write_string ("fp");
        if (index > 1)
  	write_unsigned_number (index - 2);
--- 2199,2206 ----
    else if (code == PARM_DECL)
      {
        /* A function parameter used in a late-specified return type.  */
!       int index = DECL_PARM_INDEX (expr);
!       gcc_assert (index >= 1);
        write_string ("fp");
        if (index > 1)
  	write_unsigned_number (index - 2);
*** gcc/cp/parser.c
--- gcc/cp/parser.c	2009-07-03 23:49:38.303723188 -0400
*************** cp_parser_parameter_declaration_list (cp
*** 14111,14116 ****
--- 14111,14117 ----
    tree parameters = NULL_TREE;
    tree *tail = &parameters; 
    bool saved_in_unbraced_linkage_specification_p;
+   int index = 0;
  
    /* Assume all will go well.  */
    *is_error = false;
*************** cp_parser_parameter_declaration_list (cp
*** 14162,14167 ****
--- 14163,14174 ----
        if (DECL_NAME (decl))
  	decl = pushdecl (decl);
  
+       if (decl != error_mark_node)
+ 	{
+ 	  retrofit_lang_decl (decl);
+ 	  DECL_PARM_INDEX (decl) = ++index;
+ 	}
+ 
        /* Add the new parameter to the list.  */
        *tail = build_tree_list (parameter->default_argument, decl);
        tail = &TREE_CHAIN (*tail);
*** gcc/cp/pt.c
--- gcc/cp/pt.c	2009-07-03 20:47:33.947472947 -0400
*************** iterative_hash_template_arg (tree arg, h
*** 1488,1496 ****
        }
  
      case PARM_DECL:
!       /* I tried hashing parm_index as well, but in some cases we get
! 	 called too soon for that to work, so just hash the type and let
! 	 lookup check that the index matches.  */
        return iterative_hash_template_arg (TREE_TYPE (arg), val);
  
      case TARGET_EXPR:
--- 1488,1494 ----
        }
  
      case PARM_DECL:
!       val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
        return iterative_hash_template_arg (TREE_TYPE (arg), val);
  
      case TARGET_EXPR:
*** gcc/cp/tree.c
--- gcc/cp/tree.c	2009-07-03 20:57:55.886722412 -0400
*************** cp_tree_equal (tree t1, tree t2)
*** 1997,2003 ****
        /* For comparing uses of parameters in late-specified return types
  	 with an out-of-class definition of the function.  */
        if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! 	  && parm_index (t1) == parm_index (t2))
  	return true;
        else
  	return false;
--- 1997,2003 ----
        /* For comparing uses of parameters in late-specified return types
  	 with an out-of-class definition of the function.  */
        if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! 	  && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2))
  	return true;
        else
  	return false;
*************** decl_linkage (tree decl)
*** 2723,2729 ****
       template instantiations have internal linkage (in the object
       file), but the symbols should still be treated as having external
       linkage from the point of view of the language.  */
!   if (TREE_CODE (decl) != TYPE_DECL && DECL_LANG_SPECIFIC (decl)
        && DECL_COMDAT (decl))
      return lk_external;
  
--- 2723,2730 ----
       template instantiations have internal linkage (in the object
       file), but the symbols should still be treated as having external
       linkage from the point of view of the language.  */
!   if ((TREE_CODE (decl) == FUNCTION_DECL
!        || TREE_CODE (decl) == VAR_DECL)
        && DECL_COMDAT (decl))
      return lk_external;
  
*** gcc/testsuite/g++.dg/cpp0x/auto16.C
--- gcc/testsuite/g++.dg/cpp0x/auto16.C	2009-07-03 21:04:23.919510590 -0400
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/40619
+ // { dg-options "-std=c++0x" }
+ 
+ template<typename U> struct X {};
+ 
+ template<typename T> auto f(T t) -> X<decltype(t+1)> {}
+ template<typename T> auto g(T t) -> X<decltype(t+1)> {}

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