]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Introduce template arguments and default values.
authorKeith Seitz <keiths@redhat.com>
Fri, 17 Feb 2017 19:05:52 +0000 (11:05 -0800)
committerKeith Seitz <keiths@redhat.com>
Tue, 21 Feb 2017 21:33:45 +0000 (13:33 -0800)
gdb/cp-abi.h
gdb/cp-name-parser.y
gdb/cp-namespace.c
gdb/cp-support.c
gdb/cp-support.h
gdb/dwarf2read.c
gdb/gdbtypes.h
gdb/symtab.c
gdb/symtab.h

index 968f92cbaa0c23b0ff377cecb24285a16aa2ca82..9620da10f9c1b58e320593500c6dc8fe3bb483c6 100644 (file)
@@ -90,6 +90,22 @@ enum dtor_kinds {
   /* Deprecated?  */
   object_dtor_group
 };
+
+/* Kinds of template arguments.  */
+enum template_argument_kinds
+{
+  /* A type argument, e.g., "<typename T>".  */
+  type_parameter,
+
+  /* A value argument, e.g., "<int V>".  */
+  value_parameter,
+
+  /* A template argument, e.g., "<template <...> class T = X>".  */
+  template_parameter,
+
+  /* A variadic template pack, e.g., "<class ... Types>".  */
+  variadic_parameter
+};
   
 /* Return non-zero iff NAME is the mangled name of a destructor.
    Actually, return an `enum dtor_kind' value describing what *kind*
index 14a78f1877dcfc3a3d89981df27b9cddff3137b0..0db55523b264829e3f742d4547f63890e3a50067 100644 (file)
@@ -2006,7 +2006,8 @@ cp_comp_to_string (struct demangle_component *result, int estimated_len)
 
 demangle_parse_info::demangle_parse_info ()
 : info (NULL),
-  tree (NULL)
+  tree (NULL),
+  memory (NULL)
 {
   obstack_init (&obstack);
 }
@@ -2026,6 +2027,9 @@ demangle_parse_info::~demangle_parse_info ()
 
   /* Free any memory allocated during typedef replacement.  */
   obstack_free (&obstack, NULL);
+
+  /* Free any memory used for demangling.  */
+  free (memory);
 }
 
 /* Merge the two parse trees given by DEST and SRC.  The parse tree
index b96c42126dea8423d6d6059f71bdd980e87559cd..ca0ab4730e3f8f350a72eabac3a2c6dd6949b5a4 100644 (file)
@@ -536,9 +536,9 @@ cp_lookup_symbol_imports_or_template (const char *scope,
        {
          struct template_symbol *templ
            = (struct template_symbol *) function;
-         struct symbol *sym = search_symbol_list (name,
-                                                  templ->n_template_arguments,
-                                                  templ->template_arguments);
+         struct symbol *sym
+           = search_symbol_list (name, templ->template_arguments->n_arguments,
+                                 templ->template_arguments->arguments);
 
          if (sym != NULL)
            {
index b6f9605673877a6a6a952f795349262b70f789a4..f77546a2cadd5377bc74ae4aa113dd76efa6bf47 100644 (file)
@@ -37,9 +37,6 @@
 #include "gdb_setjmp.h"
 #include "safe-ctype.h"
 
-#define d_left(dc) (dc)->u.s_binary.left
-#define d_right(dc) (dc)->u.s_binary.right
-
 /* Functions related to demangled name parsing.  */
 
 static unsigned int cp_find_first_component_aux (const char *name,
@@ -580,15 +577,10 @@ cp_canonicalize_string (const char *string)
   return ret;
 }
 
-/* Convert a mangled name to a demangle_component tree.  *MEMORY is
-   set to the block of used memory that should be freed when finished
-   with the tree.  DEMANGLED_P is set to the char * that should be
-   freed when finished with the tree, or NULL if none was needed.
-   OPTIONS will be passed to the demangler.  */
+/* See description in cp-support.h.  */
 
-static std::unique_ptr<demangle_parse_info>
-mangled_name_to_comp (const char *mangled_name, int options,
-                     void **memory, char **demangled_p)
+std::unique_ptr<demangle_parse_info>
+cp_mangled_name_to_comp (const char *mangled_name, int options)
 {
   char *demangled_name;
 
@@ -597,14 +589,15 @@ mangled_name_to_comp (const char *mangled_name, int options,
   if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
     {
       struct demangle_component *ret;
+      void *memory;
 
       ret = cplus_demangle_v3_components (mangled_name,
-                                         options, memory);
+                                         options, &memory);
       if (ret)
        {
          std::unique_ptr<demangle_parse_info> info (new demangle_parse_info);
          info->tree = ret;
-         *demangled_p = NULL;
+         info->memory = memory;
          return info;
        }
     }
@@ -626,7 +619,8 @@ mangled_name_to_comp (const char *mangled_name, int options,
       return NULL;
     }
 
-  *demangled_p = demangled_name;
+  long len;
+  copy_string_to_obstack (&info->obstack, demangled_name, &len);
   return info;
 }
 
@@ -635,14 +629,12 @@ mangled_name_to_comp (const char *mangled_name, int options,
 char *
 cp_class_name_from_physname (const char *physname)
 {
-  void *storage = NULL;
-  char *demangled_name = NULL, *ret;
+  char *ret;
   struct demangle_component *ret_comp, *prev_comp, *cur_comp;
   std::unique_ptr<demangle_parse_info> info;
   int done;
 
-  info = mangled_name_to_comp (physname, DMGL_ANSI,
-                              &storage, &demangled_name);
+  info = cp_mangled_name_to_comp (physname, DMGL_ANSI);
   if (info == NULL)
     return NULL;
 
@@ -715,8 +707,6 @@ cp_class_name_from_physname (const char *physname)
       ret = cp_comp_to_string (ret_comp, 10);
     }
 
-  xfree (storage);
-  xfree (demangled_name);
   return ret;
 }
 
@@ -784,13 +774,11 @@ unqualified_name_from_comp (struct demangle_component *comp)
 char *
 method_name_from_physname (const char *physname)
 {
-  void *storage = NULL;
-  char *demangled_name = NULL, *ret;
+  char *ret;
   struct demangle_component *ret_comp;
   std::unique_ptr<demangle_parse_info> info;
 
-  info = mangled_name_to_comp (physname, DMGL_ANSI,
-                              &storage, &demangled_name);
+  info = cp_mangled_name_to_comp (physname, DMGL_ANSI);
   if (info == NULL)
     return NULL;
 
@@ -802,8 +790,6 @@ method_name_from_physname (const char *physname)
        estimate.  */
     ret = cp_comp_to_string (ret_comp, 10);
 
-  xfree (storage);
-  xfree (demangled_name);
   return ret;
 }
 
@@ -1686,6 +1672,176 @@ info_vtbl_command (char *arg, int from_tty)
   cplus_print_vtable (value);
 }
 
+/* See description in cp-support.h.  */
+
+void
+cp_decode_template_type_indices (struct template_symbol *tsymbol,
+                                const struct demangle_parse_info *opt_info)
+{
+  const struct demangle_parse_info *info;
+  int idx;
+  struct demangle_component *ret_comp;
+  struct objfile *objfile;
+
+  /* Only do this once.  */
+  if (tsymbol->template_argument_indices != NULL)
+    return;
+
+  if (tsymbol->linkage_name == NULL)
+    {
+      warning (_("Template symbol \"%s\" has no linkage name."),
+              SYMBOL_NATURAL_NAME (&tsymbol->base));
+      return;
+    }
+
+  /* Initialize values to be returned to caller.  */
+  gdb_assert (SYMBOL_OBJFILE_OWNED (&tsymbol->base));
+  objfile = symbol_objfile (&tsymbol->base);
+  tsymbol->template_return_index = -1;
+  tsymbol->template_argument_indices
+    = XOBNEWVEC (&objfile->objfile_obstack, long,
+                TYPE_NFIELDS (SYMBOL_TYPE (&tsymbol->base)));
+
+  for (idx = 0; idx < TYPE_NFIELDS (SYMBOL_TYPE (&tsymbol->base)); ++idx)
+    tsymbol->template_argument_indices[idx] = -1;
+
+  std::unique_ptr<demangle_parse_info> dpi;
+
+  if (opt_info != NULL)
+    info = opt_info;
+  else
+    {
+      dpi = cp_mangled_name_to_comp (tsymbol->linkage_name,
+                                    DMGL_ANSI | DMGL_PARAMS);
+      if (dpi == NULL)
+       return;
+
+      info = dpi.get ();
+    }
+
+  /* Determine the return type index.  */
+  ret_comp = info->tree;
+  if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
+    {
+      if (d_left (ret_comp)->type == DEMANGLE_COMPONENT_TEMPLATE
+         && d_right (ret_comp)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
+       {
+         int done = 0;
+         struct demangle_component *func_comp = d_right (ret_comp);
+
+         /* Move to looking at the return type node.  */
+         ret_comp = d_left (func_comp);
+         if (ret_comp != NULL)
+           {
+             while (!done)
+               {
+                 switch (ret_comp->type)
+                   {
+                   case DEMANGLE_COMPONENT_CONST:
+                   case DEMANGLE_COMPONENT_RESTRICT:
+                   case DEMANGLE_COMPONENT_VOLATILE:
+                   case DEMANGLE_COMPONENT_POINTER:
+                   case DEMANGLE_COMPONENT_REFERENCE:
+                   case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+                     ret_comp = d_left (ret_comp);
+                     break;
+
+                     /*TYPED_NAME et al? */
+
+                   case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+                     /* The return type was based on a template parameter.
+                        Return the index of that parameter.  */
+                     tsymbol->template_return_index
+                       = ret_comp->u.s_number.number;
+                     done = 1;
+                     break;
+
+                   default:
+                     done = 1;
+                     break;
+                   }
+               }
+           }
+         else
+           {
+             /* The function had no marked return type.  Check if it is
+                a conversion operator and record the template parameter
+                index for that.  */
+
+             ret_comp = d_left (info->tree);
+             while (!done)
+               {
+                 switch (ret_comp->type)
+                   {
+                   case DEMANGLE_COMPONENT_TEMPLATE:
+                   case DEMANGLE_COMPONENT_CONVERSION:
+                   case DEMANGLE_COMPONENT_CONST:
+                   case DEMANGLE_COMPONENT_RESTRICT:
+                   case DEMANGLE_COMPONENT_VOLATILE:
+                   case DEMANGLE_COMPONENT_POINTER:
+                   case DEMANGLE_COMPONENT_REFERENCE:
+                   case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+                     ret_comp = d_left (ret_comp);
+                     break;
+
+                   case DEMANGLE_COMPONENT_QUAL_NAME:
+                     ret_comp = d_right (ret_comp);
+                     break;
+
+                   case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+                     tsymbol->conversion_operator_index
+                       = ret_comp->u.s_number.number;
+                     done = 1;
+                     break;
+
+                   default:
+                     done = 1;
+                     break;
+                   }
+               }
+           }
+
+         /* Determine the same information for the function arguments.  */
+         ret_comp = d_right (func_comp);
+         idx = 0;
+         while (ret_comp != NULL
+                && ret_comp->type == DEMANGLE_COMPONENT_ARGLIST)
+           {
+             struct demangle_component *comp;
+
+             comp = d_left (ret_comp);
+             if (comp == NULL)
+               break;
+             done = 0;
+             while (!done)
+               {
+                 switch (comp->type)
+                   {
+                   case DEMANGLE_COMPONENT_CONST:
+                   case DEMANGLE_COMPONENT_RESTRICT:
+                   case DEMANGLE_COMPONENT_VOLATILE:
+                   case DEMANGLE_COMPONENT_POINTER:
+                   case DEMANGLE_COMPONENT_REFERENCE:
+                   case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+                     comp = d_left (comp);
+                     break;
+                   default:
+                     done = 1;
+                     break;
+                   }
+               }
+
+             if (comp->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
+               tsymbol->template_argument_indices[idx]
+                 = comp->u.s_number.number;
+             ++idx;
+
+             ret_comp = d_right (ret_comp);
+           }
+       }
+    }
+}
+
 void
 _initialize_cp_support (void)
 {
index d14e9cc8f8e0fc8a52b5af520ed0ca7f22eda36f..85d6461eef6c3cab3c06f0a0593e768fb0a0f17c 100644 (file)
@@ -29,6 +29,8 @@
 #include "gdb_vecs.h"
 #include "gdb_obstack.h"
 
+#include <string>
+
 /* Opaque declarations.  */
 
 struct symbol;
@@ -60,10 +62,13 @@ struct demangle_parse_info
   /* The result of the parse.  */
   struct demangle_component *tree;
 
-  /* Any temporary memory used during typedef replacement.  */
+  /* Any temporary memory used, e.g., during typedef replacement
+     or demangling a name.  */
   struct obstack obstack;
-};
 
+  /* The memory used for demangling a name prior to parsing.  */
+  void *memory;
+};
 
 /* Functions from cp-support.c.  */
 
@@ -147,6 +152,17 @@ struct type *cp_find_type_baseclass_by_name (struct type *parent_type,
 extern std::unique_ptr<demangle_parse_info> cp_demangled_name_to_comp
      (const char *demangled_name, const char **errmsg);
 
+/* Convert a mangled name to a demangle_component tree.  OPTIONS will be
+   passed to the demangler.  */
+
+extern std::unique_ptr<demangle_parse_info>
+  cp_mangled_name_to_comp (const char *mangled_name, int options);
+
+/* Convenience macros to move through the demangle tree.  */
+
+#define d_left(dc) (dc)->u.s_binary.left
+#define d_right(dc) (dc)->u.s_binary.right
+
 extern char *cp_comp_to_string (struct demangle_component *result,
                                int estimated_len);
 
@@ -162,6 +178,16 @@ extern struct cmd_list_element *maint_cplus_cmd_list;
 
 char *gdb_demangle (const char *name, int options);
 
+/* Decode template information for TSYMBOL.  This function determines whether
+   the template's return and argument types are concrete types or template
+   parameters.  The symbol's obstack is used to allocate any needed memory.
+   If OPT_INFO is non-NULL, use the given demangle tree to do this.  Otherwise,
+   this function will demangle the template's linkage name.  */
+
+extern void
+  cp_decode_template_type_indices (struct template_symbol *tsymbol,
+                                  const struct demangle_parse_info *opt_info);
+
 /* Like gdb_demangle, but suitable for use as la_sniff_from_mangled_name.  */
 
 int gdb_sniff_from_mangled_name (const char *mangled, char **demangled);
index 540ae1a931c7c18a74070e31eef940f92b2ed238..72f7373b8884b2e1ae5cfcc12ca4a47f5a7624aa 100644 (file)
@@ -78,6 +78,9 @@
 typedef struct symbol *symbolp;
 DEF_VEC_P (symbolp);
 
+typedef enum template_argument_kinds template_argument_kinds_t;
+DEF_VEC_I (template_argument_kinds_t);
+
 /* When == 1, print basic high level tracing messages.
    When > 1, be more verbose.
    This is in contrast to the low level DIE reading of dwarf_die_debug.  */
@@ -11574,6 +11577,34 @@ possibly_add_new_xtor_method (const char *name, struct die_info *die,
     }
 }
 
+/* Return the type of the template parameter given by TAG.  */
+
+static enum template_argument_kinds
+dw2_template_param_kind (enum dwarf_tag tag)
+{
+  enum template_argument_kinds kind;
+
+  switch (tag)
+    {
+    case DW_TAG_template_type_param:
+      kind = type_parameter;
+      break;
+    case DW_TAG_template_value_param:
+      kind = value_parameter;
+      break;
+    case DW_TAG_GNU_template_template_param:
+      kind = template_parameter;
+      break;
+    case DW_TAG_GNU_template_parameter_pack:
+      kind = variadic_parameter;
+      break;
+    default:
+      gdb_assert_not_reached ("unexpected template parameter tag");
+    }
+
+  return kind;
+}
+
 static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -11589,7 +11620,10 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct block *block;
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
   VEC (symbolp) *template_args = NULL;
+  VEC (template_argument_kinds_t) *template_args_kinds = NULL;
+  VEC (symbolp) *template_arg_defaults = NULL;
   struct template_symbol *templ_func = NULL;
+  struct type *type;
 
   if (inlined_func)
     {
@@ -11648,9 +11682,9 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
        }
     }
 
+  type = read_type_die (die, cu);
   newobj = push_context (0, lowpc);
-  newobj->name = new_symbol_full (die, read_type_die (die, cu), cu,
-                              (struct symbol *) templ_func);
+  newobj->name = new_symbol_full (die, type, cu, (struct symbol *) templ_func);
 
   /* If there is a location expression for DW_AT_frame_base, record
      it.  */
@@ -11681,7 +11715,17 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
              struct symbol *arg = new_symbol (child_die, NULL, cu);
 
              if (arg != NULL)
-               VEC_safe_push (symbolp, template_args, arg);
+               {
+                 VEC_safe_push (symbolp, template_args, arg);
+                 VEC_safe_push (template_argument_kinds_t,
+                                template_args_kinds,
+                                dw2_template_param_kind (child_die->tag));
+                 if (dwarf2_flag_true_p (child_die,
+                                         DW_AT_default_value, cu))
+                   VEC_safe_push (symbolp, template_arg_defaults, arg);
+                 else
+                   VEC_safe_push (symbolp, template_arg_defaults, NULL);
+               }
            }
          else
            process_die (child_die, cu);
@@ -11740,15 +11784,37 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
     {
       gdb_assert (templ_func != NULL);
 
-      templ_func->n_template_arguments = VEC_length (symbolp, template_args);
       templ_func->template_arguments
+       = XOBNEW (&objfile->objfile_obstack, struct template_argument_info);
+      templ_func->template_arguments->n_arguments = VEC_length (symbolp, template_args);
+      templ_func->template_arguments->arguments
         = XOBNEWVEC (&objfile->objfile_obstack, struct symbol *,
-                    templ_func->n_template_arguments);
-      memcpy (templ_func->template_arguments,
+                    templ_func->template_arguments->n_arguments);
+      memcpy (templ_func->template_arguments->arguments,
              VEC_address (symbolp, template_args),
-             (templ_func->n_template_arguments * sizeof (struct symbol *)));
+             (templ_func->template_arguments->n_arguments * sizeof (struct symbol *)));
+      templ_func->template_arguments->argument_kinds
+       = XOBNEWVEC (&objfile->objfile_obstack, enum template_argument_kinds,
+                    templ_func->template_arguments->n_arguments);
+      memcpy (templ_func->template_arguments->argument_kinds,
+             VEC_address (template_argument_kinds_t, template_args_kinds),
+             (templ_func->template_arguments->n_arguments
+              * sizeof (enum template_argument_kinds)));
+      templ_func->template_arguments->default_arguments
+       = XOBNEWVEC (&objfile->objfile_obstack, struct symbol *,
+                    templ_func->template_arguments->n_arguments);
+      memcpy (templ_func->template_arguments->default_arguments,
+             VEC_address (symbolp, template_arg_defaults),
+             (templ_func->template_arguments->n_arguments * sizeof (struct symbol *)));
+
       VEC_free (symbolp, template_args);
+      VEC_free (template_argument_kinds_t, template_args_kinds);
+      VEC_free (symbolp, template_arg_defaults);
+
+      /* Determine whether the template's return and argument types were
+        specified using template parameters.  */
       const char *linkage_name = dw2_linkage_name (die, cu);
+      templ_func->linkage_name = linkage_name;
       if (linkage_name != NULL)
        {
          char *str;
@@ -13835,6 +13901,8 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
     {
       struct field_info fi;
       VEC (symbolp) *template_args = NULL;
+      VEC (template_argument_kinds_t) *template_args_kinds = NULL;
+      VEC (symbolp) *template_arg_defaults = NULL;
       struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
       memset (&fi, 0, sizeof (struct field_info));
@@ -13884,7 +13952,17 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
              struct symbol *arg = new_symbol (child_die, NULL, cu);
 
              if (arg != NULL)
-               VEC_safe_push (symbolp, template_args, arg);
+               {
+                 VEC_safe_push (symbolp, template_args, arg);
+                 VEC_safe_push (template_argument_kinds_t,
+                                template_args_kinds,
+                                dw2_template_param_kind (child_die->tag));
+                 if (dwarf2_flag_true_p (child_die,
+                                         DW_AT_default_value, cu))
+                   VEC_safe_push (symbolp, template_arg_defaults, arg);
+                 else
+                   VEC_safe_push (symbolp, template_arg_defaults, NULL);
+               }
            }
 
          child_die = sibling_die (child_die);
@@ -13894,17 +13972,36 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
       if (! VEC_empty (symbolp, template_args))
        {
          ALLOCATE_CPLUS_STRUCT_TYPE (type);
-         TYPE_N_TEMPLATE_ARGUMENTS (type)
+         TYPE_TEMPLATE_ARGUMENT_INFO (type)
+           = XOBNEW (&objfile->objfile_obstack, struct template_argument_info);
+         TYPE_TEMPLATE_ARGUMENT_INFO (type)->n_arguments
            = VEC_length (symbolp, template_args);
-         TYPE_TEMPLATE_ARGUMENTS (type)
+         TYPE_TEMPLATE_ARGUMENT_INFO (type)->arguments
            = XOBNEWVEC (&objfile->objfile_obstack,
                         struct symbol *,
                         TYPE_N_TEMPLATE_ARGUMENTS (type));
-         memcpy (TYPE_TEMPLATE_ARGUMENTS (type),
+         memcpy (TYPE_TEMPLATE_ARGUMENT_INFO (type)->arguments,
                  VEC_address (symbolp, template_args),
                  (TYPE_N_TEMPLATE_ARGUMENTS (type)
                   * sizeof (struct symbol *)));
+         TYPE_TEMPLATE_ARGUMENT_KINDS (type)
+           = XOBNEWVEC (&objfile->objfile_obstack,
+                        enum template_argument_kinds,
+                        TYPE_N_TEMPLATE_ARGUMENTS (type));
+         memcpy (TYPE_TEMPLATE_ARGUMENT_KINDS (type),
+                 VEC_address (template_argument_kinds_t, template_args_kinds),
+                 (TYPE_N_TEMPLATE_ARGUMENTS (type)
+                  * sizeof (enum template_argument_kinds)));
+         TYPE_TEMPLATE_DEFAULT_ARGUMENTS (type)
+           = XOBNEWVEC (&objfile->objfile_obstack, struct symbol *,
+                        TYPE_N_TEMPLATE_ARGUMENTS (type));
+         memcpy (TYPE_TEMPLATE_DEFAULT_ARGUMENTS (type),
+                 VEC_address (symbolp, template_arg_defaults),
+                 (TYPE_N_TEMPLATE_ARGUMENTS (type)
+                  * sizeof (struct symbol *)));
          VEC_free (symbolp, template_args);
+         VEC_free (template_argument_kinds_t, template_args_kinds);
+         VEC_free (symbolp, template_arg_defaults);
        }
 
       /* Attach fields and member functions to the type.  */
index f5a1a4d62196c3fc3132df6281a2b9cb623d6307..1064f0ae1b094b3970ae91d320e874c7b7627969 100644 (file)
@@ -915,6 +915,26 @@ struct decl_field
   unsigned int dummy : 13;
 };
 
+/* * Template function/type argument information.  */
+
+struct template_argument_info
+{
+    /* * Number of template arguments.  */
+  unsigned short n_arguments;
+
+  /* * The template arguments.  This is an array with n_arguments elements.  */
+  struct symbol **arguments;
+
+  /* * Default values.  An array with n_arguments elements.  Note that this
+     array only describes this particular instance!  It will not describe
+     default values for /all/ template instances (unless this instance uses
+     all the defaults).  This is a DWARF limitation.  */
+    struct symbol **default_arguments;
+
+    /* * The kinds of arguments.  An array with n_arguments elements.  */
+    enum template_argument_kinds *argument_kinds;
+};
+
 /* * C++ language-specific information for TYPE_CODE_STRUCT and
    TYPE_CODE_UNION nodes.  */
 
@@ -948,9 +968,10 @@ struct cplus_struct_type
 
     short nfn_fields;
 
-    /* * Number of template arguments.  */
+    /* * Template arguments, if any, or NULL if this type does not represent a
+       templated type.  */
 
-    unsigned short n_template_arguments;
+    struct template_argument_info *template_arguments;
 
     /* * One if this struct is a dynamic class, as defined by the
        Itanium C++ ABI: if it requires a virtual table pointer,
@@ -1022,12 +1043,6 @@ struct cplus_struct_type
     struct decl_field *nested_types;
 
     unsigned nested_types_count;
-
-    /* * The template arguments.  This is an array with
-       N_TEMPLATE_ARGUMENTS elements.  This is NULL for non-template
-       classes.  */
-
-    struct symbol **template_arguments;
   };
 
 /* * Struct used to store conversion rankings.  */
@@ -1425,12 +1440,24 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
 #define TYPE_FN_FIELDLIST_NAME(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].name
 #define TYPE_FN_FIELDLIST_LENGTH(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].length
 
+#define TYPE_TEMPLATE_ARGUMENT_INFO(thistype) \
+  TYPE_CPLUS_SPECIFIC (thistype)->template_arguments
 #define TYPE_N_TEMPLATE_ARGUMENTS(thistype) \
-  TYPE_CPLUS_SPECIFIC (thistype)->n_template_arguments
+  (TYPE_TEMPLATE_ARGUMENT_INFO (thistype) == NULL ? 0 \
+   : TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->n_arguments)
 #define TYPE_TEMPLATE_ARGUMENTS(thistype) \
-  TYPE_CPLUS_SPECIFIC (thistype)->template_arguments
+  (TYPE_TEMPLATE_ARGUMENT_INFO (thistype) == NULL ? NULL \
+   : TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->arguments)
 #define TYPE_TEMPLATE_ARGUMENT(thistype, n) \
-  TYPE_CPLUS_SPECIFIC (thistype)->template_arguments[n]
+  TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->arguments[n]
+#define TYPE_TEMPLATE_ARGUMENT_KINDS(thistype) \
+  TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->argument_kinds
+#define TYPE_TEMPLATE_ARGUMENT_KIND(thistype, n) \
+  TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->argument_kinds[n]
+#define TYPE_TEMPLATE_DEFAULT_ARGUMENTS(thistype) \
+  TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->default_arguments
+#define TYPE_TEMPLATE_DEFAULT_ARGUMENT(thistype, n) \
+  TYPE_TEMPLATE_ARGUMENT_INFO (thistype)->default_arguments[n]
 
 #define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
 #define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
index f5290b3d4c973ad5c7e3213695f32e9dd7f3bcb5..4053f1e4cd9371162d01f74cc93ac1834ee6220f 100644 (file)
@@ -6105,6 +6105,8 @@ allocate_template_symbol (struct objfile *objfile)
 
   result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
   initialize_objfile_symbol_1 (&result->base);
+  result->template_return_index = -1;
+  result->conversion_operator_index = -1;
 
   return result;
 }
index 07de87e51cae4296d6ae360f911726f58257a551..3f6029c47c00d150f4f266888ce43c5f12b03856 100644 (file)
@@ -907,12 +907,28 @@ struct template_symbol
   /* Search name of the template (it's name sans parameters).  */
   char *search_name;
 
-  /* The number of template arguments.  */
-  int n_template_arguments;
+  /* Information on template arguments.  */
+  struct template_argument_info *template_arguments;
 
-  /* The template arguments.  This is an array with
-     N_TEMPLATE_ARGUMENTS elements.  */
-  struct symbol **template_arguments;
+  /* The template's linkage name.  */
+  const char *linkage_name;
+
+  /* The template argument substitutions below are populated lazily to speed
+     up initial symbol reading.  This is done by parsing the symbol's
+     linkage name.  */
+
+  /* If the return type was specified as a template parameter, this will
+     hold the index of the template parameter used;  -1 otherwise.  */
+  long template_return_index;
+
+  /* Index into template_arguments describing the function's arguments
+     or -1 if the argument is not a template parameter.  There are
+     TYPE_NFIELDS entries.  */
+  long *template_argument_indices;
+
+  /* If this symbol is a conversion operator, this records which template
+     parameter is used for the conversion; -1 otherwise.  */
+  long conversion_operator_index;
 };
 
 \f