📄 cp-lex.c
字号:
return reduce_count[*q] - reduce_count[*p];}static inttoken_cmp (p, q) int *p, *q;{ return token_count[*q] - token_count[*p];}voidprint_parse_statistics (){#ifdef GATHER_STATISTICS#if YYDEBUG != 0 int i; int maxlen = REDUCE_LENGTH; unsigned *sorted; if (reduce_count[-1] == 0) return; if (TOKEN_LENGTH > REDUCE_LENGTH) maxlen = TOKEN_LENGTH; sorted = (unsigned *) alloca (sizeof (int) * maxlen); for (i = 0; i < TOKEN_LENGTH; i++) sorted[i] = i; qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp); for (i = 0; i < TOKEN_LENGTH; i++) { int index = sorted[i]; if (token_count[index] == 0) break; if (token_count[index] < token_count[-1]) break; fprintf (stderr, "token %d, `%s', count = %d\n", index, yytname[YYTRANSLATE (index)], token_count[index]); } fprintf (stderr, "\n"); for (i = 0; i < REDUCE_LENGTH; i++) sorted[i] = i; qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp); for (i = 0; i < REDUCE_LENGTH; i++) { int index = sorted[i]; if (reduce_count[index] == 0) break; if (reduce_count[index] < reduce_count[-1]) break; fprintf (stderr, "rule %d, line %d, count = %d\n", index, yyrline[index], reduce_count[index]); } fprintf (stderr, "\n");#endif#endif}/* Sets the value of the 'yydebug' variable to VALUE. This is a function so we don't have to have YYDEBUG defined in order to build the compiler. */voidset_yydebug (value) int value;{#if YYDEBUG != 0 yydebug = value;#else warning ("YYDEBUG not defined.");#endif}#ifdef SPEW_DEBUGconst char *debug_yytranslate (value) int value;{ return yytname[YYTRANSLATE (value)];}#endif/* Functions and data structures for #pragma interface. `#pragma implementation' means that the main file being compiled is considered to implement (provide) the classes that appear in its main body. I.e., if this is file "foo.cc", and class `bar' is defined in "foo.cc", then we say that "foo.cc implements bar". All main input files "implement" themselves automagically. `#pragma interface' means that unless this file (of the form "foo.h" is not presently being included by file "foo.cc", the CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none of the vtables nor any of the inline functions defined in foo.h will ever be output. There are cases when we want to link files such as "defs.h" and "main.cc". In this case, we give "defs.h" a `#pragma interface', and "main.cc" has `#pragma implementation "defs.h"'. */struct impl_files{ char *filename; struct impl_files *next;};static struct impl_files *impl_file_chain;/* Helper function to load global variables with interface information. */voidextract_interface_info (){ tree fileinfo = get_time_identifier (input_filename); fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo); interface_only = TREE_INT_CST_LOW (fileinfo); interface_unknown = TREE_INT_CST_HIGH (fileinfo);}/* Return nonzero if S and T are not considered part of an INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */static intinterface_strcmp (s) char *s;{ /* Set the interface/implementation bits for this scope. */ struct impl_files *ifiles; char *s1; s = FILE_NAME_NONDIRECTORY (s); for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) { char *t1 = ifiles->filename; s1 = s; if (*s1 != *t1 || *s1 == 0) continue; while (*s1 == *t1 && *s1 != 0) s1++, t1++; /* A match. */ if (*s1 == *t1) return 0; /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ if (index (s1, '.') || index (t1, '.')) continue; if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') continue; /* A match. */ return 0; } /* No matches. */ return 1;}voidset_typedecl_interface_info (prev, vars) tree prev, vars;{ tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); tree fileinfo = IDENTIFIER_CLASS_VALUE (id); tree type = TREE_TYPE (vars); CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) = interface_strcmp (DECL_SOURCE_FILE (vars));}voidset_vardecl_interface_info (prev, vars) tree prev, vars;{ tree type = DECL_CONTEXT (vars); if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0) { if (CLASSTYPE_INTERFACE_ONLY (type)) set_typedecl_interface_info (prev, TYPE_NAME (type)); else CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); TREE_PUBLIC (vars) = 1; }}/* Called from the top level: if there are any pending inlines to do, set up to process them now. */voiddo_pending_inlines (){ struct pending_inline *prev = 0, *tail; struct pending_inline *t; /* Reverse the pending inline functions, since they were cons'd instead of appended. */ for (t = pending_inlines; t; t = tail) { t->deja_vu = 1; tail = t->next; t->next = prev; prev = t; } /* Reset to zero so that if the inline functions we are currently processing define inline functions of their own, that is handled correctly. ??? This hasn't been checked in a while. */ pending_inlines = 0; /* Now start processing the first inline function. */ t = prev; my_friendly_assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE), 226); if (t->parm_vec) push_template_decls (t->parm_vec, t->bindings, 0); if (t->len > 0) { feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0); lineno = t->lineno;#if 0 if (input_filename != t->filename) { input_filename = t->filename; /* Get interface/implementation back in sync. */ extract_interface_info (); }#else input_filename = t->filename; interface_unknown = t->interface == 1; interface_only = t->interface == 0;#endif yychar = PRE_PARSED_FUNCTION_DECL; } /* Pass back a handle on the rest of the inline functions, so that they can be processed later. */ yylval.ttype = build_tree_list ((tree) t, t->fndecl); if (flag_default_inline && t->fndecl /* If we're working from a template, don't change the `inline' state. */ && t->parm_vec == NULL_TREE) DECL_INLINE (t->fndecl) = 1; DECL_PENDING_INLINE_INFO (t->fndecl) = 0;}extern struct pending_input *to_be_restored;static int nextchar = -1;voidprocess_next_inline (t) tree t;{ struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE), 227); if (i->parm_vec) pop_template_decls (i->parm_vec, i->bindings, 0); i = i->next; if (yychar == YYEMPTY) yychar = yylex (); if (yychar != END_OF_SAVED_INPUT) { error ("parse error at end of saved function text"); /* restore_pending_input will abort unless yychar is either * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're * hosed, feed back YYEMPTY. * We also need to discard nextchar, since that may have gotten * set as well. */ nextchar = -1; } yychar = YYEMPTY; if (to_be_restored == 0) my_friendly_abort (123); restore_pending_input (to_be_restored); to_be_restored = 0; if (i && i->fndecl != NULL_TREE) { my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE), 228); if (i->parm_vec) push_template_decls (i->parm_vec, i->bindings, 0); feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0); lineno = i->lineno; input_filename = i->filename; yychar = PRE_PARSED_FUNCTION_DECL; yylval.ttype = build_tree_list ((tree) i, i->fndecl); if (flag_default_inline /* If we're working from a template, don't change the `inline' state. */ && i->parm_vec == NULL_TREE) DECL_INLINE (i->fndecl) = 1; DECL_PENDING_INLINE_INFO (i->fndecl) = 0; } if (i) { interface_unknown = i->interface == 1; interface_only = i->interface == 0; } else extract_interface_info ();}/* Since inline methods can refer to text which has not yet been seen, we store the text of the method in a structure which is placed in the DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. After parsing the body of the class definition, the FUNCTION_DECL's are scanned to see which ones have this field set. Those are then digested one at a time. This function's FUNCTION_DECL will have a bit set in its common so that we know to watch out for it. */voidconsume_string (this_obstack) register struct obstack *this_obstack;{ register char c; do { c = getch (); if (c == '\\') { obstack_1grow (this_obstack, c); c = getch (); obstack_1grow (this_obstack, c); continue; } if (c == '\n') { if (pedantic) pedwarn ("ANSI C++ forbids newline in string constant"); lineno++; } obstack_1grow (this_obstack, c); } while (c != '\"');}static int nextyychar = YYEMPTY;static YYSTYPE nextyylval;struct pending_input { int nextchar, yychar, nextyychar, eof; YYSTYPE yylval, nextyylval; struct obstack token_obstack; int first_token;};struct pending_input *save_pending_input (){ struct pending_input *p; p = (struct pending_input *) xmalloc (sizeof (struct pending_input)); p->nextchar = nextchar; p->yychar = yychar; p->nextyychar = nextyychar; p->yylval = yylval; p->nextyylval = nextyylval; p->eof = end_of_file; yychar = nextyychar = YYEMPTY; nextchar = -1; p->first_token = first_token; p->token_obstack = token_obstack; first_token = 0; gcc_obstack_init (&token_obstack); end_of_file = 0; return p;}voidrestore_pending_input (p) struct pending_input *p;{ my_friendly_assert (nextchar == -1, 229); nextchar = p->nextchar; my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); yychar = p->yychar; my_friendly_assert (nextyychar == YYEMPTY, 231); nextyychar = p->nextyychar; yylval = p->yylval; nextyylval = p->nextyylval; first_token = p->first_token; obstack_free (&token_obstack, (char *) 0); token_obstack = p->token_obstack; end_of_file = p->eof; free (p);}/* Return next non-whitespace input character, which may come from `finput', or from `nextchar'. */static intyynextch (){ int c; if (nextchar >= 0) { c = nextchar; nextchar = -1; } else c = getch (); return skip_white_space (c);}/* Unget character CH from the input stream. If RESCAN is non-zero, then we want to `see' this character as the next input token. */voidyyungetc (ch, rescan) int ch; int rescan;{ /* Unget a character from the input stream. */ if (yychar == YYEMPTY || rescan == 0) { if (nextchar >= 0) put_back (nextchar); nextchar = ch; } else { my_friendly_assert (nextyychar == YYEMPTY, 232); nextyychar = yychar; nextyylval = yylval; yychar = ch; }}/* This function stores away the text for an inline function that should be processed later. It decides how much later, and may need to move the info between obstacks; therefore, the caller should not refer to the T parameter after calling this function. This function also stores the list of template-parameter bindings that will be needed for expanding the template, if any. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -