+2002-11-22 David Carlton <carlton@math.stanford.edu>
+
+ * linespec.c (examine_compound_token): Rewrite as switch
+ statement, and add FIXME comment.
+ * frame.h: Make arg of block_innermost_frame const.
+ * blockframe.c (block_innermost_frame): Make arg const.
+ * block.h: Make args to block_function, contained_in const.
+ * block.c (block_function): Make arg const.
+ (contained_in): Ditto.
+ * value.h: Make arg of symbol_read_needs_frame const.
+ * findvar.c (symbol_read_needs_frame): Make arg const.
+ * symtab.h: Make first arg of symbol_demangled_name const.
+ * symtab.c (symbol_demangled_name): Make arg const.
+ * value.h: Make first arg of read_var_value const.
+ * findvar.c (read_var_value): Make first arg const.
+ * Makefile.in (valops.o): Depend on cp_support_h.
+ * valops.c: #include "cp-support.h"
+ * symtab.h: Add FIXME about name of namespace_enum.
+ Add opaque declaration of struct using_direct_node.
+ * symtab.c (lookup_symbol_namespace): Make extern; rename args.
+ * symtab.h: Declare lookup_symbol_namespace.
+ * valops.c (value_struct_elt_for_reference): Make 'name' a const
+ char *.
+ (value_namespace_elt): New function.
+ * expprint.c (print_subexp): Ditto.
+ (dump_subexp): Ditto.
+ * parse.c (length_of_subexp): Ditto.
+ (prefixify_subexp): Ditto.
+ * expression.h: Update comment to reflect the block in OP_SCOPE.
+ * c-exp.y: Set block in OP_SCOPE expression.
+ * jv-exp.y (push_qualified_expression_name): Put a NULL block in
+ OP_SCOPE expression.
+ * objc-exp.y: Ditto.
+ * p-exp.y: Ditto.
+ * eval.c (evaluate_subexp_standard): Handle OP_SCOPE via
+ value_aggregate_elt.
+ * value.h: Add declaration for value_aggregate_elt; delete
+ declaration for value_struct_elt_for_reference.
+ * valops.c (value_aggregate_elt): New function.
+ (value_struct_elt_for_reference): Make static. Don't check type
+ of curtype.
+ * c-exp.y: Accept TYPE_CODE_NAMESPACE in qualified_name.
+ * cp-support.c (cp_check_namespace_symbol): Set TYPE_NAME (type).
+
2002-11-21 David Carlton <carlton@math.stanford.edu>
* cp-support.c (get_namespace_objfile): Set
valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \
$(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \
$(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(gdb_string_h) \
- $(gdb_assert_h) $(dictionary_h) $(block_h)
+ $(gdb_assert_h) $(dictionary_h) $(block_h) $(cp_support_h)
valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \
$(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h)
lexical block, described by a struct block BL. */
struct symbol *
-block_function (struct block *bl)
+block_function (const struct block *bl)
{
while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
bl = BLOCK_SUPERBLOCK (bl);
Return zero otherwise. */
int
-contained_in (struct block *a, struct block *b)
+contained_in (const struct block *a, const struct block *b)
{
if (!a || !b)
return 0;
#define STATIC_BLOCK 1
#define FIRST_LOCAL_BLOCK 2
-extern struct symbol *block_function (struct block *);
+extern struct symbol *block_function (const struct block *);
-extern int contained_in (struct block *, struct block *);
+extern int contained_in (const struct block *, const struct block *);
extern struct using_direct_node *block_using (const struct block *);
or NULL if there is no such frame. If BLOCK is NULL, just return NULL. */
struct frame_info *
-block_innermost_frame (struct block *block)
+block_innermost_frame (const struct block *block)
{
struct frame_info *frame;
register CORE_ADDR start;
{
struct type *type = $1;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
- && TYPE_CODE (type) != TYPE_CODE_UNION)
+ && TYPE_CODE (type) != TYPE_CODE_UNION
+ && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
+ /* If it's a namespace, we need to know the
+ block. */
+ write_exp_elt_block (expression_context_block);
write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE);
}
struct type *type = $1;
struct stoken tmp_token;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
- && TYPE_CODE (type) != TYPE_CODE_UNION)
+ && TYPE_CODE (type) != TYPE_CODE_UNION
+ && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
destructor_name_p (tmp_token.ptr, type);
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
+ write_exp_elt_block (expression_context_block);
write_exp_string (tmp_token);
write_exp_elt_opcode (OP_SCOPE);
}
struct type *type = alloc_type (objfile);
INIT_CPLUS_SPECIFIC (type);
TYPE_TAG_NAME (type) = obsavestring (name, len, &objfile->type_obstack);
+ TYPE_NAME (type) = TYPE_TAG_NAME (type);
TYPE_CODE (type) = TYPE_CODE_NAMESPACE;
TYPE_LENGTH (type) = 0;
switch (op)
{
case OP_SCOPE:
- tem = longest_to_int (exp->elts[pc + 2].longconst);
- (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
- arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
- 0,
- exp->elts[pc + 1].type,
- &exp->elts[pc + 3].string,
- NULL_TYPE);
+ tem = longest_to_int (exp->elts[pc + 3].longconst);
+ (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1);
+ arg1 = value_aggregate_elt (exp->elts[pc + 1].type,
+ exp->elts[pc + 2].block,
+ &exp->elts[pc + 4].string);
if (arg1 == NULL)
- error ("There is no field named %s", &exp->elts[pc + 3].string);
+ error ("There is no field named %s", &exp->elts[pc + 4].string);
return arg1;
case OP_LONG:
{
if (op == OP_SCOPE)
{
- int temm = longest_to_int (exp->elts[pc + 3].longconst);
- (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1);
+ int temm = longest_to_int (exp->elts[pc + 4].longconst);
+ (*pos) += 4 + BYTES_TO_EXP_ELEM (temm + 1);
}
else
evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
assoc = 0;
fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream);
fputs_filtered ("::", stream);
- nargs = longest_to_int (exp->elts[pc + 2].longconst);
- (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1);
- fputs_filtered (&exp->elts[pc + 3].string, stream);
+ nargs = longest_to_int (exp->elts[pc + 3].longconst);
+ (*pos) += 5 + BYTES_TO_EXP_ELEM (nargs + 1);
+ fputs_filtered (&exp->elts[pc + 4].string, stream);
return;
case OP_LONG:
type_print (exp->elts[elt].type, NULL, stream, 0);
fprintf_filtered (stream, ") ");
- len = longest_to_int (exp->elts[elt + 1].longconst);
- elem_name = &exp->elts[elt + 2].string;
+ len = longest_to_int (exp->elts[elt + 2].longconst);
+ elem_name = &exp->elts[elt + 3].string;
fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name);
- elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
+ elt += 5 + BYTES_TO_EXP_ELEM (len + 1);
}
break;
default:
/* Objective C: "@selector" pseudo-operator */
OP_SELECTOR,
- /* OP_SCOPE surrounds a type name and a field name. The type
- name is encoded as one element, but the field name stays as
- a string, which, of course, is variable length. */
+ /* OP_SCOPE surrounds a type name, a block, and a field name. The
+ type name and block are encoded as one element, but the field
+ name stays as a string, which, of course, is variable
+ length. */
OP_SCOPE,
/* Used to represent named structure field values in brace
up caring what frame it is being evaluated relative to? SYM must
be non-NULL. */
int
-symbol_read_needs_frame (struct symbol *sym)
+symbol_read_needs_frame (const struct symbol *sym)
{
switch (SYMBOL_CLASS (sym))
{
If FRAME is NULL, use the selected_frame. */
struct value *
-read_var_value (register struct symbol *var, struct frame_info *frame)
+read_var_value (const struct symbol *var, struct frame_info *frame)
{
register struct value *v;
struct type *type = SYMBOL_TYPE (var);
extern void show_frame_info (struct frame_info *, int, int, int);
-extern struct frame_info *block_innermost_frame (struct block *);
+extern struct frame_info *block_innermost_frame (const struct block *);
extern struct frame_info *find_frame_addr_in_frame_chain (CORE_ADDR);
token.length = dot_index;
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (typ);
+ write_exp_elt_block (NULL);
write_exp_string (token);
write_exp_elt_opcode (OP_SCOPE);
if (dot_index < name.length)
t = check_typedef (SYMBOL_TYPE (class_sym));
- if (TYPE_CODE (t) == TYPE_CODE_STRUCT
- || TYPE_CODE (t) == TYPE_CODE_UNION)
+ switch (TYPE_CODE (t))
{
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
/* Find the next token (everything up to end or next blank). */
current_component = find_next_token (argptr);
t, class_sym);
return 1;
- }
- else
- {
+ case TYPE_CODE_NAMESPACE:
+ return 0;
+ default:
+ /* FIXME: carlton/2002-11-19: Once this all settles down, this
+ case should be an error rather than a return 0; that will
+ allow us to make VALUES the return value rather than an
+ argument. */
return 0;
}
}
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
+ write_exp_block (NULL);
write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE);
}
tmp_token.ptr[tmp_token.length] = 0;
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
+ write_exp_elt_block (NULL);
write_exp_string (tmp_token);
write_exp_elt_opcode (OP_SCOPE);
}
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
+ write_exp_elt_block (NULL);
write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE);
}
/* C++ */
case OP_SCOPE:
oplen = longest_to_int (expr->elts[endpos - 2].longconst);
- oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
+ oplen = 6 + BYTES_TO_EXP_ELEM (oplen + 1);
break;
case OP_LONG:
/* C++ */
case OP_SCOPE:
oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
- oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
+ oplen = 6 + BYTES_TO_EXP_ELEM (oplen + 1);
break;
case OP_LONG:
int scope_len,
struct using_direct_node *using);
-static
-struct symbol *lookup_symbol_namespace (const char *prefix,
- int prefix_len,
- const char *rest,
- struct using_direct_node *using,
- const char *mangled_name,
- namespace_enum namespace,
- struct symtab **symtab);
-
static
struct symbol *lookup_symbol_aux_minsyms (int block_index,
const char *name,
/* Return the demangled name for a symbol based on the language for
that symbol. If no demangled name exists, return NULL. */
char *
-symbol_demangled_name (struct general_symbol_info *gsymbol)
+symbol_demangled_name (const struct general_symbol_info *gsymbol)
{
if (gsymbol->language == language_cplus
|| gsymbol->language == language_java)
mangled_name, namespace, symtab);
}
-/* This tries to look up REST in the namespace given by the initial
- substring of PREFIX of length PREFIX_LEN.
+/* This tries to look up NAME in the namespace given by the initial
+ substring of NAMESPACE of length NAMESPACE_LEN.
For example, assume that we have using directives adding A to the
global namespace, adding A::inner to namespace A, and adding B to
hopes that it or something like it might eventually be useful
outside of lookup_symbol. */
-static struct symbol *
-lookup_symbol_namespace (const char *prefix,
- int prefix_len,
- const char *rest,
+struct symbol *
+lookup_symbol_namespace (const char *namespace,
+ int namespace_len,
+ const char *name,
struct using_direct_node *using,
const char *mangled_name,
- namespace_enum namespace,
+ namespace_enum name_space,
struct symtab **symtab)
{
struct using_direct_node *current;
for (current = using; current; current = current->next)
{
- /* First, see if the prefix matches the start of this using
+ /* First, see if the namespace matches the start of this using
directive. */
- if (prefix_len <= current->current->outer_length
- && strncmp (prefix, current->current->name, prefix_len) == 0)
+ if (namespace_len <= current->current->outer_length
+ && strncmp (namespace, current->current->name, namespace_len) == 0)
{
/* Great, it matches: now does the rest of the using
directive match the rest of the name? */
- const char *rest_of_outer = current->current->name + prefix_len;
+ const char *rest_of_outer = current->current->name + namespace_len;
int rest_of_outer_len
- = current->current->outer_length - prefix_len;
+ = current->current->outer_length - namespace_len;
/* Should we skip some colons? Should be true unless
- PREFIX_LEN is zero (and hence we're in the global
+ NAMESPACE_LEN is zero (and hence we're in the global
namespace) or we've finished all of outer. */
if (rest_of_outer_len != 0 && *rest_of_outer == ':')
{
rest_of_outer += 2;
rest_of_outer_len -= 2;
}
- if (strncmp (rest_of_outer, rest, rest_of_outer_len) == 0)
+ if (strncmp (rest_of_outer, name, rest_of_outer_len) == 0)
{
/* Everything matches! Yippee! So apply the using
directive and recurse. */
- const char *new_rest = rest + rest_of_outer_len;
- if (*new_rest == ':')
- new_rest += 2;
+ const char *new_name = name + rest_of_outer_len;
+ if (*new_name == ':')
+ new_name += 2;
sym = lookup_symbol_namespace (current->current->name,
current->current->inner_length,
- new_rest,
+ new_name,
using,
mangled_name,
- namespace,
+ name_space,
symtab);
if (sym != NULL)
return sym;
that are still applicable; so let's see if we've got a match
using the current name. */
- if (prefix_len == 0)
+ if (namespace_len == 0)
{
- return lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, rest, mangled_name,
- namespace, symtab);
+ return lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, name, mangled_name,
+ name_space, symtab);
}
else
{
char *concatenated_name
- = xmalloc (prefix_len + 2 + strlen (rest) + 1);
- strncpy (concatenated_name, prefix, prefix_len);
- strcpy (concatenated_name + prefix_len, "::");
- strcpy (concatenated_name + prefix_len + 2, rest);
+ = xmalloc (namespace_len + 2 + strlen (name) + 1);
+ strncpy (concatenated_name, namespace, namespace_len);
+ strcpy (concatenated_name + namespace_len, "::");
+ strcpy (concatenated_name + namespace_len + 2, name);
sym = lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, concatenated_name,
- mangled_name, namespace, symtab);
+ mangled_name, name_space, symtab);
xfree (concatenated_name);
return sym;
#define SYMTAB_H 1
/* Opaque declarations. */
+
struct obstack;
struct block;
struct blockvector;
+struct using_direct_node;
/* Don't do this; it means that if some .o's are compiled with GNU C
and some are not (easy to do accidentally the way we configure
that symbol. If no demangled name exists, return NULL. */
#define SYMBOL_DEMANGLED_NAME(symbol) \
(symbol_demangled_name (&(symbol)->ginfo))
-extern char *symbol_demangled_name (struct general_symbol_info *symbol);
+extern char *symbol_demangled_name (const struct general_symbol_info *symbol);
/* Macro that returns the demangled name of the symbol if if possible
and the symbol name if not possible. This is like
/* Different name spaces for symbols. Looking up a symbol specifies a
namespace and ignores symbol definitions in other name spaces. */
+/* FIXME: carlton/2002-11-22: This name me crazy when doing C++
+ namespace stuff. Maybe name_space_enum and XXX_NAME_SPACE? */
+
typedef enum
{
/* UNDEF_NAMESPACE is used when a namespace has not been discovered or
const namespace_enum, int *,
struct symtab **);
+/* Lookup a symbol within a namespace. */
+
+extern struct symbol *lookup_symbol_namespace (const char *namespace,
+ int namespace_len,
+ const char *name,
+ struct using_direct_node *using,
+ const char *mangled_name,
+ namespace_enum name_space,
+ struct symtab **symtab);
+
/* lookup a symbol by name, within a specified block */
extern struct symbol *lookup_block_symbol (const struct block *, const char *,
+2002-11-22 David Carlton <carlton@math.stanford.edu>
+
+ * gdb.c++/namespace.exp: Change a couple of tests to not use
+ single quotes.
+
2002-11-21 David Carlton <carlton@math.stanford.edu>
* carlton_runnamespace: Run using multiple compilers.
gdb_test "up" ".*main.*" "up from marker1"
# Access a data item inside a namespace using colons and
-# single quotes :-(
+# single quotes. :-(
+
+# NOTE: carlton/2002-11-22: the colons are becoming less necessary.
send_gdb "print 'AAA::c'\n"
gdb_expect {
timeout { fail "(timeout) print 'AAA::c'" }
}
+send_gdb "print AAA::c\n"
+gdb_expect {
+ -re "\\$\[0-9\]* = 0 '\\\\(0|000)'\r\n$gdb_prompt $" { pass "print AAA::c" }
+ -re ".*$gdb_prompt $" { fail "print AAA::c" }
+ timeout { fail "(timeout) print AAA::c" }
+}
+
# An object declared using "using".
send_gdb "print ina\n"
# Call a function in a namespace
-send_gdb "print 'AAA::xyzq'('x')\n"
+send_gdb "print AAA::xyzq('x')\n"
gdb_expect {
-re "\\$\[0-9\]* = 97 'a'\r\n$gdb_prompt $" {
- pass "print 'AAA::xyzq'('x')"
+ pass "print AAA::xyzq('x')"
}
- -re ".*$gdb_prompt $" { fail "print 'AAA::xyzq'('x')" }
- timeout { fail "(timeout) print 'AAA::xyzq'('x')" }
+ -re ".*$gdb_prompt $" { fail "print AAA::xyzq('x')" }
+ timeout { fail "(timeout) print AAA::xyzq('x')" }
}
# Break on a function in a namespace
#include <errno.h>
#include "gdb_string.h"
#include "gdb_assert.h"
+#include "cp-support.h"
/* Flag indicating HP compilers were used; needed to correctly handle some
value operations with HP aCC code/runtime. */
static int check_field_in (struct type *, const char *);
+static struct value *value_struct_elt_for_reference (struct type *domain,
+ int offset,
+ struct type *curtype,
+ const char *name,
+ struct type *intype);
+
+static struct value *value_namespace_elt (const struct type *curtype,
+ const struct block *block,
+ const char *name);
+
static CORE_ADDR allocate_space_in_inferior (int);
static struct value *cast_into_complex (struct type *, struct value *);
}
struct value *
-value_of_variable (struct symbol *var, struct block *b)
+value_of_variable (const struct symbol *var, const struct block *b)
{
struct value *val;
struct frame_info *frame = NULL;
return check_field_in (t, name);
}
+/* C++: Given an aggregate type CURTYPE, and a member name NAME,
+ return the appropriate member. BLOCK is the current block; it is
+ used if TYPE is a namespace. This function is used to resolve user
+ expressions of the form "DOMAIN::NAME". For more details on what
+ happens, see the comment before value_struct_elt_for_reference. */
+
+struct value *
+value_aggregate_elt (struct type *curtype,
+ const struct block *block,
+ const char *name)
+{
+ switch (TYPE_CODE (curtype))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL);
+ case TYPE_CODE_NAMESPACE:
+ return value_namespace_elt (curtype, block, name);
+ default:
+ error ("Internal error: non-aggregate type to value_aggregate_elt");
+ }
+}
+
/* C++: Given an aggregate type CURTYPE, and a member name NAME,
return the address of this member as a "pointer to member"
type. If INTYPE is non-null, then it will be the type
"pointers to member functions". This function is used
to resolve user expressions of the form "DOMAIN::NAME". */
-struct value *
+static struct value *
value_struct_elt_for_reference (struct type *domain, int offset,
- struct type *curtype, char *name,
+ struct type *curtype, const char *name,
struct type *intype)
{
register struct type *t = curtype;
register int i;
struct value *v;
- if (TYPE_CODE (t) != TYPE_CODE_STRUCT
- && TYPE_CODE (t) != TYPE_CODE_UNION)
- error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
-
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
{
char *t_field_name = TYPE_FIELD_NAME (t, i);
return 0;
}
+/* C++: Return the member NAME of the namespace given by the type
+ CURTYPE. Look this up within BLOCK: in particular, apply the using
+ directives from within BLOCK. */
+
+static struct value *
+value_namespace_elt (const struct type *curtype,
+ const struct block *block,
+ const char *name)
+{
+ const char *namespace_name = TYPE_TAG_NAME (curtype);
+ struct using_direct_node *usings = block_all_usings (block);
+ const struct symbol *sym;
+
+ sym = lookup_symbol_namespace (namespace_name, strlen (namespace_name),
+ name, usings, NULL, VAR_NAMESPACE, NULL);
+
+ cp_free_usings (usings);
+
+ return value_of_variable (sym, block);
+}
/* Given a pointer value V, find the real (RTTI) type
of the object it points to.
extern struct value *value_from_register (struct type *type, int regnum,
struct frame_info *frame);
-extern struct value *value_of_variable (struct symbol *var, struct block *b);
+extern struct value *value_of_variable (const struct symbol *var,
+ const struct block *b);
extern struct value *value_of_register (int regnum,
struct frame_info *frame);
-extern int symbol_read_needs_frame (struct symbol *);
+extern int symbol_read_needs_frame (const struct symbol *);
-extern struct value *read_var_value (struct symbol *var,
+extern struct value *read_var_value (const struct symbol *var,
struct frame_info *frame);
extern struct value *locate_var_value (struct symbol *var,
char *name, int *static_memfuncp,
char *err);
-extern struct value *value_struct_elt_for_reference (struct type *domain,
- int offset,
- struct type *curtype,
- char *name,
- struct type *intype);
+extern struct value *value_aggregate_elt (struct type *curtype,
+ const struct block *block,
+ const char *name);
extern struct value *value_static_field (struct type *type, int fieldno);