diff options
author | Jim Kingdon <jkingdon@engr.sgi.com> | 1991-04-26 23:01:36 +0000 |
---|---|---|
committer | Jim Kingdon <jkingdon@engr.sgi.com> | 1991-04-26 23:01:36 +0000 |
commit | d96b54ea7a436af3f8b18c2bba149f01314b7a5d (patch) | |
tree | 98b840900646d9507a31c7e668ccce9c499b9a67 /gdb | |
parent | 7cc4387940ab7594e38782cc41a78d9c79496c09 (diff) | |
download | gdb-d96b54ea7a436af3f8b18c2bba149f01314b7a5d.zip gdb-d96b54ea7a436af3f8b18c2bba149f01314b7a5d.tar.gz gdb-d96b54ea7a436af3f8b18c2bba149f01314b7a5d.tar.bz2 |
* symtab.c, symtab.h: Have a builtin_type_{,unsigned_}long_long
regardless of LONG_LONG.
symtab.c, symtab.h (allocate_stub_method): New function.
* symtab.c (decode_line_1): Deal with operators specified as
"operator" <optional whitespace> <symbols for operator>.
(operator_chars): Help do it.
* symtab.c (lookup_struct_elt_type): Call check_stub_type.
Take additional argument noerr.
Don't dump core if TYPE_FIELD_NAME is NULL.
Check the baseclasses recursively.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/symtab.c | 193 |
1 files changed, 174 insertions, 19 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c index 98b6ca1..15e2ad6 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -60,16 +60,12 @@ struct type *builtin_type_char; struct type *builtin_type_short; struct type *builtin_type_int; struct type *builtin_type_long; -#ifdef LONG_LONG struct type *builtin_type_long_long; -#endif struct type *builtin_type_unsigned_char; struct type *builtin_type_unsigned_short; struct type *builtin_type_unsigned_int; struct type *builtin_type_unsigned_long; -#ifdef LONG_LONG struct type *builtin_type_unsigned_long_long; -#endif struct type *builtin_type_float; struct type *builtin_type_double; struct type *builtin_type_error; @@ -385,12 +381,14 @@ lookup_enum (name, block) } /* Given a type TYPE, lookup the type of the component of type named - NAME. */ + NAME. + If NOERR is nonzero, return zero if NAME is not suitably defined. */ struct type * -lookup_struct_elt_type (type, name) +lookup_struct_elt_type (type, name, noerr) struct type *type; char *name; + int noerr; { int i; @@ -404,10 +402,27 @@ lookup_struct_elt_type (type, name) error (" is not a structure or union type."); } + check_stub_type (type); + for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) - if (!strcmp (TYPE_FIELD_NAME (type, i), name)) - return TYPE_FIELD_TYPE (type, i); + { + char *t_field_name = TYPE_FIELD_NAME (type, i); + if (t_field_name && !strcmp (t_field_name, name)) + return TYPE_FIELD_TYPE (type, i); + } + /* OK, it's not in this class. Recursively check the baseclasses. */ + for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) + { + struct type *t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), + name, 0); + if (t != NULL) + return t; + } + + if (noerr) + return NULL; + target_terminal_ours (); fflush (stdout); fprintf (stderr, "Type "); @@ -538,6 +553,29 @@ lookup_member_type (type, domain) return mtype; } +/* Allocate a stub method whose return type is + TYPE. We will fill in arguments later. This always + returns a fresh type. If we unify this type with + an existing type later, the storage allocated + here can be freed. */ +struct type * +allocate_stub_method (type) + struct type *type; +{ + struct type *mtype = (struct type *)xmalloc (sizeof (struct type)); + bzero (mtype, sizeof (struct type)); + TYPE_MAIN_VARIANT (mtype) = mtype; + TYPE_TARGET_TYPE (mtype) = type; + TYPE_FLAGS (mtype) = TYPE_FLAG_STUB; + TYPE_CODE (mtype) = TYPE_CODE_METHOD; + TYPE_LENGTH (mtype) = 1; + return mtype; +} + +/* Lookup a method type returning type TYPE, belonging + to class DOMAIN, and taking a list of arguments ARGS. + If one is not found, allocate a new one. */ + struct type * lookup_method_type (type, domain, args) struct type *type, *domain, **args; @@ -1613,6 +1651,81 @@ find_pc_line_pc_range (pc, startptr, endptr) return sal.symtab != 0; } +/* If P is of the form "operator[ \t]+..." where `...' is + some legitimate operator text, return a pointer to the + beginning of the substring of the operator text. + Otherwise, return "". */ +static char * +operator_chars (p, end) + char *p; + char **end; +{ + *end = ""; + if (strncmp (p, "operator", 8)) + return *end; + p += 8; + + /* Don't get faked out by `operator' being part of a longer + identifier. */ + if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') + || *p == '_' || *p == '$' || *p == '\0') + return *end; + + /* Allow some whitespace between `operator' and the operator symbol. */ + while (*p == ' ' || *p == '\t') + p++; + + switch (*p) + { + case '!': + case '=': + case '*': + case '/': + case '%': + case '^': + if (p[1] == '=') + *end = p+2; + else + *end = p+1; + return p; + case '<': + case '>': + case '+': + case '-': + case '&': + case '|': + if (p[1] == '=' || p[1] == p[0]) + *end = p+2; + else + *end = p+1; + return p; + case '~': + case ',': + *end = p+1; + return p; + case '(': + if (p[1] != ')') + error ("`operator ()' must be specified without whitespace in `()'"); + *end = p+2; + return p; + case '?': + if (p[1] != ':') + error ("`operator ?:' must be specified without whitespace in `?:'"); + *end = p+2; + return p; + case '[': + if (p[1] != ']') + error ("`operator []' must be specified without whitespace in `[]'"); + *end = p+2; + return p; + default: + error ("`operator %s' not supported", p); + break; + } + *end = ""; + return *end; +} + /* Recursive helper function for decode_line_1. * Look for methods named NAME in type T. * Return number of matches. @@ -1740,6 +1853,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) struct symtabs_and_lines values; struct symtab_and_line val; register char *p, *p1; + char *q, *q1; register struct symtab *s; register struct symbol *sym; @@ -1788,6 +1902,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) } while (p[0] == ' ' || p[0] == '\t') p++; + q = operator_chars (*argptr, &q1); if (p[0] == ':') { @@ -1817,9 +1932,23 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) Find the next token (everything up to end or next whitespace). */ p = *argptr; while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++; - copy = (char *) alloca (p - *argptr + 1); - bcopy (*argptr, copy, p - *argptr); - copy[p - *argptr] = '\0'; + q = operator_chars (*argptr, &q1); + + copy = (char *) alloca (p - *argptr + 1 + (q1 - q)); + if (q1 - q) + { + copy[0] = 'o'; + copy[1] = 'p'; + copy[2] = CPLUS_MARKER; + bcopy (q, copy + 3, q1 - q); + copy[3 + (q1 - q)] = '\0'; + p = q1; + } + else + { + bcopy (*argptr, copy, p - *argptr); + copy[p - *argptr] = '\0'; + } /* no line number may be specified */ while (*p == ' ' || *p == '\t') p++; @@ -1875,7 +2004,19 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) return decode_line_2 (sym_arr, i1, funfirstline); } else - error ("that class does not have any method named %s",copy); + { + char *tmp; + + if (OPNAME_PREFIX_P (copy)) + { + tmp = (char *)alloca (strlen (copy+3) + 9); + strcpy (tmp, "operator "); + strcat (tmp, copy+3); + } + else + tmp = copy; + error ("that class does not have any method named %s", tmp); + } } else /* The quotes are important if copy is empty. */ @@ -1887,9 +2028,21 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) /* Extract the file name. */ p1 = p; while (p != *argptr && p[-1] == ' ') --p; - copy = (char *) alloca (p - *argptr + 1); - bcopy (*argptr, copy, p - *argptr); - copy[p - *argptr] = 0; + copy = (char *) alloca (p - *argptr + 1 + (q1 - q)); + if (q1 - q) + { + copy[0] = 'o'; + copy[1] = 'p'; + copy[2] = CPLUS_MARKER; + bcopy (q, copy + 3, q1-q); + copy[3 + (q1-q)] = 0; + p = q1; + } + else + { + bcopy (*argptr, copy, p - *argptr); + copy[p - *argptr] = 0; + } /* Find that file's data. */ s = lookup_symtab (copy); @@ -2746,12 +2899,14 @@ are listed."); builtin_type_unsigned_short = init_type (TYPE_CODE_INT, sizeof (short), 1, "unsigned short"); builtin_type_unsigned_long = init_type (TYPE_CODE_INT, sizeof (long), 1, "unsigned long"); builtin_type_unsigned_int = init_type (TYPE_CODE_INT, sizeof (int), 1, "unsigned int"); -#ifdef LONG_LONG + builtin_type_long_long = - init_type (TYPE_CODE_INT, sizeof (long long), 0, "long long"); + init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long long"); builtin_type_unsigned_long_long = - init_type (TYPE_CODE_INT, sizeof (long long), 1, "unsigned long long"); -#endif + init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 1, "unsigned long long"); + builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0, "<unknown type>"); } |