/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986, 1989-2000, 2003-2004, 2006-2012 Free Software
- Foundation, Inc.
+ Copyright (C) 1986-2013 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_assert.h"
#include "macroscope.h"
#include "objc-lang.h"
+#include "typeprint.h"
+#include "cp-abi.h"
#define parse_type builtin_type (parse_gdbarch)
block : block COLONCOLON name
{ struct symbol *tem
= lookup_symbol (copy_name ($3), $1,
- VAR_DOMAIN, (int *) NULL);
+ VAR_DOMAIN, NULL);
if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
error (_("No function \"%s\" in specified context."),
copy_name ($3));
variable: block COLONCOLON name
{ struct symbol *sym;
sym = lookup_symbol (copy_name ($3), $1,
- VAR_DOMAIN, (int *) NULL);
+ VAR_DOMAIN, NULL);
if (sym == 0)
error (_("No symbol \"%s\" in specified context."),
copy_name ($3));
sym =
lookup_symbol (name, (const struct block *) NULL,
- VAR_DOMAIN, (int *) NULL);
+ VAR_DOMAIN, NULL);
if (sym)
{
write_exp_elt_opcode (OP_VAR_VALUE);
| STRUCT name
{ $$ = lookup_struct (copy_name ($2),
expression_context_block); }
+ | STRUCT COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_STRUCT, "", 0);
+ $$ = NULL;
+ }
+ | STRUCT name COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr,
+ $2.length);
+ $$ = NULL;
+ }
| CLASS name
{ $$ = lookup_struct (copy_name ($2),
expression_context_block); }
+ | CLASS COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_CLASS, "", 0);
+ $$ = NULL;
+ }
+ | CLASS name COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_CLASS, $2.ptr,
+ $2.length);
+ $$ = NULL;
+ }
| UNION name
{ $$ = lookup_union (copy_name ($2),
expression_context_block); }
+ | UNION COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_UNION, "", 0);
+ $$ = NULL;
+ }
+ | UNION name COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_UNION, $2.ptr,
+ $2.length);
+ $$ = NULL;
+ }
| ENUM name
{ $$ = lookup_enum (copy_name ($2),
expression_context_block); }
+ | ENUM COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_ENUM, "", 0);
+ $$ = NULL;
+ }
+ | ENUM name COMPLETE
+ {
+ mark_completion_tag (TYPE_CODE_ENUM, $2.ptr,
+ $2.length);
+ $$ = NULL;
+ }
| UNSIGNED typename
{ $$ = lookup_unsigned_typename (parse_language,
parse_gdbarch,
long length;
struct ui_file *buf = mem_fileopen ();
- c_print_type ($2, NULL, buf, -1, 0);
+ c_print_type ($2, NULL, buf, -1, 0,
+ &type_print_raw_options);
name = ui_file_xstrdup (buf, &length);
ui_file_delete (buf);
$$ = operator_stoken (name);
*/
| operator
{
+ struct field_of_this_result is_a_field_of_this;
+
$$.stoken = $1;
$$.sym = lookup_symbol ($1.ptr,
expression_context_block,
VAR_DOMAIN,
- &$$.is_a_field_of_this);
+ &is_a_field_of_this);
+ $$.is_a_field_of_this
+ = is_a_field_of_this.type != NULL;
}
| UNKNOWN_CPP_NAME
;
lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
- if (in_parse_field && tokentab2[i].token == ARROW)
+ if (parse_completion && tokentab2[i].token == ARROW)
last_was_structop = 1;
return tokentab2[i].token;
}
/* Might be a floating point number. */
if (lexptr[1] < '0' || lexptr[1] > '9')
{
- if (in_parse_field)
+ if (parse_completion)
last_was_structop = 1;
goto symbol; /* Nope, must be a symbol. */
}
if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
{
- int is_a_field_of_this = 0;
+ struct field_of_this_result is_a_field_of_this;
if (lookup_symbol (copy, expression_context_block,
VAR_DOMAIN,
if (*tokstart == '$')
return VARIABLE;
- if (in_parse_field && *lexptr == '\0')
+ if (parse_completion && *lexptr == '\0')
saw_name_at_eof = 1;
return NAME;
}
in which lookups start; this can be NULL to mean the global
scope. */
static int
-classify_name (struct block *block)
+classify_name (const struct block *block)
{
struct symbol *sym;
char *copy;
- int is_a_field_of_this = 0;
+ struct field_of_this_result is_a_field_of_this;
copy = copy_name (yylval.sval);
+ /* Initialize this in case we *don't* use it in this call; that way
+ we can refer to it unconditionally below. */
+ memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this));
+
sym = lookup_symbol (copy, block, VAR_DOMAIN,
parse_language->la_name_of_this
- ? &is_a_field_of_this : (int *) NULL);
+ ? &is_a_field_of_this : NULL);
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
yylval.ssym.sym = sym;
- yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
return BLOCKNAME;
}
else if (!sym)
yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
return FILENAME;
}
+
+ /* If we found a field of 'this', we might have erroneously
+ found a constructor where we wanted a type name. Handle this
+ case by noticing that we found a constructor and then look up
+ the type tag instead. */
+ if (is_a_field_of_this.type != NULL
+ && is_a_field_of_this.fn_field != NULL
+ && TYPE_FN_FIELD_CONSTRUCTOR (is_a_field_of_this.fn_field->fn_fields,
+ 0))
+ {
+ struct field_of_this_result inner_is_a_field_of_this;
+
+ sym = lookup_symbol (copy, block, STRUCT_DOMAIN,
+ &inner_is_a_field_of_this);
+ if (sym != NULL)
+ {
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+ return TYPENAME;
+ }
+ }
}
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
if (hextype == INT)
{
yylval.ssym.sym = sym;
- yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
return NAME_OR_INT;
}
}
/* Any other kind of symbol */
yylval.ssym.sym = sym;
- yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+ yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
if (sym == NULL
&& parse_language->la_language == language_cplus
- && !is_a_field_of_this
+ && is_a_field_of_this.type == NULL
&& !lookup_minimal_symbol (copy, NULL, NULL))
return UNKNOWN_CPP_NAME;
in `yylval' is the first component of a name, false otherwise. */
static int
-classify_inner_name (struct block *block, int first_name)
+classify_inner_name (const struct block *block, int first_name)
{
struct type *type, *new_type;
char *copy;