summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/spew.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/spew.c')
-rw-r--r--contrib/gcc/cp/spew.c530
1 files changed, 260 insertions, 270 deletions
diff --git a/contrib/gcc/cp/spew.c b/contrib/gcc/cp/spew.c
index 278a99a..5bd3fdf 100644
--- a/contrib/gcc/cp/spew.c
+++ b/contrib/gcc/cp/spew.c
@@ -29,7 +29,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h"
#include "cp-tree.h"
#include "cpplib.h"
-#include "c-lex.h"
+#include "c-pragma.h"
#include "lex.h"
#include "parse.h"
#include "flags.h"
@@ -50,12 +50,12 @@ Boston, MA 02111-1307, USA. */
backtracking. */
/* fifo of tokens recognized and available to parser. */
-struct token
+struct token GTY(())
{
/* The values for YYCHAR will fit in a short. */
short yychar;
unsigned int lineno;
- YYSTYPE yylval;
+ YYSTYPE GTY ((desc ("%1.yychar"))) yylval;
};
/* Since inline methods can refer to text which has not yet been seen,
@@ -68,64 +68,82 @@ struct token
This function's FUNCTION_DECL will have a bit set in its common so
that we know to watch out for it. */
-struct unparsed_text
+#define TOKEN_CHUNK_SIZE 20
+struct token_chunk GTY(())
+{
+ struct token_chunk *next;
+ struct token toks[TOKEN_CHUNK_SIZE];
+};
+
+struct unparsed_text GTY(())
{
struct unparsed_text *next; /* process this one next */
tree decl; /* associated declaration */
- const char *filename; /* name of file we were processing */
- int lineno; /* line number we got the text from */
+ location_t locus; /* location we got the text from */
int interface; /* remembering interface_unknown and interface_only */
- struct token *pos; /* current position, when rescanning */
- struct token *limit; /* end of saved text */
+ struct token_chunk * tokens; /* Start of the token list. */
+
+ struct token_chunk *last_chunk; /* End of the token list. */
+ short last_pos; /* Number of tokens used in the last chunk of
+ TOKENS. */
+
+ short cur_pos; /* Current token in 'cur_chunk', when rescanning. */
+ struct token_chunk *cur_chunk; /* Current chunk, when rescanning. */
};
/* Stack of state saved off when we return to an inline method or
default argument that has been stored for later parsing. */
-struct feed
+struct feed GTY(())
{
struct unparsed_text *input;
- const char *filename;
- int lineno;
+ location_t locus;
int yychar;
- YYSTYPE yylval;
+ YYSTYPE GTY ((desc ("%1.yychar"))) yylval;
int first_token;
- struct obstack token_obstack;
+ struct obstack GTY ((skip (""))) token_obstack;
struct feed *next;
-};
+};
-static struct obstack feed_obstack;
-static struct feed *feed;
+static GTY(()) struct feed *feed;
static SPEW_INLINE void do_aggr PARAMS ((void));
static SPEW_INLINE int identifier_type PARAMS ((tree));
static void scan_tokens PARAMS ((int));
static void feed_defarg PARAMS ((tree));
static void finish_defarg PARAMS ((void));
+static void yylexstring PARAMS ((struct token *));
static int read_token PARAMS ((struct token *));
static SPEW_INLINE int num_tokens PARAMS ((void));
static SPEW_INLINE struct token *nth_token PARAMS ((int));
-static SPEW_INLINE int add_token PARAMS ((struct token *));
+static SPEW_INLINE int next_token PARAMS ((struct token *));
static SPEW_INLINE int shift_token PARAMS ((void));
static SPEW_INLINE void push_token PARAMS ((struct token *));
static SPEW_INLINE void consume_token PARAMS ((void));
static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *));
static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *));
-static SPEW_INLINE void snarf_block PARAMS ((const char *, int));
+static SPEW_INLINE struct token * space_for_token
+ PARAMS ((struct unparsed_text *t));
+static SPEW_INLINE struct token * remove_last_token
+ PARAMS ((struct unparsed_text *t));
+static struct unparsed_text * alloc_unparsed_text
+ PARAMS ((const location_t *, tree decl, int interface));
+
+static void snarf_block PARAMS ((struct unparsed_text *t));
static tree snarf_defarg PARAMS ((void));
-static void snarf_parenthesized_expression PARAMS ((const char *, int));
+static void snarf_parenthesized_expression (struct unparsed_text *);
static int frob_id PARAMS ((int, int, tree *));
/* The list of inline functions being held off until we reach the end of
the current class declaration. */
-static struct unparsed_text *pending_inlines;
-static struct unparsed_text *pending_inlines_tail;
+static GTY(()) struct unparsed_text *pending_inlines;
+static GTY(()) struct unparsed_text *pending_inlines_tail;
/* The list of previously-deferred inline functions currently being parsed.
This exists solely to be a GC root. */
-static struct unparsed_text *processing_these_inlines;
+static GTY(()) struct unparsed_text *processing_these_inlines;
static void begin_parsing_inclass_inline PARAMS ((struct unparsed_text *));
@@ -152,52 +170,33 @@ extern int yychar; /* the lookahead symbol */
extern YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
/* The token fifo lives in this obstack. */
-struct obstack token_obstack;
-int first_token;
-
-/* Sometimes we need to save tokens for later parsing. If so, they are
- stored on this obstack. */
-struct obstack inline_text_obstack;
-char *inline_text_firstobj;
+static struct obstack token_obstack;
+static int first_token;
/* When we see a default argument in a method declaration, we snarf it as
text using snarf_defarg. When we get up to namespace scope, we then go
through and parse all of them using do_pending_defargs. Since yacc
parsers are not reentrant, we retain defargs state in these two
variables so that subsequent calls to do_pending_defargs can resume
- where the previous call left off. DEFARG_FNS is a tree_list where
+ where the previous call left off. DEFARG_FNS is a tree_list where
the TREE_TYPE is the current_class_type, TREE_VALUE is the FUNCTION_DECL,
and TREE_PURPOSE is the list unprocessed dependent functions. */
-static tree defarg_fns; /* list of functions with unprocessed defargs */
-static tree defarg_parm; /* current default parameter */
-static tree defarg_depfns; /* list of unprocessed fns met during current fn. */
-static tree defarg_fnsdone; /* list of fns with circular defargs */
+/* list of functions with unprocessed defargs */
+static GTY(()) tree defarg_fns;
+/* current default parameter */
+static GTY(()) tree defarg_parm;
+/* list of unprocessed fns met during current fn. */
+static GTY(()) tree defarg_depfns;
+/* list of fns with circular defargs */
+static GTY(()) tree defarg_fnsdone;
/* Initialize obstacks. Called once, from cxx_init. */
void
init_spew ()
{
- gcc_obstack_init (&inline_text_obstack);
- inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
gcc_obstack_init (&token_obstack);
- gcc_obstack_init (&feed_obstack);
- ggc_add_tree_root (&defarg_fns, 1);
- ggc_add_tree_root (&defarg_parm, 1);
- ggc_add_tree_root (&defarg_depfns, 1);
- ggc_add_tree_root (&defarg_fnsdone, 1);
-
- ggc_add_root (&pending_inlines, 1, sizeof (struct unparsed_text *),
- mark_pending_inlines);
- ggc_add_root (&processing_these_inlines, 1, sizeof (struct unparsed_text *),
- mark_pending_inlines);
-}
-
-void
-clear_inline_text_obstack ()
-{
- obstack_free (&inline_text_obstack, inline_text_firstobj);
}
/* Subroutine of read_token. */
@@ -209,23 +208,8 @@ read_process_identifier (pyylval)
if (C_IS_RESERVED_WORD (id))
{
- /* Possibly replace the IDENTIFIER_NODE with a magic cookie.
- Can't put yylval.code numbers in ridpointers[]. Bleah. */
-
- switch (C_RID_CODE (id))
- {
- case RID_BITAND: pyylval->code = BIT_AND_EXPR; return '&';
- case RID_AND_EQ: pyylval->code = BIT_AND_EXPR; return ASSIGN;
- case RID_BITOR: pyylval->code = BIT_IOR_EXPR; return '|';
- case RID_OR_EQ: pyylval->code = BIT_IOR_EXPR; return ASSIGN;
- case RID_XOR: pyylval->code = BIT_XOR_EXPR; return '^';
- case RID_XOR_EQ: pyylval->code = BIT_XOR_EXPR; return ASSIGN;
- case RID_NOT_EQ: pyylval->code = NE_EXPR; return EQCOMPARE;
-
- default:
- pyylval->ttype = ridpointers[C_RID_CODE (id)];
- return C_RID_YYCODE (id);
- }
+ pyylval->ttype = ridpointers[C_RID_CODE (id)];
+ return C_RID_YYCODE (id);
}
/* Make sure that user does not collide with our internal naming
@@ -244,6 +228,41 @@ read_process_identifier (pyylval)
return IDENTIFIER;
}
+/* Concatenate strings before returning them to the parser. This isn't quite
+ as good as having it done in the lexer, but it's better than nothing. */
+
+static void
+yylexstring (t)
+ struct token *t;
+{
+ enum cpp_ttype next_type;
+ tree next;
+
+ next_type = c_lex (&next);
+ if (next_type == CPP_STRING || next_type == CPP_WSTRING)
+ {
+ varray_type strings;
+
+ VARRAY_TREE_INIT (strings, 32, "strings");
+ VARRAY_PUSH_TREE (strings, t->yylval.ttype);
+
+ do
+ {
+ VARRAY_PUSH_TREE (strings, next);
+ next_type = c_lex (&next);
+ }
+ while (next_type == CPP_STRING || next_type == CPP_WSTRING);
+
+ t->yylval.ttype = combine_strings (strings);
+ last_token_id = t->yylval.ttype;
+ }
+
+ /* We will have always read one token too many. */
+ _cpp_backup_tokens (parse_in, 1);
+
+ t->yychar = STRING;
+}
+
/* Read the next token from the input file. The token is written into
T, and its type number is returned. */
static int
@@ -325,7 +344,7 @@ read_token (t)
case CPP_EOF:
t->yychar = 0;
break;
-
+
case CPP_NAME:
t->yychar = read_process_identifier (&t->yylval);
break;
@@ -338,7 +357,7 @@ read_token (t)
case CPP_STRING:
case CPP_WSTRING:
- t->yychar = STRING;
+ yylexstring (t);
break;
default:
@@ -360,28 +379,28 @@ feed_input (input)
abort ();
#endif
- f = obstack_alloc (&feed_obstack, sizeof (struct feed));
+ f = ggc_alloc (sizeof (struct feed));
- /* The token list starts just after the struct unparsed_text in memory. */
- input->pos = (struct token *) (input + 1);
+ input->cur_chunk = input->tokens;
+ input->cur_pos = 0;
#ifdef SPEW_DEBUG
if (spew_debug)
fprintf (stderr, "\tfeeding %s:%d [%d tokens]\n",
- input->filename, input->lineno, input->limit - input->pos);
+ input->locus.file, input->locus.line, input->limit - input->pos);
#endif
f->input = input;
- f->filename = input_filename;
- f->lineno = lineno;
+ f->locus.file = input_filename;
+ f->locus.line = lineno;
f->yychar = yychar;
f->yylval = yylval;
f->first_token = first_token;
f->token_obstack = token_obstack;
f->next = feed;
- input_filename = input->filename;
- lineno = input->lineno;
+ input_filename = input->locus.file;
+ lineno = input->locus.line;
yychar = YYEMPTY;
yylval.ttype = NULL_TREE;
first_token = 0;
@@ -394,8 +413,8 @@ end_input ()
{
struct feed *f = feed;
- input_filename = f->filename;
- lineno = f->lineno;
+ input_filename = f->locus.file;
+ lineno = f->locus.line;
yychar = f->yychar;
yylval = f->yylval;
first_token = f->first_token;
@@ -403,48 +422,12 @@ end_input ()
token_obstack = f->token_obstack;
feed = f->next;
- obstack_free (&feed_obstack, f);
-
#ifdef SPEW_DEBUG
if (spew_debug)
fprintf (stderr, "\treturning to %s:%d\n", input_filename, lineno);
#endif
}
-/* GC callback to mark memory pointed to by the pending inline queue. */
-void
-mark_pending_inlines (pi)
- PTR pi;
-{
- struct unparsed_text *up = * (struct unparsed_text **)pi;
-
- while (up)
- {
- struct token *t = (struct token *) (up + 1);
- struct token *l = up->limit;
-
- while (t < l)
- {
- /* Some of the possible values for yychar use yylval.code
- instead of yylval.ttype. We only have to worry about
- yychars that could have been returned by read_token. */
- switch (t->yychar)
- {
- case '+': case '-': case '*': case '/':
- case '%': case '&': case '|': case '^':
- case '>': case '<': case LSHIFT: case RSHIFT:
- case ASSIGN: case MIN_MAX: case EQCOMPARE: case ARITHCOMPARE:
- t++;
- continue;
- }
- if (t->yylval.ttype)
- ggc_mark_tree (t->yylval.ttype);
- t++;
- }
- up = up->next;
- }
-}
-
/* Token queue management. */
/* Return the number of tokens available on the fifo. */
@@ -474,16 +457,24 @@ static const struct token Tpad = { EMPTY, 0 UNION_INIT_ZERO };
/* Copy the next token into T and return its value. */
static SPEW_INLINE int
-add_token (t)
+next_token (t)
struct token *t;
{
if (!feed)
return read_token (t);
- if (feed->input->pos < feed->input->limit)
+ if (feed->input->cur_chunk != feed->input->last_chunk
+ || feed->input->cur_pos != feed->input->last_pos)
{
- memcpy (t, feed->input->pos, sizeof (struct token));
- return (feed->input->pos++)->yychar;
+ if (feed->input->cur_pos == TOKEN_CHUNK_SIZE)
+ {
+ feed->input->cur_chunk = feed->input->cur_chunk->next;
+ feed->input->cur_pos = 0;
+ }
+ memcpy (t, feed->input->cur_chunk->toks + feed->input->cur_pos,
+ sizeof (struct token));
+ feed->input->cur_pos++;
+ return t->yychar;
}
return 0;
@@ -495,7 +486,7 @@ shift_token ()
{
size_t point = obstack_object_size (&token_obstack);
obstack_blank (&token_obstack, sizeof (struct token));
- return add_token ((struct token *) (obstack_base (&token_obstack) + point));
+ return next_token ((struct token *) (obstack_base (&token_obstack) + point));
}
/* Consume the next token out of the fifo. */
@@ -572,7 +563,7 @@ scan_tokens (n)
goto pad_tokens;
}
return;
-
+
pad_tokens:
while (num_tokens () <= n)
obstack_grow (&token_obstack, &Tpad, sizeof (struct token));
@@ -598,17 +589,17 @@ identifier_type (decl)
{
if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL)
return PTYPENAME;
- else if (looking_for_template)
+ else if (looking_for_template)
return PFUNCNAME;
}
if (looking_for_template && really_overloaded_fn (decl))
{
/* See through a baselink. */
- if (TREE_CODE (decl) == TREE_LIST)
- decl = TREE_VALUE (decl);
+ if (TREE_CODE (decl) == BASELINK)
+ decl = BASELINK_FUNCTIONS (decl);
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
- if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
+ if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
return PFUNCNAME;
}
if (TREE_CODE (decl) == NAMESPACE_DECL)
@@ -642,7 +633,7 @@ static SPEW_INLINE void
do_aggr ()
{
int yc1, yc2;
-
+
scan_tokens (2);
yc1 = nth_token (1)->yychar;
if (yc1 != tTYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
@@ -672,12 +663,12 @@ do_aggr ()
default:
abort ();
}
-}
+}
void
see_typename ()
{
- /* Only types expected, not even namespaces. */
+ /* Only types expected, not even namespaces. */
looking_for_typename = 2;
if (yychar < 0)
if ((yychar = yylex ()) < 0) yychar = 0;
@@ -732,7 +723,7 @@ yylex ()
{
case EMPTY:
/* This is a lexical no-op. */
-#ifdef SPEW_DEBUG
+#ifdef SPEW_DEBUG
if (spew_debug)
debug_yychar (yychr);
#endif
@@ -751,7 +742,7 @@ yylex ()
case IDENTIFIER:
{
int peek;
-
+
scan_tokens (1);
peek = nth_token (1)->yychar;
yychr = frob_id (yychr, peek, &nth_token (0)->yylval.ttype);
@@ -763,7 +754,7 @@ yylex ()
case PTYPENAME:
case PTYPENAME_DEFN:
/* If we see a SCOPE next, restore the old value.
- Otherwise, we got what we want. */
+ Otherwise, we got what we want. */
looking_for_typename = old_looking_for_typename;
looking_for_template = 0;
break;
@@ -824,13 +815,13 @@ yylex ()
yychar = yychr;
{
struct token *tok = nth_token (0);
-
+
yylval = tok->yylval;
if (tok->lineno)
lineno = tok->lineno;
}
-#ifdef SPEW_DEBUG
+#ifdef SPEW_DEBUG
if (spew_debug)
debug_yychar (yychr);
#endif
@@ -841,7 +832,7 @@ yylex ()
}
/* Unget character CH from the input stream.
- If RESCAN is non-zero, then we want to `see' this
+ If RESCAN is nonzero, then we want to `see' this
character as the next input token. */
void
@@ -854,13 +845,6 @@ yyungetc (ch, rescan)
{
struct token fake;
- /* If we're putting back a brace, undo the change in indent_level
- from the first time we saw it. */
- if (ch == '{')
- indent_level--;
- else if (ch == '}')
- indent_level++;
-
fake.yychar = ch;
fake.yylval.ttype = 0;
fake.lineno = lineno;
@@ -883,7 +867,7 @@ frob_id (yyc, peek, idp)
{
tree trrr;
int old_looking_for_typename = 0;
-
+
if (peek == SCOPE)
{
/* Don't interfere with the setting from an 'aggr' prefix. */
@@ -903,7 +887,7 @@ frob_id (yyc, peek, idp)
case NSNAME:
case PTYPENAME:
/* If this got special lookup, remember it. In these
- cases, we know it can't be a declarator-id. */
+ cases, we know it can't be a declarator-id. */
if (got_scope || got_object)
*idp = trrr;
/* FALLTHROUGH */
@@ -1030,35 +1014,80 @@ process_next_inline (i)
extract_interface_info ();
}
}
+
+/* Create a new token at the end of the token list in T. */
+static SPEW_INLINE struct token *
+space_for_token (t)
+ struct unparsed_text *t;
+{
+ if (t->last_pos != TOKEN_CHUNK_SIZE)
+ return t->last_chunk->toks + (t->last_pos++);
+ t->last_chunk->next = ggc_alloc_cleared (sizeof (*t->last_chunk->next));
+ t->last_chunk = t->last_chunk->next;
+ t->last_chunk->next = NULL;
+
+ t->last_pos = 1;
+ return t->last_chunk->toks;
+}
+
+/* Shrink the token list in T by one token. */
+static SPEW_INLINE struct token *
+remove_last_token (t)
+ struct unparsed_text *t;
+{
+ struct token *result = t->last_chunk->toks + t->last_pos - 1;
+ if (t->last_pos == 0)
+ abort ();
+ t->last_pos--;
+ if (t->last_pos == 0 && t->last_chunk != t->tokens)
+ {
+ struct token_chunk *c;
+ c = t->tokens;
+ while (c->next != t->last_chunk)
+ c = c->next;
+ c->next = NULL;
+ t->last_chunk = c;
+ t->last_pos = ARRAY_SIZE (c->toks);
+ }
+ return result;
+}
+
+/* Allocate an 'unparsed_text' structure, ready to use space_for_token. */
+static struct unparsed_text *
+alloc_unparsed_text (locus, decl, interface)
+ const location_t *locus;
+ tree decl;
+ int interface;
+{
+ struct unparsed_text *r;
+ r = ggc_alloc_cleared (sizeof (*r));
+ r->decl = decl;
+ r->locus = *locus;
+ r->interface = interface;
+ r->tokens = r->last_chunk = ggc_alloc_cleared (sizeof (*r->tokens));
+ return r;
+}
/* Accumulate the tokens that make up a parenthesized expression in T,
having already read the opening parenthesis. */
static void
-snarf_parenthesized_expression (starting_file, starting_line)
- const char *starting_file;
- int starting_line;
+snarf_parenthesized_expression (struct unparsed_text *t)
{
int yyc;
int level = 1;
while (1)
{
- size_t point;
-
- point = obstack_object_size (&inline_text_obstack);
- obstack_blank (&inline_text_obstack, sizeof (struct token));
- yyc = add_token ((struct token *)
- (obstack_base (&inline_text_obstack) + point));
+ yyc = next_token (space_for_token (t));
if (yyc == '(')
++level;
else if (yyc == ')' && --level == 0)
break;
else if (yyc == 0)
{
- error_with_file_and_line (starting_file, starting_line,
- "end of file read inside definition");
+ error ("%Hend of file read inside definition", &t->locus);
break;
}
}
@@ -1066,22 +1095,19 @@ snarf_parenthesized_expression (starting_file, starting_line)
/* Subroutine of snarf_method, deals with actual absorption of the block. */
-static SPEW_INLINE void
-snarf_block (starting_file, starting_line)
- const char *starting_file;
- int starting_line;
+static void
+snarf_block (t)
+ struct unparsed_text *t;
{
int blev = 1;
int look_for_semicolon = 0;
int look_for_lbrac = 0;
int look_for_catch = 0;
int yyc;
- struct token tmp;
- size_t point;
+ struct token *current;
if (yychar == '{')
- /* We incremented indent_level in yylex; undo that. */
- indent_level--;
+ ;
else if (yychar == '=')
look_for_semicolon = 1;
else if (yychar == ':' || yychar == RETURN_KEYWORD || yychar == TRY)
@@ -1095,17 +1121,14 @@ snarf_block (starting_file, starting_line)
yyerror ("parse error in method specification");
/* The current token is the first one to be recorded. */
- tmp.yychar = yychar;
- tmp.yylval = yylval;
- tmp.lineno = lineno;
- obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
+ current = space_for_token (t);
+ current->yychar = yychar;
+ current->yylval = yylval;
+ current->lineno = lineno;
for (;;)
{
- point = obstack_object_size (&inline_text_obstack);
- obstack_blank (&inline_text_obstack, sizeof (struct token));
- yyc = add_token ((struct token *)
- (obstack_base (&inline_text_obstack) + point));
+ yyc = next_token (space_for_token (t));
if (yyc == '{')
{
@@ -1119,39 +1142,40 @@ snarf_block (starting_file, starting_line)
{
if (!look_for_catch)
break;
-
- if (add_token (&tmp) != CATCH)
+
+ if (next_token (space_for_token (t)) != CATCH)
{
- push_token (&tmp);
+ push_token (remove_last_token (t));
break;
}
look_for_lbrac = 1;
- obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
}
}
else if (yyc == ';')
{
if (look_for_lbrac)
{
+ struct token *fake;
+
error ("function body for constructor missing");
/* fake a { } to avoid further errors */
- tmp.yylval.ttype = 0;
- tmp.yychar = '{';
- obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
- tmp.yychar = '}';
- obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
+ fake = space_for_token (t);
+ fake->yylval.ttype = 0;
+ fake->yychar = '{';
+ fake = space_for_token (t);
+ fake->yylval.ttype = 0;
+ fake->yychar = '}';
break;
}
else if (look_for_semicolon && blev == 0)
break;
}
else if (yyc == '(' && blev == 0)
- snarf_parenthesized_expression (starting_file, starting_line);
+ snarf_parenthesized_expression (t);
else if (yyc == 0)
{
- error_with_file_and_line (starting_file, starting_line,
- "end of file read inside definition");
+ error ("%Hend of file read inside definition", &t->locus);
break;
}
}
@@ -1163,60 +1187,43 @@ void
snarf_method (decl)
tree decl;
{
- int starting_lineno = lineno;
- const char *starting_filename = input_filename;
- size_t len;
- int i;
-
struct unparsed_text *meth;
+ location_t starting;
+ starting.file = input_filename;
+ starting.line = lineno;
- /* Leave room for the header, then absorb the block. */
- obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text));
- snarf_block (starting_filename, starting_lineno);
+ meth = alloc_unparsed_text (&starting, decl, (interface_unknown ? 1
+ : (interface_only ? 0 : 2)));
+
+ snarf_block (meth);
/* Add three END_OF_SAVED_INPUT tokens. We used to provide an
infinite stream of END_OF_SAVED_INPUT tokens -- but that can
cause the compiler to get stuck in an infinite loop when
encountering invalid code. We need more than one because the
parser sometimes peeks ahead several tokens. */
- for (i = 0; i < 3; ++i)
- {
- size_t point = obstack_object_size (&inline_text_obstack);
- obstack_blank (&inline_text_obstack, sizeof (struct token));
- memcpy ((struct token *)
- (obstack_base (&inline_text_obstack) + point),
- &Teosi,
- sizeof (struct token));
- }
-
- len = obstack_object_size (&inline_text_obstack);
- meth = (struct unparsed_text *) obstack_finish (&inline_text_obstack);
+ memcpy (space_for_token (meth), &Teosi, sizeof (struct token));
+ memcpy (space_for_token (meth), &Teosi, sizeof (struct token));
+ memcpy (space_for_token (meth), &Teosi, sizeof (struct token));
/* Happens when we get two declarations of the same function in the
same scope. */
if (decl == void_type_node
|| (current_class_type && TYPE_REDEFINED (current_class_type)))
- {
- obstack_free (&inline_text_obstack, (char *)meth);
- return;
- }
-
- meth->decl = decl;
- meth->filename = starting_filename;
- meth->lineno = starting_lineno;
- meth->limit = (struct token *) ((char *)meth + len);
- meth->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
- meth->next = 0;
+ return;
#ifdef SPEW_DEBUG
if (spew_debug)
fprintf (stderr, "\tsaved method of %d tokens from %s:%d\n",
- meth->limit - (struct token *) (meth + 1),
- starting_filename, starting_lineno);
+ meth->limit, starting.file, starting.line);
#endif
DECL_PENDING_INLINE_INFO (decl) = meth;
DECL_PENDING_INLINE_P (decl) = 1;
+ /* We need to know that this was defined in the class, so that
+ friend templates are handled correctly. */
+ DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
+
if (pending_inlines_tail)
pending_inlines_tail->next = meth;
else
@@ -1224,30 +1231,25 @@ snarf_method (decl)
pending_inlines_tail = meth;
}
-/* Consume a no-commas expression - a default argument - and save it
- on the inline_text_obstack. */
+/* Consume a no-commas expression - a default argument - and return
+ a DEFAULT_ARG tree node. */
static tree
snarf_defarg ()
{
- int starting_lineno = lineno;
- const char *starting_filename = input_filename;
int yyc;
int plev = 0;
- size_t point;
- size_t len;
struct unparsed_text *buf;
- int i;
tree arg;
+ location_t starting;
+ starting.file = input_filename;
+ starting.line = lineno;
- obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text));
+ buf = alloc_unparsed_text (&starting, 0, 0);
for (;;)
{
- point = obstack_object_size (&inline_text_obstack);
- obstack_blank (&inline_text_obstack, sizeof (struct token));
- yyc = add_token ((struct token *)
- (obstack_base (&inline_text_obstack) + point));
+ yyc = next_token (space_for_token (buf));
if (plev <= 0 && (yyc == ')' || yyc == ','))
break;
@@ -1257,46 +1259,27 @@ snarf_defarg ()
--plev;
else if (yyc == 0)
{
- error_with_file_and_line (starting_filename, starting_lineno,
- "end of file read inside default argument");
+ error ("%Hend of file read inside default argument", &starting);
goto done;
}
}
/* Unget the last token. */
- push_token ((struct token *) (obstack_base (&inline_text_obstack) + point));
- /* This is the documented way to shrink a growing obstack block. */
- obstack_blank (&inline_text_obstack, - (int) sizeof (struct token));
+ push_token (remove_last_token (buf));
/* Add three END_OF_SAVED_INPUT tokens. We used to provide an
infinite stream of END_OF_SAVED_INPUT tokens -- but that can
cause the compiler to get stuck in an infinite loop when
encountering invalid code. We need more than one because the
parser sometimes peeks ahead several tokens. */
- for (i = 0; i < 3; ++i)
- {
- point = obstack_object_size (&inline_text_obstack);
- obstack_blank (&inline_text_obstack, sizeof (struct token));
- memcpy ((struct token *)
- (obstack_base (&inline_text_obstack) + point),
- &Teosi,
- sizeof (struct token));
- }
+ memcpy (space_for_token (buf), &Teosi, sizeof (struct token));
+ memcpy (space_for_token (buf), &Teosi, sizeof (struct token));
+ memcpy (space_for_token (buf), &Teosi, sizeof (struct token));
done:
- len = obstack_object_size (&inline_text_obstack);
- buf = (struct unparsed_text *) obstack_finish (&inline_text_obstack);
-
- buf->decl = 0;
- buf->filename = starting_filename;
- buf->lineno = starting_lineno;
- buf->limit = (struct token *) ((char *)buf + len);
- buf->next = 0;
-
#ifdef SPEW_DEBUG
if (spew_debug)
fprintf (stderr, "\tsaved defarg of %d tokens from %s:%d\n",
- buf->limit - (struct token *) (buf + 1),
- starting_filename, starting_lineno);
+ buf->limit, starting.file, starting.line);
#endif
arg = make_node (DEFAULT_ARG);
@@ -1328,7 +1311,7 @@ add_defarg_fn (decl)
TREE_VALUE (defarg_fns) = decl;
else
{
- defarg_fns = tree_cons (NULL_TREE, decl, defarg_fns);
+ defarg_fns = tree_cons (NULL_TREE, decl, defarg_fns);
TREE_TYPE (defarg_fns) = current_class_type;
}
}
@@ -1357,7 +1340,7 @@ finish_defarg ()
error ("parse error at end of saved function text");
end_input ();
-}
+}
/* Main function for deferred parsing of default arguments. Called from
the parser. */
@@ -1371,7 +1354,7 @@ do_pending_defargs ()
for (; defarg_fns;)
{
tree current = defarg_fns;
-
+
tree defarg_fn = TREE_VALUE (defarg_fns);
if (defarg_parm == NULL_TREE)
{
@@ -1411,7 +1394,7 @@ do_pending_defargs ()
poplevel (0, 0, 0);
pop_nested_class ();
-
+
defarg_fns = TREE_CHAIN (defarg_fns);
if (defarg_depfns)
{
@@ -1419,8 +1402,8 @@ do_pending_defargs ()
of defarg_fns. We will need to reprocess this function, and
check for circular dependencies. */
tree a, b;
-
- for (a = defarg_depfns, b = TREE_PURPOSE (current); a && b;
+
+ for (a = defarg_depfns, b = TREE_PURPOSE (current); a && b;
a = TREE_CHAIN (a), b = TREE_CHAIN (b))
if (TREE_VALUE (a) != TREE_VALUE (b))
goto different;
@@ -1436,8 +1419,8 @@ do_pending_defargs ()
cp_warning_at ("circular dependency in default args of `%#D'", defarg_fn);
/* No need to say what else is dependent, as they will be
picked up in another pass. */
-
- /* Immediately repeat, but marked so that we break the loop. */
+
+ /* Immediately repeat, but marked so that we break the loop. */
defarg_fns = current;
TREE_PURPOSE (current) = error_mark_node;
}
@@ -1449,7 +1432,7 @@ do_pending_defargs ()
}
/* After parsing all the default arguments, we must clear any that remain,
- which will be part of a circular dependency. */
+ which will be part of a circular dependency. */
void
done_pending_defargs ()
{
@@ -1457,7 +1440,7 @@ done_pending_defargs ()
{
tree fn = TREE_VALUE (defarg_fnsdone);
tree parms;
-
+
if (TREE_CODE (fn) == FUNCTION_DECL)
parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
else
@@ -1504,7 +1487,7 @@ replace_defarg (arg, init)
}
}
-#ifdef SPEW_DEBUG
+#ifdef SPEW_DEBUG
/* debug_yychar takes a yychar (token number) value and prints its name. */
static void
@@ -1542,12 +1525,17 @@ yyerror (msgid)
error ("%s at end of input", string);
else if (last_token == CPP_CHAR || last_token == CPP_WCHAR)
{
- unsigned int val = TREE_INT_CST_LOW (yylval.ttype);
- const char *const ell = (last_token == CPP_CHAR) ? "" : "L";
- if (val <= UCHAR_MAX && ISGRAPH (val))
- error ("%s before %s'%c'", string, ell, val);
+ if (yylval.ttype && TREE_CODE (yylval.ttype) == INTEGER_CST)
+ {
+ unsigned int val = TREE_INT_CST_LOW (yylval.ttype);
+ const char *const ell = (last_token == CPP_CHAR) ? "" : "L";
+ if (val <= UCHAR_MAX && ISGRAPH (val))
+ error ("%s before %s'%c'", string, ell, val);
+ else
+ error ("%s before %s'\\x%x'", string, ell, val);
+ }
else
- error ("%s before %s'\\x%x'", string, ell, val);
+ error ("%s", string);
}
else if (last_token == CPP_STRING
|| last_token == CPP_WSTRING)
@@ -1566,3 +1554,5 @@ yyerror (msgid)
else
error ("%s before `%s' token", string, NAME (last_token));
}
+
+#include "gt-cp-spew.h"
OpenPOWER on IntegriCloud