00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032 #include "system.h"
00033 #include "input.h"
00034 #include "tree.h"
00035 #include "cp-tree.h"
00036 #include "cpplib.h"
00037 #include "c-pragma.h"
00038 #include "lex.h"
00039 #include "parse.h"
00040 #include "flags.h"
00041 #include "obstack.h"
00042 #include "toplev.h"
00043 #include "ggc.h"
00044 #include "intl.h"
00045 #include "timevar.h"
00046
00047 #ifdef SPEW_DEBUG
00048 #define SPEW_INLINE
00049 #else
00050 #define SPEW_INLINE inline
00051 #endif
00052
00053
00054
00055
00056
00057
00058 struct token GTY(())
00059 {
00060
00061 short yychar;
00062 unsigned int lineno;
00063 YYSTYPE GTY ((desc ("%1.yychar"))) yylval;
00064 };
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #define TOKEN_CHUNK_SIZE 20
00077 struct token_chunk GTY(())
00078 {
00079 struct token_chunk *next;
00080 struct token toks[TOKEN_CHUNK_SIZE];
00081 };
00082
00083 struct unparsed_text GTY(())
00084 {
00085 struct unparsed_text *next;
00086 tree decl;
00087 location_t locus;
00088 int interface;
00089
00090 struct token_chunk * tokens;
00091
00092 struct token_chunk *last_chunk;
00093 short last_pos;
00094
00095
00096 short cur_pos;
00097 struct token_chunk *cur_chunk;
00098 };
00099
00100
00101
00102 struct feed GTY(())
00103 {
00104 struct unparsed_text *input;
00105 location_t locus;
00106 int yychar;
00107 YYSTYPE GTY ((desc ("%1.yychar"))) yylval;
00108 int first_token;
00109 struct obstack GTY ((skip (""))) token_obstack;
00110 struct feed *next;
00111 };
00112
00113 static GTY(()) struct feed *feed;
00114
00115 static SPEW_INLINE void do_aggr PARAMS ((void));
00116 static SPEW_INLINE int identifier_type PARAMS ((tree));
00117 static void scan_tokens PARAMS ((int));
00118 static void feed_defarg PARAMS ((tree));
00119 static void finish_defarg PARAMS ((void));
00120 static void yylexstring PARAMS ((struct token *));
00121 static int read_token PARAMS ((struct token *));
00122
00123 static SPEW_INLINE int num_tokens PARAMS ((void));
00124 static SPEW_INLINE struct token *nth_token PARAMS ((int));
00125 static SPEW_INLINE int next_token PARAMS ((struct token *));
00126 static SPEW_INLINE int shift_token PARAMS ((void));
00127 static SPEW_INLINE void push_token PARAMS ((struct token *));
00128 static SPEW_INLINE void consume_token PARAMS ((void));
00129 static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *));
00130
00131 static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *));
00132 static SPEW_INLINE struct token * space_for_token
00133 PARAMS ((struct unparsed_text *t));
00134 static SPEW_INLINE struct token * remove_last_token
00135 PARAMS ((struct unparsed_text *t));
00136 static struct unparsed_text * alloc_unparsed_text
00137 PARAMS ((const location_t *, tree decl, int interface));
00138
00139 static void snarf_block PARAMS ((struct unparsed_text *t));
00140 static tree snarf_defarg PARAMS ((void));
00141 static void snarf_parenthesized_expression (struct unparsed_text *);
00142 static int frob_id PARAMS ((int, int, tree *));
00143
00144
00145
00146 static GTY(()) struct unparsed_text *pending_inlines;
00147 static GTY(()) struct unparsed_text *pending_inlines_tail;
00148
00149
00150
00151 static GTY(()) struct unparsed_text *processing_these_inlines;
00152
00153 static void begin_parsing_inclass_inline PARAMS ((struct unparsed_text *));
00154
00155 #ifdef SPEW_DEBUG
00156 int spew_debug = 0;
00157 static unsigned int yylex_ctr = 0;
00158
00159 static void debug_yychar PARAMS ((int));
00160
00161
00162 extern char *debug_yytranslate PARAMS ((int));
00163 #endif
00164 static enum cpp_ttype last_token;
00165 static tree last_token_id;
00166
00167
00168
00169
00170
00171
00172
00173 extern tree lastiddecl;
00174 extern int yychar;
00175 extern YYSTYPE yylval;
00176
00177
00178 static struct obstack token_obstack;
00179 static int first_token;
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 static GTY(()) tree defarg_fns;
00192
00193 static GTY(()) tree defarg_parm;
00194
00195 static GTY(()) tree defarg_depfns;
00196
00197 static GTY(()) tree defarg_fnsdone;
00198
00199
00200
00201 void
00202 init_spew ()
00203 {
00204 gcc_obstack_init (&token_obstack);
00205 }
00206
00207 #ifdef KEY
00208 extern bool in_omp_pragma;
00209 #endif
00210
00211
00212 static SPEW_INLINE int
00213 read_process_identifier (pyylval)
00214 YYSTYPE *pyylval;
00215 {
00216 tree id = pyylval->ttype;
00217
00218 if (C_IS_RESERVED_WORD (id))
00219 {
00220 #ifdef KEY
00221
00222 if (in_omp_pragma &&
00223 (C_RID_CODE (id) == RID_PRIVATE ||
00224 C_RID_CODE (id) == RID_STATIC))
00225 return IDENTIFIER;
00226 #endif
00227
00228 pyylval->ttype = ridpointers[C_RID_CODE (id)];
00229 return C_RID_YYCODE (id);
00230 }
00231
00232
00233
00234
00235
00236 #if !defined(JOINER) || JOINER == '$'
00237 if (VPTR_NAME_P (id)
00238 || VTABLE_NAME_P (id)
00239 || TEMP_NAME_P (id)
00240 || ANON_AGGRNAME_P (id))
00241 warning (
00242 "identifier name `%s' conflicts with GNU C++ internal naming strategy",
00243 IDENTIFIER_POINTER (id));
00244 #endif
00245 return IDENTIFIER;
00246 }
00247
00248
00249
00250
00251 static void
00252 yylexstring (t)
00253 struct token *t;
00254 {
00255 enum cpp_ttype next_type;
00256 tree next;
00257
00258 next_type = c_lex (&next);
00259 if (next_type == CPP_STRING || next_type == CPP_WSTRING)
00260 {
00261 varray_type strings;
00262
00263 VARRAY_TREE_INIT (strings, 32, "strings");
00264 VARRAY_PUSH_TREE (strings, t->yylval.ttype);
00265
00266 do
00267 {
00268 VARRAY_PUSH_TREE (strings, next);
00269 next_type = c_lex (&next);
00270 }
00271 while (next_type == CPP_STRING || next_type == CPP_WSTRING);
00272
00273 t->yylval.ttype = combine_strings (strings);
00274 last_token_id = t->yylval.ttype;
00275 }
00276
00277
00278 _cpp_backup_tokens (parse_in, 1);
00279
00280 t->yychar = STRING;
00281 }
00282
00283
00284 #ifdef KEY
00285 extern bool seen_omp_paren;
00286 static int
00287 check_omp_string (char * s, bool * status)
00288 {
00289 *status = true;
00290
00291 if (!strcmp (s, "\n"))
00292 {
00293 in_omp_pragma = seen_omp_paren = FALSE;
00294 return '\n';
00295 }
00296 if (!strcmp (s, "options") && !seen_omp_paren)
00297 return OPTIONS_PRAGMA;
00298 if ((!strcmp (s, "mips_frequency_hint") ||
00299 !strcmp (s, "frequency_hint")) && !seen_omp_paren)
00300 return EXEC_FREQ_PRAGMA;
00301 if (!strcasecmp (s, "never") && !seen_omp_paren)
00302 return FREQ_NEVER;
00303 if (!strcasecmp (s, "init") && !seen_omp_paren)
00304 return FREQ_INIT;
00305 if (!strcasecmp (s, "frequent") && !seen_omp_paren)
00306 return FREQ_FREQUENT;
00307 if (!strcmp (s, "private") && !seen_omp_paren)
00308 return OMP_PRIVATE;
00309 if (!strcmp (s, "parallel") && !seen_omp_paren)
00310 return OMP_PARALLEL;
00311 if (!strcmp (s, "omp") && !seen_omp_paren)
00312 return OMP_PRAGMA;
00313 if (!strcmp (s, "copyprivate") && !seen_omp_paren)
00314 return OMP_COPYPRIVATE;
00315 if (!strcmp (s, "firstprivate") && !seen_omp_paren)
00316 return OMP_FIRSTPRIVATE;
00317 if (!strcmp (s, "lastprivate") && !seen_omp_paren)
00318 return OMP_LASTPRIVATE;
00319 if (!strcmp (s, "shared"))
00320 return OMP_SHARED;
00321 if (!strcmp (s, "none"))
00322 return OMP_NONE;
00323 if (!strcmp (s, "reduction") && !seen_omp_paren)
00324 return OMP_REDUCTION;
00325 if (!strcmp (s, "copyin") && !seen_omp_paren)
00326 return OMP_COPYIN;
00327 if (!strcmp (s, "static"))
00328 return OMP_STATIC;
00329 if (!strcmp (s, "dynamic"))
00330 return OMP_DYNAMIC;
00331 if (!strcmp (s, "guided"))
00332 return OMP_GUIDED;
00333 if (!strcmp (s, "runtime"))
00334 return OMP_RUNTIME;
00335 if (!strcmp (s, "ordered"))
00336 return OMP_ORDERED;
00337 if (!strcmp (s, "schedule"))
00338 return OMP_SCHEDULE;
00339 if (!strcmp (s, "nowait"))
00340 return OMP_NOWAIT;
00341 if (!strcmp (s, "num_threads") && !seen_omp_paren)
00342 return OMP_NUM_THREADS;
00343 if (!strcmp (s, "sections") && !seen_omp_paren)
00344 return OMP_SECTIONS;
00345 if (!strcmp (s, "section"))
00346 return OMP_SECTION;
00347 if (!strcmp (s, "single"))
00348 return OMP_SINGLE;
00349 if (!strcmp (s, "master") && !seen_omp_paren)
00350 return OMP_MASTER;
00351 if (!strcmp (s, "critical") && !seen_omp_paren)
00352 return OMP_CRITICAL;
00353 if (!strcmp (s, "barrier") && !seen_omp_paren)
00354 return OMP_BARRIER;
00355 if (!strcmp (s, "atomic") && !seen_omp_paren)
00356 return OMP_ATOMIC;
00357 if (!strcmp (s, "flush") && !seen_omp_paren)
00358 return OMP_FLUSH;
00359 if (!strcmp (s, "threadprivate") && !seen_omp_paren)
00360 return OMP_THREADPRIVATE;
00361 #ifdef TARG_SL2 //fork_joint
00362 if(!strcmp(s, "sl2") && !seen_omp_paren)
00363 return PRAGMA_SL2;
00364 if(!strcmp(s, "sl2_major_sections") && !seen_omp_paren)
00365 return SL2_SECTIONS;
00366 if(!strcmp(s, "sl2_minor_sections") && !seen_omp_paren)
00367 return SL2_MINOR_SECTIONS;
00368 if(!strcmp(s, "sl2_major_section") && !seen_omp_paren)
00369 return SL2_SECTION;
00370 if(!strcmp(s, "sl2_minor_section") && !seen_omp_paren)
00371 return SL2_MINOR_SECTION;
00372 #endif
00373
00374
00375 *status = false;
00376 return 0;
00377 }
00378 #endif
00379
00380
00381
00382 static int
00383 read_token (t)
00384 struct token *t;
00385 {
00386 retry:
00387
00388 last_token = c_lex (&last_token_id);
00389 t->yylval.ttype = last_token_id;
00390
00391 switch (last_token)
00392 {
00393 #define YYCHAR(YY) t->yychar = (YY); break;
00394 #define YYCODE(C) t->yylval.code = (C);
00395
00396 case CPP_EQ: YYCHAR('=');
00397 case CPP_NOT: YYCHAR('!');
00398 case CPP_GREATER: YYCODE(GT_EXPR); YYCHAR('>');
00399 case CPP_LESS: YYCODE(LT_EXPR); YYCHAR('<');
00400 case CPP_PLUS: YYCODE(PLUS_EXPR); YYCHAR('+');
00401 case CPP_MINUS: YYCODE(MINUS_EXPR); YYCHAR('-');
00402 case CPP_MULT: YYCODE(MULT_EXPR); YYCHAR('*');
00403 case CPP_DIV: YYCODE(TRUNC_DIV_EXPR); YYCHAR('/');
00404 case CPP_MOD: YYCODE(TRUNC_MOD_EXPR); YYCHAR('%');
00405 case CPP_AND: YYCODE(BIT_AND_EXPR); YYCHAR('&');
00406 case CPP_OR: YYCODE(BIT_IOR_EXPR); YYCHAR('|');
00407 case CPP_XOR: YYCODE(BIT_XOR_EXPR); YYCHAR('^');
00408 case CPP_RSHIFT: YYCODE(RSHIFT_EXPR); YYCHAR(RSHIFT);
00409 case CPP_LSHIFT: YYCODE(LSHIFT_EXPR); YYCHAR(LSHIFT);
00410
00411 case CPP_COMPL: YYCHAR('~');
00412 case CPP_AND_AND: YYCHAR(ANDAND);
00413 case CPP_OR_OR: YYCHAR(OROR);
00414 case CPP_QUERY: YYCHAR('?');
00415 case CPP_COLON: YYCHAR(':');
00416 case CPP_COMMA: YYCHAR(',');
00417 case CPP_OPEN_PAREN: YYCHAR('(');
00418 case CPP_CLOSE_PAREN: YYCHAR(')');
00419 case CPP_EQ_EQ: YYCODE(EQ_EXPR); YYCHAR(EQCOMPARE);
00420 case CPP_NOT_EQ: YYCODE(NE_EXPR); YYCHAR(EQCOMPARE);
00421 case CPP_GREATER_EQ:YYCODE(GE_EXPR); YYCHAR(ARITHCOMPARE);
00422 case CPP_LESS_EQ: YYCODE(LE_EXPR); YYCHAR(ARITHCOMPARE);
00423
00424 case CPP_PLUS_EQ: YYCODE(PLUS_EXPR); YYCHAR(ASSIGN);
00425 case CPP_MINUS_EQ: YYCODE(MINUS_EXPR); YYCHAR(ASSIGN);
00426 case CPP_MULT_EQ: YYCODE(MULT_EXPR); YYCHAR(ASSIGN);
00427 case CPP_DIV_EQ: YYCODE(TRUNC_DIV_EXPR); YYCHAR(ASSIGN);
00428 case CPP_MOD_EQ: YYCODE(TRUNC_MOD_EXPR); YYCHAR(ASSIGN);
00429 case CPP_AND_EQ: YYCODE(BIT_AND_EXPR); YYCHAR(ASSIGN);
00430 case CPP_OR_EQ: YYCODE(BIT_IOR_EXPR); YYCHAR(ASSIGN);
00431 case CPP_XOR_EQ: YYCODE(BIT_XOR_EXPR); YYCHAR(ASSIGN);
00432 case CPP_RSHIFT_EQ: YYCODE(RSHIFT_EXPR); YYCHAR(ASSIGN);
00433 case CPP_LSHIFT_EQ: YYCODE(LSHIFT_EXPR); YYCHAR(ASSIGN);
00434
00435 case CPP_OPEN_SQUARE: YYCHAR('[');
00436 case CPP_CLOSE_SQUARE: YYCHAR(']');
00437 case CPP_OPEN_BRACE: YYCHAR('{');
00438 case CPP_CLOSE_BRACE: YYCHAR('}');
00439 case CPP_SEMICOLON: YYCHAR(';');
00440 case CPP_ELLIPSIS: YYCHAR(ELLIPSIS);
00441
00442 case CPP_PLUS_PLUS: YYCHAR(PLUSPLUS);
00443 case CPP_MINUS_MINUS: YYCHAR(MINUSMINUS);
00444 case CPP_DEREF: YYCHAR(POINTSAT);
00445 case CPP_DOT: YYCHAR('.');
00446
00447
00448 case CPP_SCOPE: YYCHAR(SCOPE);
00449 case CPP_DEREF_STAR: YYCHAR(POINTSAT_STAR);
00450 case CPP_DOT_STAR: YYCHAR(DOT_STAR);
00451 case CPP_MIN_EQ: YYCODE(MIN_EXPR); YYCHAR(ASSIGN);
00452 case CPP_MAX_EQ: YYCODE(MAX_EXPR); YYCHAR(ASSIGN);
00453 case CPP_MIN: YYCODE(MIN_EXPR); YYCHAR(MIN_MAX);
00454 case CPP_MAX: YYCODE(MAX_EXPR); YYCHAR(MIN_MAX);
00455 #undef YYCHAR
00456 #undef YYCODE
00457
00458 case CPP_EOF:
00459 t->yychar = 0;
00460 break;
00461
00462 case CPP_NAME:
00463 t->yychar = read_process_identifier (&t->yylval);
00464 #ifdef KEY
00465 if (t->yychar == IDENTIFIER && in_omp_pragma)
00466 {
00467 if (TREE_CODE(t->yylval.ttype) != IDENTIFIER_NODE) abort();
00468 char * omp_name = IDENTIFIER_POINTER (t->yylval.ttype);
00469 bool valid = false;
00470 int code = check_omp_string (omp_name, &valid);
00471 if (valid)
00472 t->yychar = code;
00473 }
00474 #endif
00475 break;
00476
00477 case CPP_NUMBER:
00478 case CPP_CHAR:
00479 case CPP_WCHAR:
00480 t->yychar = CONSTANT;
00481 break;
00482
00483 case CPP_STRING:
00484 case CPP_WSTRING:
00485 yylexstring (t);
00486 break;
00487
00488 default:
00489 yyerror ("parse error");
00490 goto retry;
00491 }
00492
00493 t->lineno = lineno;
00494 return t->yychar;
00495 }
00496
00497 static void
00498 feed_input (input)
00499 struct unparsed_text *input;
00500 {
00501 struct feed *f;
00502 #if 0
00503 if (feed)
00504 abort ();
00505 #endif
00506
00507 f = ggc_alloc (sizeof (struct feed));
00508
00509 input->cur_chunk = input->tokens;
00510 input->cur_pos = 0;
00511
00512 #ifdef SPEW_DEBUG
00513 if (spew_debug)
00514 fprintf (stderr, "\tfeeding %s:%d [%d tokens]\n",
00515 input->locus.file, input->locus.line, input->limit - input->pos);
00516 #endif
00517
00518 f->input = input;
00519 f->locus.file = input_filename;
00520 f->locus.line = lineno;
00521 f->yychar = yychar;
00522 f->yylval = yylval;
00523 f->first_token = first_token;
00524 f->token_obstack = token_obstack;
00525 f->next = feed;
00526
00527 input_filename = input->locus.file;
00528 lineno = input->locus.line;
00529 yychar = YYEMPTY;
00530 yylval.ttype = NULL_TREE;
00531 first_token = 0;
00532 gcc_obstack_init (&token_obstack);
00533 feed = f;
00534 }
00535
00536 void
00537 end_input ()
00538 {
00539 struct feed *f = feed;
00540
00541 input_filename = f->locus.file;
00542 lineno = f->locus.line;
00543 yychar = f->yychar;
00544 yylval = f->yylval;
00545 first_token = f->first_token;
00546 obstack_free (&token_obstack, 0);
00547 token_obstack = f->token_obstack;
00548 feed = f->next;
00549
00550 #ifdef SPEW_DEBUG
00551 if (spew_debug)
00552 fprintf (stderr, "\treturning to %s:%d\n", input_filename, lineno);
00553 #endif
00554 }
00555
00556
00557
00558
00559 static SPEW_INLINE int
00560 num_tokens ()
00561 {
00562 return (obstack_object_size (&token_obstack) / sizeof (struct token))
00563 - first_token;
00564 }
00565
00566
00567
00568 static SPEW_INLINE struct token*
00569 nth_token (n)
00570 int n;
00571 {
00572 #ifdef ENABLE_CHECKING
00573
00574
00575 my_friendly_assert (n >= 0 && n < num_tokens (), 298);
00576 #endif
00577 return ((struct token*)obstack_base (&token_obstack)) + n + first_token;
00578 }
00579
00580 static const struct token Teosi = { END_OF_SAVED_INPUT, 0 UNION_INIT_ZERO };
00581 static const struct token Tpad = { EMPTY, 0 UNION_INIT_ZERO };
00582
00583
00584 static SPEW_INLINE int
00585 next_token (t)
00586 struct token *t;
00587 {
00588 if (!feed)
00589 return read_token (t);
00590
00591 if (feed->input->cur_chunk != feed->input->last_chunk
00592 || feed->input->cur_pos != feed->input->last_pos)
00593 {
00594 if (feed->input->cur_pos == TOKEN_CHUNK_SIZE)
00595 {
00596 feed->input->cur_chunk = feed->input->cur_chunk->next;
00597 feed->input->cur_pos = 0;
00598 }
00599 memcpy (t, feed->input->cur_chunk->toks + feed->input->cur_pos,
00600 sizeof (struct token));
00601 feed->input->cur_pos++;
00602 return t->yychar;
00603 }
00604
00605 return 0;
00606 }
00607
00608
00609 static SPEW_INLINE int
00610 shift_token ()
00611 {
00612 size_t point = obstack_object_size (&token_obstack);
00613 obstack_blank (&token_obstack, sizeof (struct token));
00614 return next_token ((struct token *) (obstack_base (&token_obstack) + point));
00615 }
00616
00617
00618
00619 static SPEW_INLINE void
00620 consume_token ()
00621 {
00622 if (num_tokens () == 1)
00623 {
00624 obstack_free (&token_obstack, obstack_base (&token_obstack));
00625 first_token = 0;
00626 }
00627 else
00628 first_token++;
00629 }
00630
00631
00632 static SPEW_INLINE void
00633 push_token (t)
00634 struct token *t;
00635 {
00636 if (first_token == 0)
00637 {
00638 size_t active = obstack_object_size (&token_obstack);
00639 obstack_blank (&token_obstack, sizeof (struct token));
00640 if (active)
00641 memmove (obstack_base (&token_obstack) + sizeof (struct token),
00642 obstack_base (&token_obstack), active);
00643 first_token++;
00644 }
00645 first_token--;
00646 memcpy (nth_token (0), t, sizeof (struct token));
00647 }
00648
00649
00650
00651
00652
00653 static void
00654 scan_tokens (n)
00655 int n;
00656 {
00657 int i;
00658 int num = num_tokens ();
00659 int yychar;
00660
00661
00662 i = num;
00663 while (i > 0 && nth_token (i - 1)->yychar == EMPTY)
00664 i--;
00665 if (i < num)
00666 {
00667 obstack_blank (&token_obstack, -((num - i) * sizeof (struct token)));
00668 num = i;
00669 }
00670
00671
00672 if (num > n)
00673 return;
00674
00675
00676
00677 for (i = 0; i < num; i++)
00678 {
00679 yychar = nth_token (i)->yychar;
00680 if (yychar == '{' || yychar == ':' || yychar == ';')
00681 goto pad_tokens;
00682 }
00683
00684 while (num_tokens () <= n)
00685 {
00686 yychar = shift_token ();
00687 if (yychar == '{' || yychar == ':' || yychar == ';')
00688 goto pad_tokens;
00689 }
00690 return;
00691
00692 pad_tokens:
00693 while (num_tokens () <= n)
00694 obstack_grow (&token_obstack, &Tpad, sizeof (struct token));
00695 }
00696
00697 int looking_for_typename;
00698 int looking_for_template;
00699
00700 static int after_friend;
00701 static int after_new;
00702 static int do_snarf_defarg;
00703
00704 tree got_scope;
00705 tree got_object;
00706
00707 static SPEW_INLINE int
00708 identifier_type (decl)
00709 tree decl;
00710 {
00711 tree t;
00712
00713 if (TREE_CODE (decl) == TEMPLATE_DECL)
00714 {
00715 if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL)
00716 return PTYPENAME;
00717 else if (looking_for_template)
00718 return PFUNCNAME;
00719 }
00720 if (looking_for_template && really_overloaded_fn (decl))
00721 {
00722
00723 if (TREE_CODE (decl) == BASELINK)
00724 decl = BASELINK_FUNCTIONS (decl);
00725
00726 for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
00727 if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
00728 return PFUNCNAME;
00729 }
00730 if (TREE_CODE (decl) == NAMESPACE_DECL)
00731 return NSNAME;
00732 if (TREE_CODE (decl) != TYPE_DECL)
00733 return IDENTIFIER;
00734 if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type)
00735 return SELFNAME;
00736
00737
00738
00739 t = got_scope;
00740 if (t && TREE_CODE (t) == TYPENAME_TYPE)
00741 t = TREE_TYPE (t);
00742 decl = TREE_TYPE (decl);
00743 if (TREE_CODE (decl) == TYPENAME_TYPE)
00744 decl = TREE_TYPE (decl);
00745 if (t && t == decl)
00746 return SELFNAME;
00747
00748 return tTYPENAME;
00749 }
00750
00751
00752
00753
00754
00755
00756
00757 static SPEW_INLINE void
00758 do_aggr ()
00759 {
00760 int yc1, yc2;
00761
00762 scan_tokens (2);
00763 yc1 = nth_token (1)->yychar;
00764 if (yc1 != tTYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
00765 return;
00766 yc2 = nth_token (2)->yychar;
00767 if (yc2 == ';')
00768 {
00769
00770
00771 if (after_friend || after_new)
00772 return;
00773 }
00774 else if (yc2 != '{' && yc2 != ':')
00775 return;
00776
00777 switch (yc1)
00778 {
00779 case tTYPENAME:
00780 nth_token (1)->yychar = TYPENAME_DEFN;
00781 break;
00782 case PTYPENAME:
00783 nth_token (1)->yychar = PTYPENAME_DEFN;
00784 break;
00785 case IDENTIFIER:
00786 nth_token (1)->yychar = IDENTIFIER_DEFN;
00787 break;
00788 default:
00789 abort ();
00790 }
00791 }
00792
00793 void
00794 see_typename ()
00795 {
00796
00797 looking_for_typename = 2;
00798 if (yychar < 0)
00799 if ((yychar = yylex ()) < 0) yychar = 0;
00800 looking_for_typename = 0;
00801 if (yychar == IDENTIFIER)
00802 {
00803 lastiddecl = lookup_name (yylval.ttype, -2);
00804 if (lastiddecl)
00805 yychar = identifier_type (lastiddecl);
00806 }
00807 }
00808
00809 int
00810 yylex ()
00811 {
00812 int yychr;
00813 int old_looking_for_typename = 0;
00814 int just_saw_new = 0;
00815 int just_saw_friend = 0;
00816
00817 timevar_push (TV_LEX);
00818
00819 retry:
00820 #ifdef SPEW_DEBUG
00821 if (spew_debug)
00822 {
00823 yylex_ctr ++;
00824 fprintf (stderr, "\t\t## %d @%d ", yylex_ctr, lineno);
00825 }
00826 #endif
00827
00828 if (do_snarf_defarg)
00829 {
00830 do_snarf_defarg = 0;
00831 yylval.ttype = snarf_defarg ();
00832 yychar = DEFARG;
00833 got_object = NULL_TREE;
00834 timevar_pop (TV_LEX);
00835 return DEFARG;
00836 }
00837
00838
00839 else if (num_tokens ())
00840 yychr = nth_token (0)->yychar;
00841 else
00842 yychr = shift_token ();
00843
00844
00845
00846
00847 switch (yychr)
00848 {
00849 case EMPTY:
00850
00851 #ifdef SPEW_DEBUG
00852 if (spew_debug)
00853 debug_yychar (yychr);
00854 #endif
00855 consume_token ();
00856 goto retry;
00857
00858 case '(':
00859 scan_tokens (1);
00860 if (nth_token (1)->yychar == ')')
00861 {
00862 consume_token ();
00863 yychr = LEFT_RIGHT;
00864 }
00865 break;
00866
00867 case IDENTIFIER:
00868 {
00869 int peek;
00870
00871 scan_tokens (1);
00872 peek = nth_token (1)->yychar;
00873 yychr = frob_id (yychr, peek, &nth_token (0)->yylval.ttype);
00874 break;
00875 }
00876 case IDENTIFIER_DEFN:
00877 case tTYPENAME:
00878 case TYPENAME_DEFN:
00879 case PTYPENAME:
00880 case PTYPENAME_DEFN:
00881
00882
00883 looking_for_typename = old_looking_for_typename;
00884 looking_for_template = 0;
00885 break;
00886
00887 case SCSPEC:
00888 if (nth_token (0)->yylval.ttype == ridpointers[RID_EXTERN])
00889 {
00890 scan_tokens (1);
00891 if (nth_token (1)->yychar == STRING)
00892 {
00893 yychr = EXTERN_LANG_STRING;
00894 nth_token (1)->yylval.ttype = get_identifier
00895 (TREE_STRING_POINTER (nth_token (1)->yylval.ttype));
00896 consume_token ();
00897 }
00898 }
00899
00900 else if (nth_token (0)->yylval.ttype == ridpointers[RID_FRIEND])
00901 just_saw_friend = 1;
00902
00903 break;
00904
00905 case NEW:
00906
00907 just_saw_new = 1;
00908 break;
00909
00910 case TYPESPEC:
00911 case '{':
00912 case ':':
00913 case ';':
00914
00915
00916 looking_for_typename = 0;
00917 break;
00918
00919 case AGGR:
00920 do_aggr ();
00921 break;
00922
00923 case ENUM:
00924
00925 looking_for_typename = 2;
00926 break;
00927
00928 default:
00929 break;
00930 }
00931
00932 after_friend = just_saw_friend;
00933 after_new = just_saw_new;
00934
00935
00936
00937 if (yychr != '~')
00938 got_object = NULL_TREE;
00939
00940 yychar = yychr;
00941 {
00942 struct token *tok = nth_token (0);
00943
00944 yylval = tok->yylval;
00945 if (tok->lineno)
00946 lineno = tok->lineno;
00947 }
00948
00949 #ifdef SPEW_DEBUG
00950 if (spew_debug)
00951 debug_yychar (yychr);
00952 #endif
00953 consume_token ();
00954
00955 timevar_pop (TV_LEX);
00956 return yychr;
00957 }
00958
00959
00960
00961
00962
00963 void
00964 yyungetc (ch, rescan)
00965 int ch;
00966 int rescan;
00967 {
00968
00969 if (yychar == YYEMPTY || rescan == 0)
00970 {
00971 struct token fake;
00972
00973 fake.yychar = ch;
00974 fake.yylval.ttype = 0;
00975 fake.lineno = lineno;
00976
00977 push_token (&fake);
00978 }
00979 else
00980 {
00981 yychar = ch;
00982 }
00983 }
00984
00985
00986
00987 static int
00988 frob_id (yyc, peek, idp)
00989 int yyc;
00990 int peek;
00991 tree *idp;
00992 {
00993 tree trrr;
00994 int old_looking_for_typename = 0;
00995
00996 if (peek == SCOPE)
00997 {
00998
00999 old_looking_for_typename = looking_for_typename;
01000 looking_for_typename = 1;
01001 }
01002 else if (peek == '<')
01003 looking_for_template = 1;
01004 trrr = lookup_name (*idp, -2);
01005 if (trrr)
01006 {
01007 yyc = identifier_type (trrr);
01008 switch(yyc)
01009 {
01010 case tTYPENAME:
01011 case SELFNAME:
01012 case NSNAME:
01013 case PTYPENAME:
01014
01015
01016 if (got_scope || got_object)
01017 *idp = trrr;
01018
01019 case PFUNCNAME:
01020 case IDENTIFIER:
01021 lastiddecl = trrr;
01022 break;
01023 default:
01024 abort ();
01025 }
01026 }
01027 else
01028 lastiddecl = NULL_TREE;
01029 got_scope = NULL_TREE;
01030 looking_for_typename = old_looking_for_typename;
01031 looking_for_template = 0;
01032 return yyc;
01033 }
01034
01035
01036
01037
01038 tree frob_opname (id)
01039 tree id;
01040 {
01041 scan_tokens (0);
01042 frob_id (0, nth_token (0)->yychar, &id);
01043 got_object = NULL_TREE;
01044 return id;
01045 }
01046
01047
01048
01049
01050 static void
01051 begin_parsing_inclass_inline (pi)
01052 struct unparsed_text *pi;
01053 {
01054 tree context;
01055
01056
01057
01058 if (cfun)
01059 cp_function_chain->unparsed_inlines = pi;
01060 else
01061 processing_these_inlines = pi;
01062
01063 ggc_collect ();
01064
01065
01066
01067
01068 context = decl_function_context (pi->decl);
01069 if (context)
01070 push_function_context_to (context);
01071
01072 feed_input (pi);
01073 interface_unknown = pi->interface == 1;
01074 interface_only = pi->interface == 0;
01075 DECL_PENDING_INLINE_P (pi->decl) = 0;
01076 DECL_PENDING_INLINE_INFO (pi->decl) = 0;
01077
01078
01079
01080 yychar = PRE_PARSED_FUNCTION_DECL;
01081 yylval.pi = pi;
01082
01083 start_function (NULL_TREE, pi->decl, NULL_TREE,
01084 (SF_DEFAULT | SF_PRE_PARSED | SF_INCLASS_INLINE));
01085 }
01086
01087
01088
01089
01090
01091
01092 void
01093 do_pending_inlines ()
01094 {
01095
01096 if (yychar == PRE_PARSED_FUNCTION_DECL)
01097 return;
01098
01099 if (pending_inlines)
01100 {
01101
01102
01103
01104 struct unparsed_text *first = pending_inlines;
01105 pending_inlines = pending_inlines_tail = 0;
01106
01107 begin_parsing_inclass_inline (first);
01108 }
01109 }
01110
01111
01112
01113
01114
01115 void
01116 process_next_inline (i)
01117 struct unparsed_text *i;
01118 {
01119 tree decl = i->decl;
01120 tree context = decl_function_context (decl);
01121
01122 if (context)
01123 pop_function_context_from (context);
01124 if (yychar == YYEMPTY)
01125 yychar = yylex ();
01126 if (yychar != END_OF_SAVED_INPUT)
01127 error ("parse error at end of saved function text");
01128 end_input ();
01129
01130 i = i->next;
01131 if (i)
01132 begin_parsing_inclass_inline (i);
01133 else
01134 {
01135 if (cfun)
01136 cp_function_chain->unparsed_inlines = 0;
01137 else
01138 processing_these_inlines = 0;
01139 extract_interface_info ();
01140 }
01141 }
01142
01143
01144 static SPEW_INLINE struct token *
01145 space_for_token (t)
01146 struct unparsed_text *t;
01147 {
01148 if (t->last_pos != TOKEN_CHUNK_SIZE)
01149 return t->last_chunk->toks + (t->last_pos++);
01150
01151 t->last_chunk->next = ggc_alloc_cleared (sizeof (*t->last_chunk->next));
01152 t->last_chunk = t->last_chunk->next;
01153 t->last_chunk->next = NULL;
01154
01155 t->last_pos = 1;
01156 return t->last_chunk->toks;
01157 }
01158
01159
01160 static SPEW_INLINE struct token *
01161 remove_last_token (t)
01162 struct unparsed_text *t;
01163 {
01164 struct token *result = t->last_chunk->toks + t->last_pos - 1;
01165 if (t->last_pos == 0)
01166 abort ();
01167 t->last_pos--;
01168 if (t->last_pos == 0 && t->last_chunk != t->tokens)
01169 {
01170 struct token_chunk *c;
01171 c = t->tokens;
01172 while (c->next != t->last_chunk)
01173 c = c->next;
01174 c->next = NULL;
01175 t->last_chunk = c;
01176 t->last_pos = ARRAY_SIZE (c->toks);
01177 }
01178 return result;
01179 }
01180
01181
01182 static struct unparsed_text *
01183 alloc_unparsed_text (locus, decl, interface)
01184 const location_t *locus;
01185 tree decl;
01186 int interface;
01187 {
01188 struct unparsed_text *r;
01189 r = ggc_alloc_cleared (sizeof (*r));
01190 r->decl = decl;
01191 r->locus = *locus;
01192 r->interface = interface;
01193 r->tokens = r->last_chunk = ggc_alloc_cleared (sizeof (*r->tokens));
01194 return r;
01195 }
01196
01197
01198
01199
01200 static void
01201 snarf_parenthesized_expression (struct unparsed_text *t)
01202 {
01203 int yyc;
01204 int level = 1;
01205
01206 while (1)
01207 {
01208 yyc = next_token (space_for_token (t));
01209 if (yyc == '(')
01210 ++level;
01211 else if (yyc == ')' && --level == 0)
01212 break;
01213 else if (yyc == 0)
01214 {
01215 error ("%Hend of file read inside definition", &t->locus);
01216 break;
01217 }
01218 }
01219 }
01220
01221
01222
01223 static void
01224 snarf_block (t)
01225 struct unparsed_text *t;
01226 {
01227 int blev = 1;
01228 int look_for_semicolon = 0;
01229 int look_for_lbrac = 0;
01230 int look_for_catch = 0;
01231 int yyc;
01232 struct token *current;
01233
01234 if (yychar == '{')
01235 ;
01236 else if (yychar == '=')
01237 look_for_semicolon = 1;
01238 else if (yychar == ':' || yychar == RETURN_KEYWORD || yychar == TRY)
01239 {
01240 if (yychar == TRY)
01241 look_for_catch = 1;
01242 look_for_lbrac = 1;
01243 blev = 0;
01244 }
01245 else
01246 yyerror ("parse error in method specification");
01247
01248
01249 current = space_for_token (t);
01250 current->yychar = yychar;
01251 current->yylval = yylval;
01252 current->lineno = lineno;
01253
01254 for (;;)
01255 {
01256 yyc = next_token (space_for_token (t));
01257
01258 if (yyc == '{')
01259 {
01260 look_for_lbrac = 0;
01261 blev++;
01262 }
01263 else if (yyc == '}')
01264 {
01265 blev--;
01266 if (blev == 0 && !look_for_semicolon)
01267 {
01268 if (!look_for_catch)
01269 break;
01270
01271 if (next_token (space_for_token (t)) != CATCH)
01272 {
01273 push_token (remove_last_token (t));
01274 break;
01275 }
01276
01277 look_for_lbrac = 1;
01278 }
01279 }
01280 else if (yyc == ';')
01281 {
01282 if (look_for_lbrac)
01283 {
01284 struct token *fake;
01285
01286 error ("function body for constructor missing");
01287
01288 fake = space_for_token (t);
01289 fake->yylval.ttype = 0;
01290 fake->yychar = '{';
01291 fake = space_for_token (t);
01292 fake->yylval.ttype = 0;
01293 fake->yychar = '}';
01294 break;
01295 }
01296 else if (look_for_semicolon && blev == 0)
01297 break;
01298 }
01299 else if (yyc == '(' && blev == 0)
01300 snarf_parenthesized_expression (t);
01301 else if (yyc == 0)
01302 {
01303 error ("%Hend of file read inside definition", &t->locus);
01304 break;
01305 }
01306 }
01307 }
01308
01309
01310
01311 void
01312 snarf_method (decl)
01313 tree decl;
01314 {
01315 struct unparsed_text *meth;
01316 location_t starting;
01317 starting.file = input_filename;
01318 starting.line = lineno;
01319
01320 meth = alloc_unparsed_text (&starting, decl, (interface_unknown ? 1
01321 : (interface_only ? 0 : 2)));
01322
01323 snarf_block (meth);
01324
01325
01326
01327
01328
01329 memcpy (space_for_token (meth), &Teosi, sizeof (struct token));
01330 memcpy (space_for_token (meth), &Teosi, sizeof (struct token));
01331 memcpy (space_for_token (meth), &Teosi, sizeof (struct token));
01332
01333
01334
01335 if (decl == void_type_node
01336 || (current_class_type && TYPE_REDEFINED (current_class_type)))
01337 return;
01338
01339 #ifdef SPEW_DEBUG
01340 if (spew_debug)
01341 fprintf (stderr, "\tsaved method of %d tokens from %s:%d\n",
01342 meth->limit, starting.file, starting.line);
01343 #endif
01344
01345 DECL_PENDING_INLINE_INFO (decl) = meth;
01346 DECL_PENDING_INLINE_P (decl) = 1;
01347
01348
01349
01350 DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
01351
01352 if (pending_inlines_tail)
01353 pending_inlines_tail->next = meth;
01354 else
01355 pending_inlines = meth;
01356 pending_inlines_tail = meth;
01357 }
01358
01359
01360
01361
01362 static tree
01363 snarf_defarg ()
01364 {
01365 int yyc;
01366 int plev = 0;
01367 struct unparsed_text *buf;
01368 tree arg;
01369 location_t starting;
01370 starting.file = input_filename;
01371 starting.line = lineno;
01372
01373 buf = alloc_unparsed_text (&starting, 0, 0);
01374
01375 for (;;)
01376 {
01377 yyc = next_token (space_for_token (buf));
01378
01379 if (plev <= 0 && (yyc == ')' || yyc == ','))
01380 break;
01381 else if (yyc == '(' || yyc == '[')
01382 ++plev;
01383 else if (yyc == ']' || yyc == ')')
01384 --plev;
01385 else if (yyc == 0)
01386 {
01387 error ("%Hend of file read inside default argument", &starting);
01388 goto done;
01389 }
01390 }
01391
01392
01393 push_token (remove_last_token (buf));
01394
01395
01396
01397
01398
01399 memcpy (space_for_token (buf), &Teosi, sizeof (struct token));
01400 memcpy (space_for_token (buf), &Teosi, sizeof (struct token));
01401 memcpy (space_for_token (buf), &Teosi, sizeof (struct token));
01402
01403 done:
01404 #ifdef SPEW_DEBUG
01405 if (spew_debug)
01406 fprintf (stderr, "\tsaved defarg of %d tokens from %s:%d\n",
01407 buf->limit, starting.file, starting.line);
01408 #endif
01409
01410 arg = make_node (DEFAULT_ARG);
01411 DEFARG_POINTER (arg) = (unsigned char *)buf;
01412
01413 return arg;
01414 }
01415
01416
01417
01418
01419 void
01420 maybe_snarf_defarg ()
01421 {
01422 if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
01423 do_snarf_defarg = 1;
01424 }
01425
01426
01427
01428
01429
01430
01431 void
01432 add_defarg_fn (decl)
01433 tree decl;
01434 {
01435 if (TREE_CODE (decl) == FUNCTION_DECL)
01436 TREE_VALUE (defarg_fns) = decl;
01437 else
01438 {
01439 defarg_fns = tree_cons (NULL_TREE, decl, defarg_fns);
01440 TREE_TYPE (defarg_fns) = current_class_type;
01441 }
01442 }
01443
01444
01445
01446 static void
01447 feed_defarg (p)
01448 tree p;
01449 {
01450 tree d = TREE_PURPOSE (p);
01451
01452 feed_input ((struct unparsed_text *)DEFARG_POINTER (d));
01453 yychar = DEFARG_MARKER;
01454 yylval.ttype = p;
01455 }
01456
01457
01458
01459 static void
01460 finish_defarg ()
01461 {
01462 if (yychar == YYEMPTY)
01463 yychar = yylex ();
01464 if (yychar != END_OF_SAVED_INPUT)
01465 error ("parse error at end of saved function text");
01466
01467 end_input ();
01468 }
01469
01470
01471
01472
01473 void
01474 do_pending_defargs ()
01475 {
01476 if (defarg_parm)
01477 finish_defarg ();
01478
01479 for (; defarg_fns;)
01480 {
01481 tree current = defarg_fns;
01482
01483 tree defarg_fn = TREE_VALUE (defarg_fns);
01484 if (defarg_parm == NULL_TREE)
01485 {
01486 push_nested_class (TREE_TYPE (defarg_fns), 1);
01487 pushlevel (0);
01488 if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
01489 maybe_begin_member_template_processing (defarg_fn);
01490
01491 if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
01492 defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
01493 else
01494 defarg_parm = TYPE_ARG_TYPES (defarg_fn);
01495 }
01496 else
01497 defarg_parm = TREE_CHAIN (defarg_parm);
01498
01499 for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
01500 if (!TREE_PURPOSE (defarg_parm)
01501 || TREE_CODE (TREE_PURPOSE (defarg_parm)) != DEFAULT_ARG)
01502 ;
01503 else if (TREE_PURPOSE (current) == error_mark_node)
01504 DEFARG_POINTER (TREE_PURPOSE (defarg_parm)) = NULL;
01505 else
01506 {
01507 feed_defarg (defarg_parm);
01508
01509
01510
01511 return;
01512 }
01513
01514 if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
01515 {
01516 maybe_end_member_template_processing ();
01517 check_default_args (defarg_fn);
01518 }
01519
01520 poplevel (0, 0, 0);
01521 pop_nested_class ();
01522
01523 defarg_fns = TREE_CHAIN (defarg_fns);
01524 if (defarg_depfns)
01525 {
01526
01527
01528
01529 tree a, b;
01530
01531 for (a = defarg_depfns, b = TREE_PURPOSE (current); a && b;
01532 a = TREE_CHAIN (a), b = TREE_CHAIN (b))
01533 if (TREE_VALUE (a) != TREE_VALUE (b))
01534 goto different;
01535 if (a || b)
01536 {
01537 different:;
01538 TREE_CHAIN (current) = NULL_TREE;
01539 defarg_fns = chainon (defarg_fns, current);
01540 TREE_PURPOSE (current) = defarg_depfns;
01541 }
01542 else
01543 {
01544 cp_warning_at ("circular dependency in default args of `%#D'", defarg_fn);
01545
01546
01547
01548
01549 defarg_fns = current;
01550 TREE_PURPOSE (current) = error_mark_node;
01551 }
01552 defarg_depfns = NULL_TREE;
01553 }
01554 else if (TREE_PURPOSE (current) == error_mark_node)
01555 defarg_fnsdone = tree_cons (NULL_TREE, defarg_fn, defarg_fnsdone);
01556 }
01557 }
01558
01559
01560
01561 void
01562 done_pending_defargs ()
01563 {
01564 for (; defarg_fnsdone; defarg_fnsdone = TREE_CHAIN (defarg_fnsdone))
01565 {
01566 tree fn = TREE_VALUE (defarg_fnsdone);
01567 tree parms;
01568
01569 if (TREE_CODE (fn) == FUNCTION_DECL)
01570 parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
01571 else
01572 parms = TYPE_ARG_TYPES (fn);
01573 for (; parms; parms = TREE_CHAIN (parms))
01574 if (TREE_PURPOSE (parms)
01575 && TREE_CODE (TREE_PURPOSE (parms)) == DEFAULT_ARG)
01576 {
01577 my_friendly_assert (!DEFARG_POINTER (TREE_PURPOSE (parms)), 20010107);
01578 TREE_PURPOSE (parms) = NULL_TREE;
01579 }
01580 }
01581 }
01582
01583
01584
01585
01586
01587 void
01588 unprocessed_defarg_fn (fn)
01589 tree fn;
01590 {
01591 defarg_depfns = tree_cons (NULL_TREE, fn, defarg_depfns);
01592 }
01593
01594
01595
01596
01597
01598 void
01599 replace_defarg (arg, init)
01600 tree arg, init;
01601 {
01602 if (init == error_mark_node)
01603 TREE_PURPOSE (arg) = error_mark_node;
01604 else
01605 {
01606 if (! processing_template_decl
01607 && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init))
01608 pedwarn ("invalid type `%T' for default argument to `%T'",
01609 TREE_TYPE (init), TREE_VALUE (arg));
01610 if (!defarg_depfns)
01611 TREE_PURPOSE (arg) = init;
01612 }
01613 }
01614
01615 #ifdef SPEW_DEBUG
01616
01617
01618 static void
01619 debug_yychar (yy)
01620 int yy;
01621 {
01622 if (yy<256)
01623 fprintf (stderr, "->%d < %c >\n", lineno, yy);
01624 else if (yy == IDENTIFIER || yy == tTYPENAME)
01625 {
01626 const char *id;
01627 if (TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
01628 id = IDENTIFIER_POINTER (yylval.ttype);
01629 else if (TREE_CODE_CLASS (TREE_CODE (yylval.ttype)) == 'd')
01630 id = IDENTIFIER_POINTER (DECL_NAME (yylval.ttype));
01631 else
01632 id = "";
01633 fprintf (stderr, "->%d <%s `%s'>\n", lineno, debug_yytranslate (yy), id);
01634 }
01635 else
01636 fprintf (stderr, "->%d <%s>\n", lineno, debug_yytranslate (yy));
01637 }
01638
01639 #endif
01640
01641 #define NAME(TYPE) cpp_type2name (TYPE)
01642
01643 void
01644 yyerror (msgid)
01645 const char *msgid;
01646 {
01647 const char *string = _(msgid);
01648
01649 if (last_token == CPP_EOF)
01650 error ("%s at end of input", string);
01651 else if (last_token == CPP_CHAR || last_token == CPP_WCHAR)
01652 {
01653 if (yylval.ttype && TREE_CODE (yylval.ttype) == INTEGER_CST)
01654 {
01655 unsigned int val = TREE_INT_CST_LOW (yylval.ttype);
01656 const char *const ell = (last_token == CPP_CHAR) ? "" : "L";
01657 if (val <= UCHAR_MAX && ISGRAPH (val))
01658 error ("%s before %s'%c'", string, ell, val);
01659 else
01660 error ("%s before %s'\\x%x'", string, ell, val);
01661 }
01662 else
01663 error ("%s", string);
01664 }
01665 else if (last_token == CPP_STRING
01666 || last_token == CPP_WSTRING)
01667 error ("%s before string constant", string);
01668 else if (last_token == CPP_NUMBER)
01669 error ("%s before numeric constant", string);
01670 else if (last_token == CPP_NAME)
01671 {
01672 if (TREE_CODE (last_token_id) == IDENTIFIER_NODE)
01673 error ("%s before `%s'", string, IDENTIFIER_POINTER (last_token_id));
01674 else if (ISGRAPH (yychar))
01675 error ("%s before `%c'", string, yychar);
01676 else
01677 error ("%s before `\%o'", string, yychar);
01678 }
01679 else
01680 error ("%s before `%s' token", string, NAME (last_token));
01681 }
01682
01683 #include "gt-cp-spew.h"