OSDN Git Service

Fix for PR debug/41266
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Sep 2009 20:20:03 +0000 (20:20 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Sep 2009 20:20:03 +0000 (20:20 +0000)
ChangeLog:

* include/dwarf2.h (enum dwarf_tag): Add
DW_TAG_template_parameter_pack and DW_TAG_formal_parameter_pack.

gcc/ChangeLog:

* dwarf2out.c (template_parameter_pack_die,
gen_formal_parameter_pack_die ): New functions.
(make_ith_pack_parameter_name): Remove this function.
(dwarf_tag_name): Support printing DW_TAG_template_parameter_pack and
DW_TAG_formal_parameter_pack.
(gen_generic_params_dies): Represent each template parameter pack
by a DW_TAG_template_parameter_pack DIE. Argument pack elements are
represented by usual DW_TAG_template_*_parameter DIEs that are
children of the DW_TAG_template_parameter_pack element DIE.
(generic_parameter_die): This doesn't deal with parameter pack
names anymore. Don't generate DW_AT_name for some DIEs, e.g. children of
parameter pack DIEs.
(gen_formal_parameter_die): Add a flag to not emit DW_AT_name
in certain cases, e.g. for pack elements.
(gen_formal_types_die, gen_decl_die): Adjust usage of
gen_formal_parameter_die.
(gen_subprogram_die): Represent each function parameter pack by a
DW_TAG_formal_parameter_pack DIE. Arguments of of the pack are
represented by usual DW_TAG_formal_parameter DIEs that are children
of the DW_TAG_formal_parameter_pack DIE. Remove references to
____builtin_va_alist decls as no part of the compiler uses those
anymore.
* langhooks.h (struct lang_hooks_for_decls): Add
function_parm_expanded_from_pack_p, get_generic_function_decl
and function_parameter_pack_p hooks.  Fix comment for
get_innermost_generic_parms hook.
* langhooks-def.h (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P ): Declare new hook
macros and use them to initialize lang_hook.

gcc/cp/ChangeLog:

* cp-lang.c (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P,
LANG_HOOKS_GET_GENERIC_FUNCTION_DECL): Initialize these
hooks for the c++ FE.
* cp-tree.h (function_parameter_pack_p, get_function_template_decl,
function_parameter_expanded_from_pack_p): Declare ...
* pt.c (function_parameter_pack_p, get_function_template_decl,
function_parameter_expanded_from_pack_p): ... new hooks.
(get_template_info): Make this more robust.
(template_args_variadic_p, make_ith_pack_parameter_name): Add a new
line between comment and function.
(get_template_argument_pack_elems): Fix comment.
(tsubst_decl): Arguments of function parameter packs are not
parameter packs themselves.

gcc/testsuite/ChangeLog:
* g++.dg/debug/dwarf2/template-func-params-4.C: Adjust.
* g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.
* g++.dg/debug/dwarf2/template-params-4.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152043 138bc75d-0d04-0410-961f-82ee72b054a4

14 files changed:
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/dwarf2out.c
gcc/langhooks-def.h
gcc/langhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-4.C
gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-7.C
gcc/testsuite/g++.dg/debug/dwarf2/template-params-4.C
include/ChangeLog
include/dwarf2.h

index 0c3a0b6..5a3554c 100644 (file)
@@ -1,3 +1,35 @@
+2009-09-22  Dodji Seketeli  <dodji@redhat.com>
+
+       * dwarf2out.c (template_parameter_pack_die,
+       gen_formal_parameter_pack_die ): New functions.
+       (make_ith_pack_parameter_name): Remove this function.
+       (dwarf_tag_name): Support printing DW_TAG_template_parameter_pack and
+       DW_TAG_formal_parameter_pack.
+       (gen_generic_params_dies): Represent each template parameter pack
+       by a DW_TAG_template_parameter_pack DIE. Argument pack elements are
+       represented by usual DW_TAG_template_*_parameter DIEs that are
+       children of the DW_TAG_template_parameter_pack element DIE.
+       (generic_parameter_die): This doesn't deal with parameter pack
+       names anymore. Don't generate DW_AT_name for some DIEs, e.g. children of
+       parameter pack DIEs.
+       (gen_formal_parameter_die): Add a flag to not emit DW_AT_name
+       in certain cases, e.g. for pack elements.
+       (gen_formal_types_die, gen_decl_die): Adjust usage of
+       gen_formal_parameter_die.
+       (gen_subprogram_die): Represent each function parameter pack by a
+       DW_TAG_formal_parameter_pack DIE. Arguments of of the pack are
+       represented by usual DW_TAG_formal_parameter DIEs that are children
+       of the DW_TAG_formal_parameter_pack DIE. Remove references to
+       ____builtin_va_alist decls as no part of the compiler uses those
+       anymore.
+       * langhooks.h (struct lang_hooks_for_decls): Add
+       function_parm_expanded_from_pack_p, get_generic_function_decl
+       and function_parameter_pack_p hooks.  Fix comment for
+       get_innermost_generic_parms hook.
+       * langhooks-def.h (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
+       LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P ): Declare new hook
+       macros and use them to initialize lang_hook.
+
 2009-09-22  Richard Henderson  <rth@redhat.com>
 
        * system.h (TRAMPOLINE_TEMPLATE, INITIALIZE_TRAMPOLINE): Poison.
index d2fa331..ae3045e 100644 (file)
@@ -1,3 +1,20 @@
+2009-09-22  Dodji Seketeli  <dodji@redhat.com>
+
+       * cp-lang.c (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
+       LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P,
+       LANG_HOOKS_GET_GENERIC_FUNCTION_DECL): Initialize these
+       hooks for the c++ FE.
+       * cp-tree.h (function_parameter_pack_p, get_function_template_decl,
+       function_parameter_expanded_from_pack_p): Declare ...
+       * pt.c (function_parameter_pack_p, get_function_template_decl,
+       function_parameter_expanded_from_pack_p): ... new hooks.
+       (get_template_info): Make this more robust.
+       (template_args_variadic_p, make_ith_pack_parameter_name): Add a new
+       line between comment and function.
+       (get_template_argument_pack_elems): Fix comment.
+       (tsubst_decl): Arguments of function parameter packs are not
+       parameter packs themselves.
+
 2009-09-21  Jason Merrill  <jason@redhat.com>
 
        PR c++/41421
index 9521eab..d84325d 100644 (file)
@@ -59,13 +59,20 @@ static tree cp_eh_personality (void);
 #undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
 #define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \
        get_template_innermost_arguments
+#undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P
+#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \
+       function_parameter_pack_p
 #undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS
 #define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \
        get_template_argument_pack_elems
 #undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P
 #define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \
        template_template_parameter_p
-
+#undef LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P
+#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \
+       function_parameter_expanded_from_pack_p
+#undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL
+#define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl
 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
 #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
 #undef LANG_HOOKS_DWARF_NAME
index 816b4ca..c089bb7 100644 (file)
@@ -4643,6 +4643,8 @@ extern tree instantiate_decl                      (tree, int, bool);
 extern int comp_template_parms                 (const_tree, const_tree);
 extern bool uses_parameter_packs                (tree);
 extern bool template_parameter_pack_p           (const_tree);
+extern bool function_parameter_pack_p          (const_tree);
+extern bool function_parameter_expanded_from_pack_p (tree, tree);
 extern tree make_pack_expansion                 (tree);
 extern bool check_for_bare_parameter_packs      (tree);
 extern tree get_template_info                  (const_tree);
@@ -4692,7 +4694,7 @@ bool template_template_parameter_p                (const_tree);
 extern tree get_primary_template_innermost_parameters  (const_tree);
 extern tree get_template_innermost_arguments   (const_tree);
 extern tree get_template_argument_pack_elems   (const_tree);
-
+extern tree get_function_template_decl (const_tree);
 /* in repo.c */
 extern void init_repo                          (void);
 extern int repo_emit_p                         (tree);
index 7e3a545..08964da 100644 (file)
@@ -294,6 +294,9 @@ get_template_info (const_tree t)
 {
   tree tinfo = NULL_TREE;
 
+  if (!t || t == error_mark_node)
+    return NULL;
+
   if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
     tinfo = DECL_TEMPLATE_INFO (t);
 
@@ -2617,6 +2620,7 @@ comp_template_parms (const_tree parms1, const_tree parms2)
 }
 
 /* Determine whether PARM is a parameter pack.  */
+
 bool 
 template_parameter_pack_p (const_tree parm)
 {
@@ -2635,8 +2639,49 @@ template_parameter_pack_p (const_tree parm)
          && TEMPLATE_TYPE_PARAMETER_PACK (parm));
 }
 
+/* Determine if T is a function parameter pack.  */
+
+bool
+function_parameter_pack_p (const_tree t)
+{
+  if (t && TREE_CODE (t) == PARM_DECL)
+    return FUNCTION_PARAMETER_PACK_P (t);
+  return false;
+}
+
+/* Return the function template declaration of PRIMARY_FUNC_TMPL_INST.
+   PRIMARY_FUNC_TMPL_INST is a primary function template instantiation.  */
+
+tree
+get_function_template_decl (const_tree primary_func_tmpl_inst)
+{
+  if (! primary_func_tmpl_inst
+      || TREE_CODE (primary_func_tmpl_inst) != FUNCTION_DECL
+      || ! primary_template_instantiation_p (primary_func_tmpl_inst))
+    return NULL;
+
+  return DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (primary_func_tmpl_inst));
+}
+
+/* Return true iff the function parameter PARAM_DECL was expanded
+   from the function parameter pack PACK.  */
+
+bool
+function_parameter_expanded_from_pack_p (tree param_decl, tree pack)
+{
+    if (! function_parameter_pack_p (pack))
+      return false;
+
+    gcc_assert (DECL_NAME (param_decl) && DECL_NAME (pack));
+
+    /* The parameter pack and its pack arguments have the same
+       DECL_PARM_INDEX.  */
+    return DECL_PARM_INDEX (pack) == DECL_PARM_INDEX (param_decl);
+}
+
 /* Determine whether ARGS describes a variadic template args list,
    i.e., one that is terminated by a template argument pack.  */
+
 static bool 
 template_args_variadic_p (tree args)
 {
@@ -2659,6 +2704,7 @@ template_args_variadic_p (tree args)
 
 /* Generate a new name for the parameter pack name NAME (an
    IDENTIFIER_NODE) that incorporates its */
+
 static tree
 make_ith_pack_parameter_name (tree name, int i)
 {
@@ -2735,7 +2781,8 @@ get_template_innermost_arguments (const_tree t)
   return args;
 }
 
-/* Return the arguments pack of T if T is a template, NULL otherwise.  */
+/* Return the argument pack elements of T if T is a template argument pack,
+   NULL otherwise.  */
 
 tree
 get_template_argument_pack_elems (const_tree t)
@@ -8825,6 +8872,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
             if (DECL_TEMPLATE_PARM_P (t))
               SET_DECL_TEMPLATE_PARM_P (r);
 
+           /* An argument of a function parameter pack is not a parameter
+              pack.  */
+           FUNCTION_PARAMETER_PACK_P (r) = false;
+
             if (expanded_types)
               /* We're on the Ith parameter of the function parameter
                  pack.  */
index 9c128f1..f25b18b 100644 (file)
@@ -5932,7 +5932,8 @@ static dw_die_ref base_type_die (tree);
 static int is_base_type (tree);
 static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref);
 static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
-static dw_die_ref generic_parameter_die (tree, tree, dw_die_ref, int);
+static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref);
+static dw_die_ref template_parameter_pack_die (tree, tree, dw_die_ref);
 static int type_is_enum (const_tree);
 static unsigned int dbx_reg_number (const_rtx);
 static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
@@ -6000,7 +6001,8 @@ static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_re
 static void gen_entry_point_die (tree, dw_die_ref);
 #endif
 static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
-static dw_die_ref gen_formal_parameter_die (tree, tree, dw_die_ref);
+static dw_die_ref gen_formal_parameter_die (tree, tree, bool, dw_die_ref);
+static dw_die_ref gen_formal_parameter_pack_die  (tree, tree, dw_die_ref, tree*);
 static void gen_unspecified_parameters_die (tree, dw_die_ref);
 static void gen_formal_types_die (tree, dw_die_ref);
 static void gen_subprogram_die (tree, dw_die_ref);
@@ -6032,7 +6034,6 @@ static dw_die_ref declare_in_namespace (tree, dw_die_ref);
 static struct dwarf_file_data * lookup_filename (const char *);
 static void retry_incomplete_types (void);
 static void gen_type_die_for_member (tree, tree, dw_die_ref);
-static tree make_ith_pack_parameter_name (tree, int);
 static void gen_generic_params_dies (tree);
 static void splice_child_die (dw_die_ref, dw_die_ref);
 static int file_info_cmp (const void *, const void *);
@@ -6337,6 +6338,10 @@ dwarf_tag_name (unsigned int tag)
       return "DW_TAG_condition";
     case DW_TAG_shared_type:
       return "DW_TAG_shared_type";
+    case DW_TAG_template_parameter_pack:
+      return "DW_TAG_template_parameter_pack";
+    case DW_TAG_formal_parameter_pack:
+      return "DW_TAG_formal_parameter_pack";
     case DW_TAG_MIPS_loop:
       return "DW_TAG_MIPS_loop";
     case DW_TAG_format_label:
@@ -10512,27 +10517,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
   return mod_type_die;
 }
 
-/* Generate a new name for the parameter pack name NAME (an
-   IDENTIFIER_NODE) that incorporates its */
-
-static tree
-make_ith_pack_parameter_name (tree name, int i)
-{
-  /* Munge the name to include the parameter index.  */
-#define NUMBUF_LEN 128
-  char numbuf[NUMBUF_LEN];
-  char* newname;
-  int newname_len;
-
-  snprintf (numbuf, NUMBUF_LEN, "%i", i);
-  newname_len = IDENTIFIER_LENGTH (name)
-               + strlen (numbuf) + 2;
-  newname = (char*) alloca (newname_len);
-  snprintf (newname, newname_len,
-           "%s#%i", IDENTIFIER_POINTER (name), i);
-  return get_identifier (newname);
-}
-
 /* Generate DIEs for the generic parameters of T.
    T must be either a generic type or a generic function.
    See http://gcc.gnu.org/wiki/TemplateParmsDwarf for more.  */
@@ -10564,30 +10548,27 @@ gen_generic_params_dies (tree t)
   args = lang_hooks.get_innermost_generic_args (t);
   for (i = 0; i < parms_num; i++)
     {
-      tree parm, arg;
+      tree parm, arg, arg_pack_elems;
 
       parm = TREE_VEC_ELT (parms, i);
       arg = TREE_VEC_ELT (args, i);
+      arg_pack_elems = lang_hooks.types.get_argument_pack_elems (arg);
+      gcc_assert (parm && TREE_VALUE (parm) && arg);
+
       if (parm && TREE_VALUE (parm) && arg)
        {
-         tree pack_elems =
-           lang_hooks.types.get_argument_pack_elems (arg);
-         if (pack_elems)
-           {
-             /* So ARG is an argument pack and the elements of that pack
-                are stored in PACK_ELEMS.  */
-             int i, len;
-
-             len = TREE_VEC_LENGTH (pack_elems);
-             for (i = 0; i < len; i++)
-               generic_parameter_die (TREE_VALUE (parm),
-                                      TREE_VEC_ELT (pack_elems, i),
-                                      die, i);
-           }
-         else /* Arg is not an argument pack.  */
-           generic_parameter_die (TREE_VALUE (parm),
-                                  arg, die,
-                                  -1/* Not a param pack.  */);
+         /* If PARM represents a template parameter pack,
+            emit a DW_TAG_template_parameter_pack DIE, followed
+            by DW_TAG_template_*_parameter DIEs for the argument
+            pack elements of ARG. Note that ARG would then be
+            an argument pack.  */
+         if (arg_pack_elems)
+           template_parameter_pack_die (TREE_VALUE (parm),
+                                        arg_pack_elems,
+                                        die);
+         else
+           generic_parameter_die (TREE_VALUE (parm), arg,
+                                  true /* Emit DW_AT_name */, die);
        }
     }
 }
@@ -10596,15 +10577,15 @@ gen_generic_params_dies (tree t)
    the representation of a generic type parameter.
    For instance, in the C++ front end, PARM would be a template parameter.
    ARG is the argument to PARM.
+   EMIT_NAME_P if tree, the DIE will have DW_AT_name attribute set to the
+   name of the PARM.
    PARENT_DIE is the parent DIE which the new created DIE should be added to,
-   as a child node.
-   PACK_ELEM_INDEX is >= 0 if PARM is a generic parameter pack, and if ARG
-   is one of the unpacked elements of the parameter PACK. In that case,
-   PACK_ELEM_INDEX is the index of ARG in the parameter pack.  */
+   as a child node.  */
 
 static dw_die_ref
-generic_parameter_die (tree parm, tree arg, dw_die_ref parent_die,
-                      int pack_elem_index)
+generic_parameter_die (tree parm, tree arg,
+                      bool emit_name_p,
+                      dw_die_ref parent_die)
 {
   dw_die_ref tmpl_die = NULL;
   const char *name = NULL;
@@ -10637,20 +10618,17 @@ generic_parameter_die (tree parm, tree arg, dw_die_ref parent_die,
     {
       tree tmpl_type;
 
-      if (pack_elem_index >= 0)
+      /* If PARM is a generic parameter pack, it means we are
+         emitting debug info for a template argument pack element.
+        In other terms, ARG is a template argument pack element.
+        In that case, we don't emit any DW_AT_name attribute for
+        the die.  */
+      if (emit_name_p)
        {
-         /* PARM is an element of a parameter pack.
-            Generate a name for it.  */
-         tree identifier = make_ith_pack_parameter_name (DECL_NAME (parm),
-                                                         pack_elem_index);
-         if (identifier)
-           name = IDENTIFIER_POINTER (identifier);
+         name = IDENTIFIER_POINTER (DECL_NAME (parm));
+         gcc_assert (name);
+         add_AT_string (tmpl_die, DW_AT_name, name);
        }
-      else
-       name = IDENTIFIER_POINTER (DECL_NAME (parm));
-
-      gcc_assert (name);
-      add_AT_string (tmpl_die, DW_AT_name, name);
 
       if (!lang_hooks.decls.generic_generic_parameter_decl_p (parm))
        {
@@ -10695,6 +10673,33 @@ generic_parameter_die (tree parm, tree arg, dw_die_ref parent_die,
   return tmpl_die;
 }
 
+/* Generate and return a  DW_TAG_template_parameter_pack DIE representing.
+   PARM_PACK must be a template parameter pack. The returned DIE
+   will be child DIE of PARENT_DIE.  */
+
+static dw_die_ref
+template_parameter_pack_die (tree parm_pack,
+                            tree parm_pack_args,
+                            dw_die_ref parent_die)
+{
+  dw_die_ref die;
+  int j;
+
+  gcc_assert (parent_die
+             && parm_pack
+             && DECL_NAME (parm_pack));
+
+  die = new_die (DW_TAG_template_parameter_pack, parent_die, parm_pack);
+  add_AT_string (die, DW_AT_name, IDENTIFIER_POINTER (DECL_NAME (parm_pack)));
+
+  for (j = 0; j < TREE_VEC_LENGTH (parm_pack_args); j++)
+    generic_parameter_die (parm_pack,
+                          TREE_VEC_ELT (parm_pack_args, j),
+                          false /* Don't emit DW_AT_name */,
+                          die);
+  return die;
+}
+
 /* Given a pointer to an arbitrary ..._TYPE tree node, return true if it is
    an enumerated type.  */
 
@@ -15380,10 +15385,13 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
    DIE to represent a formal parameter object (or some inlining thereof).  If
    it's the latter, then this function is only being called to output a
    DW_TAG_formal_parameter DIE to stand as a placeholder for some formal
-   argument type of some subprogram type.  */
+   argument type of some subprogram type.
+   If EMIT_NAME_P is true, name and source coordinate attributes
+   are emitted.  */
 
 static dw_die_ref
-gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
+gen_formal_parameter_die (tree node, tree origin, bool emit_name_p,
+                         dw_die_ref context_die)
 {
   tree node_or_origin = node ? node : origin;
   dw_die_ref parm_die
@@ -15399,7 +15407,8 @@ gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
       else
        {
          tree type = TREE_TYPE (node);
-         add_name_and_src_coords_attributes (parm_die, node);
+         if (emit_name_p)
+           add_name_and_src_coords_attributes (parm_die, node);
          if (decl_by_reference_p (node))
            add_type_attribute (parm_die, TREE_TYPE (type), 0, 0,
                                context_die);
@@ -15432,6 +15441,49 @@ gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
   return parm_die;
 }
 
+/* Generate and return a DW_TAG_formal_parameter_pack. Also generate
+   children DW_TAG_formal_parameter DIEs representing the arguments of the
+   parameter pack.
+
+   PARM_PACK must be a function parameter pack.
+   PACK_ARG is the first argument of the parameter pack. Its TREE_CHAIN
+   must point to the subsequent arguments of the function PACK_ARG belongs to.
+   SUBR_DIE is the DIE of the function PACK_ARG belongs to.
+   If NEXT_ARG is non NULL, *NEXT_ARG is set to the function argument
+   following the last one for which a DIE was generated.  */
+
+static dw_die_ref
+gen_formal_parameter_pack_die  (tree parm_pack,
+                               tree pack_arg,
+                               dw_die_ref subr_die,
+                               tree *next_arg)
+{
+  tree arg;
+  dw_die_ref parm_pack_die;
+
+  gcc_assert (parm_pack
+             && lang_hooks.function_parameter_pack_p (parm_pack)
+             && DECL_NAME (parm_pack)
+             && subr_die);
+
+  parm_pack_die = new_die (DW_TAG_formal_parameter_pack, subr_die, parm_pack);
+  add_AT_string (parm_pack_die, DW_AT_name,
+                IDENTIFIER_POINTER (DECL_NAME (parm_pack)));
+
+  for (arg = pack_arg; arg; arg = TREE_CHAIN (arg))
+    {
+      if (! lang_hooks.decls.function_parm_expanded_from_pack_p (arg,
+                                                                parm_pack))
+       break;
+      gen_formal_parameter_die (arg, NULL,
+                               false /* Don't emit name attribute.  */,
+                               parm_pack_die);
+    }
+  if (next_arg)
+    *next_arg = arg;
+  return parm_pack_die;
+}
+
 /* Generate a special type of DIE used as a stand-in for a trailing ellipsis
    at the end of an (ANSI prototyped) formal parameters list.  */
 
@@ -15475,7 +15527,9 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
        break;
 
       /* Output a (nameless) DIE to represent the formal parameter itself.  */
-      parm_die = gen_formal_parameter_die (formal_type, NULL, context_die);
+      parm_die = gen_formal_parameter_die (formal_type, NULL,
+                                          true /* Emit name attribute.  */,
+                                          context_die);
       if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
           && link == first_parm_type)
          || (arg && DECL_ARTIFICIAL (arg)))
@@ -15887,21 +15941,46 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
   else
     {
       /* Generate DIEs to represent all known formal parameters.  */
-      tree arg_decls = DECL_ARGUMENTS (decl);
-      tree parm;
-
-      /* When generating DIEs, generate the unspecified_parameters DIE
-        instead if we come across the arg "__builtin_va_alist" */
-      for (parm = arg_decls; parm; parm = TREE_CHAIN (parm))
-       if (TREE_CODE (parm) == PARM_DECL)
-         {
-           if (DECL_NAME (parm)
-               && !strcmp (IDENTIFIER_POINTER (DECL_NAME (parm)),
-                           "__builtin_va_alist"))
-             gen_unspecified_parameters_die (parm, subr_die);
-           else
+      tree parm = DECL_ARGUMENTS (decl);
+      tree generic_decl = lang_hooks.decls.get_generic_function_decl (decl);
+      tree generic_decl_parm = generic_decl
+                               ? DECL_ARGUMENTS (generic_decl)
+                               : NULL;
+
+      /* Now we want to walk the list of parameters of the function and
+        emit their relevant DIEs.
+
+        We consider the case of DECL being an instance of a generic function
+        as well as it being a normal function.
+
+        If DECL is an instance of a generic function we walk the
+        parameters of the generic function declaration _and_ the parameters of
+        DECL itself. This is useful because we want to emit specific DIEs for
+        function parameter packs and those are declared as part of the
+        generic function declaration. In that particular case,
+        the parameter pack yields a DW_TAG_formal_parameter_pack DIE.
+        That DIE has children DIEs representing the set of arguments
+        of the pack. Note that the set of pack arguments can be empty.
+        In that case, the DW_TAG_formal_parameter_pack DIE will not have any
+        children DIE.
+       
+        Otherwise, we just consider the parameters of DECL.  */
+      while (generic_decl_parm || parm)
+       {
+         if (generic_decl_parm
+             && lang_hooks.function_parameter_pack_p (generic_decl_parm))
+           gen_formal_parameter_pack_die (generic_decl_parm,
+                                          parm, subr_die,
+                                          &parm);
+         else if (parm)
+           {
              gen_decl_die (parm, NULL, subr_die);
-         }
+             parm = TREE_CHAIN (parm);
+           }
+
+         if (generic_decl_parm)
+           generic_decl_parm = TREE_CHAIN (generic_decl_parm);
+       }
 
       /* Decide whether we need an unspecified_parameters DIE at the end.
         There are 2 more cases to do this for: 1) the ansi ... declaration -
@@ -17489,7 +17568,9 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
       if (!origin)
         origin = decl_ultimate_origin (decl);
       if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
-       gen_formal_parameter_die (decl, origin, context_die);
+       gen_formal_parameter_die (decl, origin,
+                                 true /* Emit name attribute.  */,
+                                 context_die);
       else
        gen_variable_die (decl, origin, context_die);
       break;
@@ -17511,7 +17592,9 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
        gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
       else
        gen_type_die (TREE_TYPE (decl_or_origin), context_die);
-      gen_formal_parameter_die (decl, origin, context_die);
+      gen_formal_parameter_die (decl, origin,
+                               true /* Emit name attribute.  */,
+                               context_die);
       break;
 
     case NAMESPACE_DECL:
index dc4fdee..fa078ad 100644 (file)
@@ -157,8 +157,12 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_GENERIC_TYPE_P      hook_bool_const_tree_false
 #define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS hook_tree_const_tree_null
 #define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS hook_tree_const_tree_null
+#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P hook_bool_const_tree_false
 #define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS hook_tree_const_tree_null
 #define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P hook_bool_const_tree_false
+#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \
+                                       hook_bool_tree_tree_false
+#define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL hook_tree_const_tree_null
 #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
 #define LANG_HOOKS_TYPE_MAX_SIZE       lhd_return_null_const_tree
@@ -214,6 +218,8 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_GETDECLS, \
   LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
   LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
+  LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \
+  LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \
   LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
   LANG_HOOKS_WRITE_GLOBALS, \
   LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
@@ -268,6 +274,7 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_FOR_TYPES_INITIALIZER, \
   LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS, \
   LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS, \
+  LANG_HOOKS_FUNCTION_PARAMETER_PACK_P, \
   LANG_HOOKS_GIMPLIFY_EXPR, \
   LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
   LANG_HOOKS_BUILTIN_FUNCTION, \
index 349a5d8..ab64040 100644 (file)
@@ -172,6 +172,13 @@ struct lang_hooks_for_decls
      of a generic type, e.g a template template parameter for the C++ FE.  */
   bool (*generic_generic_parameter_decl_p) (const_tree);
 
+  /* Determine if a function parameter got expanded from a
+     function parameter pack.  */
+  bool (*function_parm_expanded_from_pack_p) (tree, tree);
+
+  /* Returns the generic declaration of a generic function instantiations.  */
+  tree (*get_generic_function_decl) (const_tree);
+
   /* Returns true when we should warn for an unused global DECL.
      We will already have checked that it has static binding.  */
   bool (*warn_unused_global) (const_tree);
@@ -379,7 +386,7 @@ struct lang_hooks
 
   struct lang_hooks_for_types types;
 
-  /* Retuns the generic parameters of an instantiation of
+  /* Returns the generic parameters of an instantiation of
      a generic type or decl, e.g. C++ template instantiation.  */
   tree (*get_innermost_generic_parms) (const_tree);
 
@@ -387,6 +394,9 @@ struct lang_hooks
      of a generic type of decl, e.g. C++ template instantiation.  */
   tree (*get_innermost_generic_args) (const_tree);
 
+  /* Determine if a tree is a function parameter pack.  */
+  bool (*function_parameter_pack_p) (const_tree);
+
   /* Perform language-specific gimplification on the argument.  Returns an
      enum gimplify_status, though we can't see that type here.  */
   int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *);
index fd26fb2..efd31a7 100644 (file)
@@ -1,3 +1,9 @@
+2009-09-22  Dodji Seketeli  <dodji@redhat.com>
+
+       * g++.dg/debug/dwarf2/template-func-params-4.C: Adjust.
+       * g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.
+       * g++.dg/debug/dwarf2/template-params-4.C: Likewise.
+
 2009-09-22  Alexandre Oliva  <aoliva@redhat.com>
 
        PR debug/41295
index 0eb0fe5..f75d0e6 100644 (file)
@@ -1,10 +1,16 @@
 // Contributed by Dodji Seketeli <dodji@redhat.com>
 // Origin PR debug/30161
 // { dg-options "-std=c++0x -g -dA" }
-// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
-// { dg-final { scan-assembler "DW_AT_name.*P#0" } }
-// { dg-final { scan-assembler "DW_AT_name.*P#1" } }
-// { dg-final { scan-assembler "DW_AT_name.*P#2" } }
+//
+// In theory the compiler instantiates count<int, char, long>,
+// count<char, long> and count<long>. In practice, only
+// count<int, char, long> is emitted, thanks to constant folding.
+// So in theory, each of the 3 instances of count yields a
+// DW_TAG_tempalate_parameter_pack DIE, but in practise, there is only one
+// DW_TAG_template_parameter_pack as there is only count<int, char, long>
+// is emitted.
+// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_parameter_pack" 1} }
+// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_type_param" 3} }
 
 
 template <typename... Args> struct count;
index dc6ac99..8a883f8 100644 (file)
 // { dg-final {scan-assembler-times "\"printf.0\".*?DW_AT_name" 1 } }
 
 // printf<int, char, int> and printf<char, int> have a pack expansion as
-// function parameters. In the former, the elements of the parameter pack
-// expansion are PackTypes#0, PackTypes#1 and the arguments are args#0 and
-// args#1. In the later, the element of the parameter pack expansion
-// is PackTypes#0 and the argument is args#0.
-// { dg-final {scan-assembler-times "DW_AT_name: \"PackTypes#0\"" 2 } }
-// { dg-final {scan-assembler-times "\"args#0.0\".*?DW_AT_name" 2 } }
-// { dg-final {scan-assembler-times "\"PackTypes#1.0\".*?DW_AT_name" 1 } }
-// { dg-final {scan-assembler-times "\"args#1.0\".*?DW_AT_name" 1 } }
-
+// function parameters. There should then be 3
+// DW_TAG_template_parameter_pack and 3 DW_TAG_formal_parameter_pack DIEs
+// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_parameter_pack" 3 } }
+// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_formal_parameter_pack" 3 } }
+// These 3 function template instantiations has a total of 3 template
+// parameters named T.
 // { dg_final {scan-assembler-times "\.ascii \"T.0\"\[\t \]+.*?DW_AT_name" 3 } }
 
+
 void
 printf(const char* s)
 {
index 09d1d95..e83ef61 100644 (file)
@@ -1,10 +1,16 @@
 // Contributed by Dodji Seketeli <dodji@redhat.com>
 // Origin PR debug/30161
 // { dg-options "-std=c++0x -g -dA" }
-// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
-// { dg-final { scan-assembler "DW_AT_name.*Args#0" } }
-// { dg-final { scan-assembler "DW_AT_name.*Args#1" } }
-// { dg-final { scan-assembler "DW_AT_name.*Args#2" } }
+//
+// In theory the compiler instantiates count<int, char, long>,
+// count<char, long> and count<long>. In practice, only
+// count<int, char, long> is emitted, thanks to constant folding.
+// So in theory, each of the 3 instances of count yields a
+// DW_TAG_tempalate_parameter_pack DIE, but in practise, there is only one
+// DW_TAG_template_parameter_pack as there is only count<int, char, long>
+// is emitted.
+// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_parameter_pack" 1} }
+// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_type_param" 3} }
 
 template <typename... Args> struct count;
 
index 4bd5e81..3ba01d2 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-22  Dodji Seketeli  <dodji@redhat.com>
+
+       * dwarf2.h (enum dwarf_tag): Add
+       DW_TAG_template_parameter_pack and DW_TAG_formal_parameter_pack.
+
 2009-07-24  Ian Lance Taylor  <iant@google.com>
 
        PR bootstrap/40854
index befaceb..608f7b5 100644 (file)
@@ -200,6 +200,14 @@ enum dwarf_tag
     DW_TAG_lo_user = 0x4080,
     DW_TAG_hi_user = 0xffff,
 
+    /* DWARF 5?  */
+
+    /* Template parameter pack extension, specified at
+       http://wiki.dwarfstd.org/index.php?title=C%2B%2B0x:_Variadic_templates
+       .  */
+    DW_TAG_template_parameter_pack = 0x43,
+    DW_TAG_formal_parameter_pack = 0x44,
+
     /* SGI/MIPS Extensions.  */
     DW_TAG_MIPS_loop = 0x4081,
     /* HP extensions.  See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */