gdb
PR c++/9946: * symfile.c (reread_symbols): Clear template_symbols. * symtab.h (struct symbol) <is_cplus_template_function>: New field. (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION): New macro. (struct template_symbol): New. * symtab.c (lookup_symbol_aux_local): Use cp_lookup_symbol_imports_or_template. * objfiles.h (struct objfile) <template_symbols>: New field. * objfiles.c (relocate_one_symbol): New function. (objfile_relocate1): Use it. Relocate isolated symbols. * gdbtypes.h (struct cplus_struct_type) <n_template_arguments, template_arguments>: New fields. (TYPE_N_TEMPLATE_ARGUMENTS): New macro. (TYPE_TEMPLATE_ARGUMENTS): Likewise. (TYPE_TEMPLATE_ARGUMENT): Likewise. (lookup_typename): Update. * gdbtypes.c (lookup_typename): Constify "block" argument. * dwarf2read.c: Include vec.h. (symbolp): New typedef. (read_func_scope): Read template arguments. Allocate a template_symbol when needed. (read_structure_type): Read template arguments. (new_symbol_full): New function, from new_symbol. Handle DW_TAG_template_type_param and DW_TAG_template_value_param. (new_symbol): Rewrite as wrapper. * cp-support.h (cp_lookup_symbol_imports_or_template): Declare. * cp-namespace.c: Include language.h. (search_symbol_list): New function. (cp_lookup_symbol_imports_or_template): Likewise. gdb/testsuite PR c++/9946: * gdb.cp/temargs.exp: New file. * gdb.cp/temargs.cc: New file.
This commit is contained in:
parent
75bc1f8113
commit
34eaf5422c
14 changed files with 532 additions and 40 deletions
|
@ -1,3 +1,36 @@
|
||||||
|
2010-07-28 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
PR c++/9946:
|
||||||
|
* symfile.c (reread_symbols): Clear template_symbols.
|
||||||
|
* symtab.h (struct symbol) <is_cplus_template_function>: New
|
||||||
|
field.
|
||||||
|
(SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION): New macro.
|
||||||
|
(struct template_symbol): New.
|
||||||
|
* symtab.c (lookup_symbol_aux_local): Use
|
||||||
|
cp_lookup_symbol_imports_or_template.
|
||||||
|
* objfiles.h (struct objfile) <template_symbols>: New field.
|
||||||
|
* objfiles.c (relocate_one_symbol): New function.
|
||||||
|
(objfile_relocate1): Use it. Relocate isolated symbols.
|
||||||
|
* gdbtypes.h (struct cplus_struct_type) <n_template_arguments,
|
||||||
|
template_arguments>: New fields.
|
||||||
|
(TYPE_N_TEMPLATE_ARGUMENTS): New macro.
|
||||||
|
(TYPE_TEMPLATE_ARGUMENTS): Likewise.
|
||||||
|
(TYPE_TEMPLATE_ARGUMENT): Likewise.
|
||||||
|
(lookup_typename): Update.
|
||||||
|
* gdbtypes.c (lookup_typename): Constify "block" argument.
|
||||||
|
* dwarf2read.c: Include vec.h.
|
||||||
|
(symbolp): New typedef.
|
||||||
|
(read_func_scope): Read template arguments. Allocate a
|
||||||
|
template_symbol when needed.
|
||||||
|
(read_structure_type): Read template arguments.
|
||||||
|
(new_symbol_full): New function, from new_symbol. Handle
|
||||||
|
DW_TAG_template_type_param and DW_TAG_template_value_param.
|
||||||
|
(new_symbol): Rewrite as wrapper.
|
||||||
|
* cp-support.h (cp_lookup_symbol_imports_or_template): Declare.
|
||||||
|
* cp-namespace.c: Include language.h.
|
||||||
|
(search_symbol_list): New function.
|
||||||
|
(cp_lookup_symbol_imports_or_template): Likewise.
|
||||||
|
|
||||||
2010-07-28 Balazs Kezes <rlblaster@gmail.com>
|
2010-07-28 Balazs Kezes <rlblaster@gmail.com>
|
||||||
|
|
||||||
* tui/tui-win.c (make_visible_with_new_height): Resize and move
|
* tui/tui-win.c (make_visible_with_new_height): Resize and move
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "buildsym.h"
|
#include "buildsym.h"
|
||||||
|
#include "language.h"
|
||||||
|
|
||||||
static struct symbol *lookup_namespace_scope (const char *name,
|
static struct symbol *lookup_namespace_scope (const char *name,
|
||||||
const struct block *block,
|
const struct block *block,
|
||||||
|
@ -412,6 +413,95 @@ cp_lookup_symbol_imports (const char *scope,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper function that searches an array of symbols for one named
|
||||||
|
NAME. */
|
||||||
|
|
||||||
|
static struct symbol *
|
||||||
|
search_symbol_list (const char *name, int num, struct symbol **syms)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Maybe we should store a dictionary in here instead. */
|
||||||
|
for (i = 0; i < num; ++i)
|
||||||
|
{
|
||||||
|
if (strcmp (name, SYMBOL_NATURAL_NAME (syms[i])) == 0)
|
||||||
|
return syms[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like cp_lookup_symbol_imports, but if BLOCK is a function, it
|
||||||
|
searches through the template parameters of the function and the
|
||||||
|
function's type. */
|
||||||
|
|
||||||
|
struct symbol *
|
||||||
|
cp_lookup_symbol_imports_or_template (const char *scope,
|
||||||
|
const char *name,
|
||||||
|
const struct block *block,
|
||||||
|
const domain_enum domain)
|
||||||
|
{
|
||||||
|
struct symbol *function = BLOCK_FUNCTION (block);
|
||||||
|
|
||||||
|
if (function != NULL && SYMBOL_LANGUAGE (function) == language_cplus)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct cplus_specific *cps
|
||||||
|
= function->ginfo.language_specific.cplus_specific;
|
||||||
|
|
||||||
|
/* Search the function's template parameters. */
|
||||||
|
if (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (function))
|
||||||
|
{
|
||||||
|
struct template_symbol *templ = (struct template_symbol *) function;
|
||||||
|
struct symbol *result;
|
||||||
|
|
||||||
|
result = search_symbol_list (name,
|
||||||
|
templ->n_template_arguments,
|
||||||
|
templ->template_arguments);
|
||||||
|
if (result != NULL)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search the template parameters of the function's defining
|
||||||
|
context. */
|
||||||
|
if (SYMBOL_NATURAL_NAME (function))
|
||||||
|
{
|
||||||
|
struct type *context;
|
||||||
|
char *name_copy = xstrdup (SYMBOL_NATURAL_NAME (function));
|
||||||
|
struct cleanup *cleanups = make_cleanup (xfree, name_copy);
|
||||||
|
const struct language_defn *lang = language_def (language_cplus);
|
||||||
|
struct gdbarch *arch = SYMBOL_SYMTAB (function)->objfile->gdbarch;
|
||||||
|
const struct block *parent = BLOCK_SUPERBLOCK (block);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
struct symbol *result;
|
||||||
|
unsigned int prefix_len = cp_entire_prefix_len (name_copy);
|
||||||
|
|
||||||
|
if (prefix_len == 0)
|
||||||
|
context = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name_copy[prefix_len] = '\0';
|
||||||
|
context = lookup_typename (lang, arch, name_copy, parent, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
result = search_symbol_list (name,
|
||||||
|
TYPE_N_TEMPLATE_ARGUMENTS (context),
|
||||||
|
TYPE_TEMPLATE_ARGUMENTS (context));
|
||||||
|
if (result != NULL)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cleanups (cleanups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cp_lookup_symbol_imports (scope, name, block, domain, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Searches for NAME in the current namespace, and by applying relevant import
|
/* Searches for NAME in the current namespace, and by applying relevant import
|
||||||
statements belonging to BLOCK and its parents. SCOPE is the namespace scope
|
statements belonging to BLOCK and its parents. SCOPE is the namespace scope
|
||||||
of the context in which the search is being evaluated. */
|
of the context in which the search is being evaluated. */
|
||||||
|
|
|
@ -158,6 +158,12 @@ extern struct symbol *cp_lookup_symbol_imports (const char *scope,
|
||||||
const int declaration_only,
|
const int declaration_only,
|
||||||
const int search_parents);
|
const int search_parents);
|
||||||
|
|
||||||
|
extern struct symbol *cp_lookup_symbol_imports_or_template
|
||||||
|
(const char *scope,
|
||||||
|
const char *name,
|
||||||
|
const struct block *block,
|
||||||
|
const domain_enum domain);
|
||||||
|
|
||||||
extern struct type *cp_lookup_nested_type (struct type *parent_type,
|
extern struct type *cp_lookup_nested_type (struct type *parent_type,
|
||||||
const char *nested_name,
|
const char *nested_name,
|
||||||
const struct block *block);
|
const struct block *block);
|
||||||
|
|
161
gdb/dwarf2read.c
161
gdb/dwarf2read.c
|
@ -54,6 +54,7 @@
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "gdb_stat.h"
|
#include "gdb_stat.h"
|
||||||
#include "completer.h"
|
#include "completer.h"
|
||||||
|
#include "vec.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
|
@ -69,6 +70,9 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct symbol *symbolp;
|
||||||
|
DEF_VEC_P (symbolp);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* .debug_info header for a compilation unit
|
/* .debug_info header for a compilation unit
|
||||||
Because of alignment constraints, this structure has padding and cannot
|
Because of alignment constraints, this structure has padding and cannot
|
||||||
|
@ -969,6 +973,9 @@ static void dwarf2_start_subfile (char *, char *, char *);
|
||||||
static struct symbol *new_symbol (struct die_info *, struct type *,
|
static struct symbol *new_symbol (struct die_info *, struct type *,
|
||||||
struct dwarf2_cu *);
|
struct dwarf2_cu *);
|
||||||
|
|
||||||
|
static struct symbol *new_symbol_full (struct die_info *, struct type *,
|
||||||
|
struct dwarf2_cu *, struct symbol *);
|
||||||
|
|
||||||
static void dwarf2_const_value (struct attribute *, struct symbol *,
|
static void dwarf2_const_value (struct attribute *, struct symbol *,
|
||||||
struct dwarf2_cu *);
|
struct dwarf2_cu *);
|
||||||
|
|
||||||
|
@ -5049,6 +5056,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
CORE_ADDR baseaddr;
|
CORE_ADDR baseaddr;
|
||||||
struct block *block;
|
struct block *block;
|
||||||
int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
|
int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
|
||||||
|
VEC (symbolp) *template_args = NULL;
|
||||||
|
struct template_symbol *templ_func = NULL;
|
||||||
|
|
||||||
if (inlined_func)
|
if (inlined_func)
|
||||||
{
|
{
|
||||||
|
@ -5094,8 +5103,23 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
/* Record the function range for dwarf_decode_lines. */
|
/* Record the function range for dwarf_decode_lines. */
|
||||||
add_to_cu_func_list (name, lowpc, highpc, cu);
|
add_to_cu_func_list (name, lowpc, highpc, cu);
|
||||||
|
|
||||||
|
/* If we have any template arguments, then we must allocate a
|
||||||
|
different sort of symbol. */
|
||||||
|
for (child_die = die->child; child_die; child_die = sibling_die (child_die))
|
||||||
|
{
|
||||||
|
if (child_die->tag == DW_TAG_template_type_param
|
||||||
|
|| child_die->tag == DW_TAG_template_value_param)
|
||||||
|
{
|
||||||
|
templ_func = OBSTACK_ZALLOC (&objfile->objfile_obstack,
|
||||||
|
struct template_symbol);
|
||||||
|
templ_func->base.is_cplus_template_function = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new = push_context (0, lowpc);
|
new = push_context (0, lowpc);
|
||||||
new->name = new_symbol (die, read_type_die (die, cu), cu);
|
new->name = new_symbol_full (die, read_type_die (die, cu), cu,
|
||||||
|
(struct symbol *) templ_func);
|
||||||
|
|
||||||
/* If there is a location expression for DW_AT_frame_base, record
|
/* If there is a location expression for DW_AT_frame_base, record
|
||||||
it. */
|
it. */
|
||||||
|
@ -5119,7 +5143,15 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
child_die = die->child;
|
child_die = die->child;
|
||||||
while (child_die && child_die->tag)
|
while (child_die && child_die->tag)
|
||||||
{
|
{
|
||||||
process_die (child_die, cu);
|
if (child_die->tag == DW_TAG_template_type_param
|
||||||
|
|| child_die->tag == DW_TAG_template_value_param)
|
||||||
|
{
|
||||||
|
struct symbol *arg = new_symbol (child_die, NULL, cu);
|
||||||
|
|
||||||
|
VEC_safe_push (symbolp, template_args, arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
process_die (child_die, cu);
|
||||||
child_die = sibling_die (child_die);
|
child_die = sibling_die (child_die);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5165,6 +5197,22 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
/* If we have address ranges, record them. */
|
/* If we have address ranges, record them. */
|
||||||
dwarf2_record_block_ranges (die, block, baseaddr, cu);
|
dwarf2_record_block_ranges (die, block, baseaddr, cu);
|
||||||
|
|
||||||
|
/* Attach template arguments to function. */
|
||||||
|
if (! VEC_empty (symbolp, template_args))
|
||||||
|
{
|
||||||
|
gdb_assert (templ_func != NULL);
|
||||||
|
|
||||||
|
templ_func->n_template_arguments = VEC_length (symbolp, template_args);
|
||||||
|
templ_func->template_arguments
|
||||||
|
= obstack_alloc (&objfile->objfile_obstack,
|
||||||
|
(templ_func->n_template_arguments
|
||||||
|
* sizeof (struct symbol *)));
|
||||||
|
memcpy (templ_func->template_arguments,
|
||||||
|
VEC_address (symbolp, template_args),
|
||||||
|
(templ_func->n_template_arguments * sizeof (struct symbol *)));
|
||||||
|
VEC_free (symbolp, template_args);
|
||||||
|
}
|
||||||
|
|
||||||
/* In C++, we can have functions nested inside functions (e.g., when
|
/* In C++, we can have functions nested inside functions (e.g., when
|
||||||
a function declares a class that has methods). This means that
|
a function declares a class that has methods). This means that
|
||||||
when we finish processing a function scope, we may need to go
|
when we finish processing a function scope, we may need to go
|
||||||
|
@ -6372,6 +6420,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
{
|
{
|
||||||
struct field_info fi;
|
struct field_info fi;
|
||||||
struct die_info *child_die;
|
struct die_info *child_die;
|
||||||
|
VEC (symbolp) *template_args = NULL;
|
||||||
|
|
||||||
memset (&fi, 0, sizeof (struct field_info));
|
memset (&fi, 0, sizeof (struct field_info));
|
||||||
|
|
||||||
|
@ -6401,9 +6450,34 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
}
|
}
|
||||||
else if (child_die->tag == DW_TAG_typedef)
|
else if (child_die->tag == DW_TAG_typedef)
|
||||||
dwarf2_add_typedef (&fi, child_die, cu);
|
dwarf2_add_typedef (&fi, child_die, cu);
|
||||||
|
else if (child_die->tag == DW_TAG_template_type_param
|
||||||
|
|| child_die->tag == DW_TAG_template_value_param)
|
||||||
|
{
|
||||||
|
struct symbol *arg = new_symbol (child_die, NULL, cu);
|
||||||
|
|
||||||
|
VEC_safe_push (symbolp, template_args, arg);
|
||||||
|
}
|
||||||
|
|
||||||
child_die = sibling_die (child_die);
|
child_die = sibling_die (child_die);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attach template arguments to type. */
|
||||||
|
if (! VEC_empty (symbolp, template_args))
|
||||||
|
{
|
||||||
|
ALLOCATE_CPLUS_STRUCT_TYPE (type);
|
||||||
|
TYPE_N_TEMPLATE_ARGUMENTS (type)
|
||||||
|
= VEC_length (symbolp, template_args);
|
||||||
|
TYPE_TEMPLATE_ARGUMENTS (type)
|
||||||
|
= obstack_alloc (&objfile->objfile_obstack,
|
||||||
|
(TYPE_N_TEMPLATE_ARGUMENTS (type)
|
||||||
|
* sizeof (struct symbol *)));
|
||||||
|
memcpy (TYPE_TEMPLATE_ARGUMENTS (type),
|
||||||
|
VEC_address (symbolp, template_args),
|
||||||
|
(TYPE_N_TEMPLATE_ARGUMENTS (type)
|
||||||
|
* sizeof (struct symbol *)));
|
||||||
|
VEC_free (symbolp, template_args);
|
||||||
|
}
|
||||||
|
|
||||||
/* Attach fields and member functions to the type. */
|
/* Attach fields and member functions to the type. */
|
||||||
if (fi.nfields)
|
if (fi.nfields)
|
||||||
dwarf2_attach_fields_to_type (&fi, type, cu);
|
dwarf2_attach_fields_to_type (&fi, type, cu);
|
||||||
|
@ -6526,7 +6600,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
{
|
{
|
||||||
if (child_die->tag == DW_TAG_member
|
if (child_die->tag == DW_TAG_member
|
||||||
|| child_die->tag == DW_TAG_variable
|
|| child_die->tag == DW_TAG_variable
|
||||||
|| child_die->tag == DW_TAG_inheritance)
|
|| child_die->tag == DW_TAG_inheritance
|
||||||
|
|| child_die->tag == DW_TAG_template_value_param
|
||||||
|
|| child_die->tag == DW_TAG_template_type_param)
|
||||||
{
|
{
|
||||||
/* Do nothing. */
|
/* Do nothing. */
|
||||||
}
|
}
|
||||||
|
@ -9867,10 +9943,13 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
|
||||||
to make a symbol table entry for it, and if so, create a new entry
|
to make a symbol table entry for it, and if so, create a new entry
|
||||||
and return a pointer to it.
|
and return a pointer to it.
|
||||||
If TYPE is NULL, determine symbol type from the die, otherwise
|
If TYPE is NULL, determine symbol type from the die, otherwise
|
||||||
used the passed type. */
|
used the passed type.
|
||||||
|
If SPACE is not NULL, use it to hold the new symbol. If it is
|
||||||
|
NULL, allocate a new symbol on the objfile's obstack. */
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
|
||||||
|
struct symbol *space)
|
||||||
{
|
{
|
||||||
struct objfile *objfile = cu->objfile;
|
struct objfile *objfile = cu->objfile;
|
||||||
struct symbol *sym = NULL;
|
struct symbol *sym = NULL;
|
||||||
|
@ -9886,11 +9965,13 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
const char *linkagename;
|
const char *linkagename;
|
||||||
|
int suppress_add = 0;
|
||||||
|
|
||||||
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
|
if (space)
|
||||||
sizeof (struct symbol));
|
sym = space;
|
||||||
|
else
|
||||||
|
sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
|
||||||
OBJSTAT (objfile, n_syms++);
|
OBJSTAT (objfile, n_syms++);
|
||||||
memset (sym, 0, sizeof (struct symbol));
|
|
||||||
|
|
||||||
/* Cache this symbol's name and the name's demangled form (if any). */
|
/* Cache this symbol's name and the name's demangled form (if any). */
|
||||||
SYMBOL_LANGUAGE (sym) = cu->language;
|
SYMBOL_LANGUAGE (sym) = cu->language;
|
||||||
|
@ -9983,6 +10064,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
/* Do not add the symbol to any lists. It will be found via
|
/* Do not add the symbol to any lists. It will be found via
|
||||||
BLOCK_FUNCTION from the blockvector. */
|
BLOCK_FUNCTION from the blockvector. */
|
||||||
break;
|
break;
|
||||||
|
case DW_TAG_template_value_param:
|
||||||
|
suppress_add = 1;
|
||||||
|
/* Fall through. */
|
||||||
case DW_TAG_variable:
|
case DW_TAG_variable:
|
||||||
case DW_TAG_member:
|
case DW_TAG_member:
|
||||||
/* Compilation with minimal debug info may result in variables
|
/* Compilation with minimal debug info may result in variables
|
||||||
|
@ -10006,10 +10090,18 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
{
|
{
|
||||||
dwarf2_const_value (attr, sym, cu);
|
dwarf2_const_value (attr, sym, cu);
|
||||||
attr2 = dwarf2_attr (die, DW_AT_external, cu);
|
attr2 = dwarf2_attr (die, DW_AT_external, cu);
|
||||||
if (attr2 && (DW_UNSND (attr2) != 0))
|
if (suppress_add)
|
||||||
add_symbol_to_list (sym, &global_symbols);
|
{
|
||||||
|
sym->hash_next = objfile->template_symbols;
|
||||||
|
objfile->template_symbols = sym;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
add_symbol_to_list (sym, cu->list_in_scope);
|
{
|
||||||
|
if (attr2 && (DW_UNSND (attr2) != 0))
|
||||||
|
add_symbol_to_list (sym, &global_symbols);
|
||||||
|
else
|
||||||
|
add_symbol_to_list (sym, cu->list_in_scope);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
attr = dwarf2_attr (die, DW_AT_location, cu);
|
attr = dwarf2_attr (die, DW_AT_location, cu);
|
||||||
|
@ -10073,13 +10165,25 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
? &global_symbols : cu->list_in_scope);
|
? &global_symbols : cu->list_in_scope);
|
||||||
|
|
||||||
SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
|
SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
|
||||||
add_symbol_to_list (sym, list_to_add);
|
if (suppress_add)
|
||||||
|
{
|
||||||
|
sym->hash_next = objfile->template_symbols;
|
||||||
|
objfile->template_symbols = sym;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
add_symbol_to_list (sym, list_to_add);
|
||||||
}
|
}
|
||||||
else if (!die_is_declaration (die, cu))
|
else if (!die_is_declaration (die, cu))
|
||||||
{
|
{
|
||||||
/* Use the default LOC_OPTIMIZED_OUT class. */
|
/* Use the default LOC_OPTIMIZED_OUT class. */
|
||||||
gdb_assert (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT);
|
gdb_assert (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT);
|
||||||
add_symbol_to_list (sym, cu->list_in_scope);
|
if (suppress_add)
|
||||||
|
{
|
||||||
|
sym->hash_next = objfile->template_symbols;
|
||||||
|
objfile->template_symbols = sym;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
add_symbol_to_list (sym, cu->list_in_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -10118,6 +10222,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
interest in this information, so just ignore it for now.
|
interest in this information, so just ignore it for now.
|
||||||
(FIXME?) */
|
(FIXME?) */
|
||||||
break;
|
break;
|
||||||
|
case DW_TAG_template_type_param:
|
||||||
|
suppress_add = 1;
|
||||||
|
/* Fall through. */
|
||||||
case DW_TAG_class_type:
|
case DW_TAG_class_type:
|
||||||
case DW_TAG_interface_type:
|
case DW_TAG_interface_type:
|
||||||
case DW_TAG_structure_type:
|
case DW_TAG_structure_type:
|
||||||
|
@ -10136,14 +10243,22 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
saves you. See the OtherFileClass tests in
|
saves you. See the OtherFileClass tests in
|
||||||
gdb.c++/namespace.exp. */
|
gdb.c++/namespace.exp. */
|
||||||
|
|
||||||
struct pending **list_to_add;
|
if (suppress_add)
|
||||||
|
{
|
||||||
|
sym->hash_next = objfile->template_symbols;
|
||||||
|
objfile->template_symbols = sym;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct pending **list_to_add;
|
||||||
|
|
||||||
list_to_add = (cu->list_in_scope == &file_symbols
|
list_to_add = (cu->list_in_scope == &file_symbols
|
||||||
&& (cu->language == language_cplus
|
&& (cu->language == language_cplus
|
||||||
|| cu->language == language_java)
|
|| cu->language == language_java)
|
||||||
? &global_symbols : cu->list_in_scope);
|
? &global_symbols : cu->list_in_scope);
|
||||||
|
|
||||||
add_symbol_to_list (sym, list_to_add);
|
add_symbol_to_list (sym, list_to_add);
|
||||||
|
}
|
||||||
|
|
||||||
/* The semantics of C++ state that "struct foo { ... }" also
|
/* The semantics of C++ state that "struct foo { ... }" also
|
||||||
defines a typedef for "foo". A Java class declaration also
|
defines a typedef for "foo". A Java class declaration also
|
||||||
|
@ -10214,6 +10329,14 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
return (sym);
|
return (sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A wrapper for new_symbol_full that always allocates a new symbol. */
|
||||||
|
|
||||||
|
static struct symbol *
|
||||||
|
new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
||||||
|
{
|
||||||
|
return new_symbol_full (die, type, cu, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy constant value from an attribute to a symbol. */
|
/* Copy constant value from an attribute to a symbol. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1046,7 +1046,7 @@ type_name_no_tag (const struct type *type)
|
||||||
struct type *
|
struct type *
|
||||||
lookup_typename (const struct language_defn *language,
|
lookup_typename (const struct language_defn *language,
|
||||||
struct gdbarch *gdbarch, char *name,
|
struct gdbarch *gdbarch, char *name,
|
||||||
struct block *block, int noerr)
|
const struct block *block, int noerr)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct type *tmp;
|
struct type *tmp;
|
||||||
|
|
|
@ -681,6 +681,9 @@ struct cplus_struct_type
|
||||||
|
|
||||||
short nfn_fields_total;
|
short nfn_fields_total;
|
||||||
|
|
||||||
|
/* Number of template arguments. */
|
||||||
|
unsigned short n_template_arguments;
|
||||||
|
|
||||||
/* One if this struct is a dynamic class, as defined by the
|
/* One if this struct is a dynamic class, as defined by the
|
||||||
Itanium C++ ABI: if it requires a virtual table pointer,
|
Itanium C++ ABI: if it requires a virtual table pointer,
|
||||||
because it or any of its base classes have one or more virtual
|
because it or any of its base classes have one or more virtual
|
||||||
|
@ -826,6 +829,11 @@ struct cplus_struct_type
|
||||||
}
|
}
|
||||||
*typedef_field;
|
*typedef_field;
|
||||||
unsigned typedef_field_count;
|
unsigned typedef_field_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 in computing virtual base list */
|
/* Struct used in computing virtual base list */
|
||||||
|
@ -1023,6 +1031,13 @@ extern void allocate_gnat_aux_type (struct type *);
|
||||||
#define TYPE_FN_FIELDLIST_NAME(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].name
|
#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_FN_FIELDLIST_LENGTH(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].length
|
||||||
|
|
||||||
|
#define TYPE_N_TEMPLATE_ARGUMENTS(thistype) \
|
||||||
|
TYPE_CPLUS_SPECIFIC (thistype)->n_template_arguments
|
||||||
|
#define TYPE_TEMPLATE_ARGUMENTS(thistype) \
|
||||||
|
TYPE_CPLUS_SPECIFIC (thistype)->template_arguments
|
||||||
|
#define TYPE_TEMPLATE_ARGUMENT(thistype, n) \
|
||||||
|
TYPE_CPLUS_SPECIFIC (thistype)->template_arguments[n]
|
||||||
|
|
||||||
#define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
|
#define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
|
||||||
#define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
|
#define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
|
||||||
#define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
|
#define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
|
||||||
|
@ -1353,7 +1368,7 @@ extern char *gdb_mangle_name (struct type *, int, int);
|
||||||
|
|
||||||
extern struct type *lookup_typename (const struct language_defn *,
|
extern struct type *lookup_typename (const struct language_defn *,
|
||||||
struct gdbarch *, char *,
|
struct gdbarch *, char *,
|
||||||
struct block *, int);
|
const struct block *, int);
|
||||||
|
|
||||||
extern struct type *lookup_template_type (char *, struct type *,
|
extern struct type *lookup_template_type (char *, struct type *,
|
||||||
struct block *);
|
struct block *);
|
||||||
|
|
|
@ -702,6 +702,27 @@ free_all_objfiles (void)
|
||||||
clear_symtab_users ();
|
clear_symtab_users ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A helper function for objfile_relocate1 that relocates a single
|
||||||
|
symbol. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
relocate_one_symbol (struct symbol *sym, struct objfile *objfile,
|
||||||
|
struct section_offsets *delta)
|
||||||
|
{
|
||||||
|
fixup_symbol_section (sym, objfile);
|
||||||
|
|
||||||
|
/* The RS6000 code from which this was taken skipped
|
||||||
|
any symbols in STRUCT_DOMAIN or UNDEF_DOMAIN.
|
||||||
|
But I'm leaving out that test, on the theory that
|
||||||
|
they can't possibly pass the tests below. */
|
||||||
|
if ((SYMBOL_CLASS (sym) == LOC_LABEL
|
||||||
|
|| SYMBOL_CLASS (sym) == LOC_STATIC)
|
||||||
|
&& SYMBOL_SECTION (sym) >= 0)
|
||||||
|
{
|
||||||
|
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (delta, SYMBOL_SECTION (sym));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
|
/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
|
||||||
entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here.
|
entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here.
|
||||||
Return non-zero iff any change happened. */
|
Return non-zero iff any change happened. */
|
||||||
|
@ -767,24 +788,20 @@ objfile_relocate1 (struct objfile *objfile,
|
||||||
|
|
||||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||||
{
|
{
|
||||||
fixup_symbol_section (sym, objfile);
|
relocate_one_symbol (sym, objfile, delta);
|
||||||
|
|
||||||
/* The RS6000 code from which this was taken skipped
|
|
||||||
any symbols in STRUCT_DOMAIN or UNDEF_DOMAIN.
|
|
||||||
But I'm leaving out that test, on the theory that
|
|
||||||
they can't possibly pass the tests below. */
|
|
||||||
if ((SYMBOL_CLASS (sym) == LOC_LABEL
|
|
||||||
|| SYMBOL_CLASS (sym) == LOC_STATIC)
|
|
||||||
&& SYMBOL_SECTION (sym) >= 0)
|
|
||||||
{
|
|
||||||
SYMBOL_VALUE_ADDRESS (sym) +=
|
|
||||||
ANOFFSET (delta, SYMBOL_SECTION (sym));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Relocate isolated symbols. */
|
||||||
|
{
|
||||||
|
struct symbol *iter;
|
||||||
|
|
||||||
|
for (iter = objfile->template_symbols; iter; iter = iter->hash_next)
|
||||||
|
relocate_one_symbol (iter, objfile, delta);
|
||||||
|
}
|
||||||
|
|
||||||
if (objfile->psymtabs_addrmap)
|
if (objfile->psymtabs_addrmap)
|
||||||
addrmap_relocate (objfile->psymtabs_addrmap,
|
addrmap_relocate (objfile->psymtabs_addrmap,
|
||||||
ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
|
ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
|
||||||
|
|
|
@ -391,6 +391,12 @@ struct objfile
|
||||||
/* FIXME/carlton-2003-06-27: Delete this in a few years once
|
/* FIXME/carlton-2003-06-27: Delete this in a few years once
|
||||||
"possible namespace symbols" go away. */
|
"possible namespace symbols" go away. */
|
||||||
struct symtab *cp_namespace_symtab;
|
struct symtab *cp_namespace_symtab;
|
||||||
|
|
||||||
|
/* A linked list of symbols created when reading template types or
|
||||||
|
function templates. These symbols are not stored in any symbol
|
||||||
|
table, so we have to keep them here to relocate them
|
||||||
|
properly. */
|
||||||
|
struct symbol *template_symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Defines for the objfile flag word. */
|
/* Defines for the objfile flag word. */
|
||||||
|
|
|
@ -2420,6 +2420,7 @@ reread_symbols (void)
|
||||||
objfile->psymtabs_addrmap = NULL;
|
objfile->psymtabs_addrmap = NULL;
|
||||||
objfile->free_psymtabs = NULL;
|
objfile->free_psymtabs = NULL;
|
||||||
objfile->cp_namespace_symtab = NULL;
|
objfile->cp_namespace_symtab = NULL;
|
||||||
|
objfile->template_symbols = NULL;
|
||||||
objfile->msymbols = NULL;
|
objfile->msymbols = NULL;
|
||||||
objfile->deprecated_sym_private = NULL;
|
objfile->deprecated_sym_private = NULL;
|
||||||
objfile->minimal_symbol_count = 0;
|
objfile->minimal_symbol_count = 0;
|
||||||
|
|
|
@ -1227,12 +1227,8 @@ lookup_symbol_aux_local (const char *name, const struct block *block,
|
||||||
|
|
||||||
if (language == language_cplus || language == language_fortran)
|
if (language == language_cplus || language == language_fortran)
|
||||||
{
|
{
|
||||||
sym = cp_lookup_symbol_imports (scope,
|
sym = cp_lookup_symbol_imports_or_template (scope, name, block,
|
||||||
name,
|
domain);
|
||||||
block,
|
|
||||||
domain,
|
|
||||||
1,
|
|
||||||
1);
|
|
||||||
if (sym != NULL)
|
if (sym != NULL)
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
26
gdb/symtab.h
26
gdb/symtab.h
|
@ -589,6 +589,10 @@ struct symbol
|
||||||
/* Whether this is an inlined function (class LOC_BLOCK only). */
|
/* Whether this is an inlined function (class LOC_BLOCK only). */
|
||||||
unsigned is_inlined : 1;
|
unsigned is_inlined : 1;
|
||||||
|
|
||||||
|
/* True if this is a C++ function symbol with template arguments.
|
||||||
|
In this case the symbol is really a "struct template_symbol". */
|
||||||
|
unsigned is_cplus_template_function : 1;
|
||||||
|
|
||||||
/* Line number of this symbol's definition, except for inlined
|
/* Line number of this symbol's definition, except for inlined
|
||||||
functions. For an inlined function (class LOC_BLOCK and
|
functions. For an inlined function (class LOC_BLOCK and
|
||||||
SYMBOL_INLINED set) this is the line number of the function's call
|
SYMBOL_INLINED set) this is the line number of the function's call
|
||||||
|
@ -636,12 +640,34 @@ struct symbol
|
||||||
#define SYMBOL_CLASS(symbol) (symbol)->aclass
|
#define SYMBOL_CLASS(symbol) (symbol)->aclass
|
||||||
#define SYMBOL_IS_ARGUMENT(symbol) (symbol)->is_argument
|
#define SYMBOL_IS_ARGUMENT(symbol) (symbol)->is_argument
|
||||||
#define SYMBOL_INLINED(symbol) (symbol)->is_inlined
|
#define SYMBOL_INLINED(symbol) (symbol)->is_inlined
|
||||||
|
#define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \
|
||||||
|
(symbol)->is_cplus_template_function
|
||||||
#define SYMBOL_TYPE(symbol) (symbol)->type
|
#define SYMBOL_TYPE(symbol) (symbol)->type
|
||||||
#define SYMBOL_LINE(symbol) (symbol)->line
|
#define SYMBOL_LINE(symbol) (symbol)->line
|
||||||
#define SYMBOL_SYMTAB(symbol) (symbol)->symtab
|
#define SYMBOL_SYMTAB(symbol) (symbol)->symtab
|
||||||
#define SYMBOL_COMPUTED_OPS(symbol) (symbol)->ops.ops_computed
|
#define SYMBOL_COMPUTED_OPS(symbol) (symbol)->ops.ops_computed
|
||||||
#define SYMBOL_REGISTER_OPS(symbol) (symbol)->ops.ops_register
|
#define SYMBOL_REGISTER_OPS(symbol) (symbol)->ops.ops_register
|
||||||
#define SYMBOL_LOCATION_BATON(symbol) (symbol)->aux_value
|
#define SYMBOL_LOCATION_BATON(symbol) (symbol)->aux_value
|
||||||
|
|
||||||
|
/* An instance of this type is used to represent a C++ template
|
||||||
|
function. It includes a "struct symbol" as a kind of base class;
|
||||||
|
users downcast to "struct template_symbol *" when needed. A symbol
|
||||||
|
is really of this type iff SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION is
|
||||||
|
true. */
|
||||||
|
|
||||||
|
struct template_symbol
|
||||||
|
{
|
||||||
|
/* The base class. */
|
||||||
|
struct symbol base;
|
||||||
|
|
||||||
|
/* The number of template arguments. */
|
||||||
|
int n_template_arguments;
|
||||||
|
|
||||||
|
/* The template arguments. This is an array with
|
||||||
|
N_TEMPLATE_ARGUMENTS elements. */
|
||||||
|
struct symbol **template_arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Each item represents a line-->pc (or the reverse) mapping. This is
|
/* Each item represents a line-->pc (or the reverse) mapping. This is
|
||||||
somewhat more wasteful of space than one might wish, but since only
|
somewhat more wasteful of space than one might wish, but since only
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2010-07-28 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
PR c++/9946:
|
||||||
|
* gdb.cp/temargs.exp: New file.
|
||||||
|
* gdb.cp/temargs.cc: New file.
|
||||||
|
|
||||||
2010-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2010-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* gdb.base/help.exp (help disassemble): Update the content.
|
* gdb.base/help.exp (help disassemble): Update the content.
|
||||||
|
|
71
gdb/testsuite/gdb.cp/temargs.cc
Normal file
71
gdb/testsuite/gdb.cp/temargs.cc
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* Template argument tests.
|
||||||
|
|
||||||
|
Copyright 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Please email any bugs, comments, and/or additions to this file to:
|
||||||
|
bug-gdb@gnu.org */
|
||||||
|
|
||||||
|
int a_global;
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int f;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, int I, int *P, int S::*MP>
|
||||||
|
struct Base
|
||||||
|
{
|
||||||
|
template<typename Z>
|
||||||
|
struct Inner
|
||||||
|
{
|
||||||
|
void inner_m ()
|
||||||
|
{
|
||||||
|
// Breakpoint 2.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void base_m ()
|
||||||
|
{
|
||||||
|
// Breakpoint 1.
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Q>
|
||||||
|
void templ_m ()
|
||||||
|
{
|
||||||
|
// Breakpoint 4.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, int I, int *P, int S::*MP>
|
||||||
|
void func ()
|
||||||
|
{
|
||||||
|
// Breakpoint 3.
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
Base<double, 23, &a_global, &S::f> base;
|
||||||
|
// Note that instantiating with P==0 does not work with g++.
|
||||||
|
// That would be worth testing, once g++ is fixed.
|
||||||
|
Base<long, 47, &a_global, &S::f>::Inner<float> inner;
|
||||||
|
|
||||||
|
base.base_m ();
|
||||||
|
inner.inner_m ();
|
||||||
|
func<unsigned char, 91, &a_global, &S::f> ();
|
||||||
|
base.templ_m<short> ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
102
gdb/testsuite/gdb.cp/temargs.exp
Normal file
102
gdb/testsuite/gdb.cp/temargs.exp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# temargs.exp - Template argument tests
|
||||||
|
#
|
||||||
|
# Copyright 2010 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# This file is part of the gdb testsuite.
|
||||||
|
|
||||||
|
if {$tracelevel} {
|
||||||
|
strace $tracelevel
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[skip_cplus_tests]} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
set testfile "temargs"
|
||||||
|
set srcfile "${testfile}.cc"
|
||||||
|
|
||||||
|
if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {![runto_main]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set line [gdb_get_line_number "Breakpoint 1" $srcfile]
|
||||||
|
gdb_test "break $srcfile:$line" "Breakpoint 2.*" \
|
||||||
|
"set first breakpoint for temargs"
|
||||||
|
set line [gdb_get_line_number "Breakpoint 2" $srcfile]
|
||||||
|
gdb_test "break $srcfile:$line" "Breakpoint 3.*" \
|
||||||
|
"set second breakpoint for temargs"
|
||||||
|
set line [gdb_get_line_number "Breakpoint 3" $srcfile]
|
||||||
|
gdb_test "break $srcfile:$line" "Breakpoint 4.*" \
|
||||||
|
"set third breakpoint for temargs"
|
||||||
|
set line [gdb_get_line_number "Breakpoint 4" $srcfile]
|
||||||
|
gdb_test "break $srcfile:$line" "Breakpoint 5.*" \
|
||||||
|
"set fourth breakpoint for temargs"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tests in Base::base_m.
|
||||||
|
#
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "continue to first breakpoint for temargs"
|
||||||
|
|
||||||
|
gdb_test "ptype T" "double" "test type of T in base_m"
|
||||||
|
gdb_test "print I" " = 23" "test value of I in base_m"
|
||||||
|
gdb_test "print P == &a_global" " = true" "test value of P in base_m"
|
||||||
|
setup_kfail "gcc/41736" *-*-*
|
||||||
|
gdb_test "print MP" "&S::f" "test value of MP in base_m"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tests in Inner::inner_m.
|
||||||
|
#
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "continue to second breakpoint for temargs"
|
||||||
|
|
||||||
|
setup_kfail "gcc/45024" *-*-*
|
||||||
|
gdb_test "ptype T" "long" "test type of T in inner_m"
|
||||||
|
setup_kfail "gcc/45024" *-*-*
|
||||||
|
gdb_test "print I" " = 47" "test value of I in inner_m"
|
||||||
|
gdb_test "print P == &a_global" " = true" "test value of P in inner_m"
|
||||||
|
setup_kfail "gcc/41736" *-*-*
|
||||||
|
gdb_test "print MP" "&S::f" "test value of MP in inner_m"
|
||||||
|
gdb_test "whatis Z" "float" "test type of Z in inner_m"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tests in func.
|
||||||
|
#
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "continue to third breakpoint for temargs"
|
||||||
|
|
||||||
|
gdb_test "ptype T" "unsigned char" "test type of T in func"
|
||||||
|
gdb_test "print I" " = 91" "test value of I in func"
|
||||||
|
gdb_test "print P == &a_global" " = true" "test value of P in func"
|
||||||
|
setup_kfail "gcc/41736" *-*-*
|
||||||
|
gdb_test "print MP" "&S::f" "test value of MP in func"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tests in Base::templ_m.
|
||||||
|
#
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "continue to fourth breakpoint for temargs"
|
||||||
|
|
||||||
|
gdb_test "ptype T" "double" "test type of T in templ_m"
|
||||||
|
gdb_test "print I" " = 23" "test value of I in templ_m"
|
||||||
|
gdb_test "print P == &a_global" " = true" "test value of P in templ_m"
|
||||||
|
setup_kfail "gcc/41736" *-*-*
|
||||||
|
gdb_test "print MP" "&S::f" "test value of MP in templ_m"
|
||||||
|
gdb_test "whatis Q" "short" "test type of Q in templ_m"
|
Loading…
Reference in a new issue