diff options
author | Keith Seitz <keiths@redhat.com> | 2017-02-17 11:05:52 -0800 |
---|---|---|
committer | Keith Seitz <keiths@redhat.com> | 2017-02-21 13:33:45 -0800 |
commit | 882b3a06fd27ecbbe562d137a0eac62034f00651 (patch) | |
tree | 3e2923944e066c51890a016ba83ee39134c39676 | |
parent | 8e4430c2ec07ca8cc824b87da8a9c0cc917ad686 (diff) | |
download | gdb-882b3a06fd27ecbbe562d137a0eac62034f00651.zip gdb-882b3a06fd27ecbbe562d137a0eac62034f00651.tar.gz gdb-882b3a06fd27ecbbe562d137a0eac62034f00651.tar.bz2 |
Introduce template arguments and default values.
-rw-r--r-- | gdb/cp-abi.h | 16 | ||||
-rw-r--r-- | gdb/cp-name-parser.y | 6 | ||||
-rw-r--r-- | gdb/cp-namespace.c | 6 | ||||
-rw-r--r-- | gdb/cp-support.c | 208 | ||||
-rw-r--r-- | gdb/cp-support.h | 30 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 119 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 49 | ||||
-rw-r--r-- | gdb/symtab.c | 2 | ||||
-rw-r--r-- | gdb/symtab.h | 26 |
9 files changed, 403 insertions, 59 deletions
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h index 968f92c..9620da1 100644 --- a/gdb/cp-abi.h +++ b/gdb/cp-abi.h @@ -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* diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index 14a78f1..0db5552 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -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 diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index b96c421..ca0ab47 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -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) { diff --git a/gdb/cp-support.c b/gdb/cp-support.c index b6f9605..f77546a 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -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) { diff --git a/gdb/cp-support.h b/gdb/cp-support.h index d14e9cc..85d6461 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -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); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 540ae1a..72f7373 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -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. */ diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index f5a1a4d..1064f0a 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -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 diff --git a/gdb/symtab.c b/gdb/symtab.c index f5290b3..4053f1e 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -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; } diff --git a/gdb/symtab.h b/gdb/symtab.h index 07de87e..3f6029c 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -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; }; |