📄 lex.c
字号:
}/* 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. */static voidstore_pending_inline (decl, t) tree decl; struct pending_inline *t;{ t->fndecl = decl; DECL_PENDING_INLINE_INFO (decl) = t; /* Because we use obstacks, we must process these in precise order. */ t->next = pending_inlines; pending_inlines = t;}voidreinit_parse_for_method (yychar, decl) int yychar; tree decl;{ int len; int starting_lineno = lineno; char *starting_filename = input_filename; reinit_parse_for_block (yychar, &inline_text_obstack); len = obstack_object_size (&inline_text_obstack); current_base_init_list = NULL_TREE; current_member_init_list = NULL_TREE; if (decl == void_type_node || (current_class_type && TYPE_REDEFINED (current_class_type))) { /* Happens when we get two declarations of the same function in the same scope. */ char *buf = obstack_finish (&inline_text_obstack); obstack_free (&inline_text_obstack, buf); return; } else { struct pending_inline *t; char *buf = obstack_finish (&inline_text_obstack); t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, sizeof (struct pending_inline)); t->lineno = starting_lineno; t->filename = starting_filename; t->token = YYEMPTY; t->token_value = 0; t->buf = buf; t->len = len; t->deja_vu = 0;#if 0 if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) warn_if_unknown_interface (decl);#endif t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); store_pending_inline (decl, t); }}/* Consume a block -- actually, a method beginning with `:' or `{' -- and save it away on the specified obstack. */voidreinit_parse_for_block (pyychar, obstackp) int pyychar; struct obstack *obstackp;{ register int c = 0; int blev = 1; int starting_lineno = lineno; char *starting_filename = input_filename; int len; int look_for_semicolon = 0; int look_for_lbrac = 0; if (pyychar == '{') obstack_1grow (obstackp, '{'); else if (pyychar == '=') look_for_semicolon = 1; else if (pyychar == ':') { obstack_1grow (obstackp, pyychar); /* Add a space so we don't get confused by ': ::A(20)'. */ obstack_1grow (obstackp, ' '); look_for_lbrac = 1; blev = 0; } else if (pyychar == RETURN_KEYWORD) { obstack_grow (obstackp, "return", 6); look_for_lbrac = 1; blev = 0; } else if (pyychar == TRY) { obstack_grow (obstackp, "try", 3); look_for_lbrac = 1; blev = 0; } else { yyerror ("parse error in method specification"); obstack_1grow (obstackp, '{'); } if (nextchar != EOF) { c = nextchar; nextchar = EOF; } else c = getch (); while (c != EOF) { int this_lineno = lineno; c = skip_white_space (c); /* Don't lose our cool if there are lots of comments. */ if (lineno == this_lineno + 1) obstack_1grow (obstackp, '\n'); else if (lineno == this_lineno) ; else if (lineno - this_lineno < 10) { int i; for (i = lineno - this_lineno; i > 0; i--) obstack_1grow (obstackp, '\n'); } else { char buf[16]; sprintf (buf, "\n# %d \"", lineno); len = strlen (buf); obstack_grow (obstackp, buf, len); len = strlen (input_filename); obstack_grow (obstackp, input_filename, len); obstack_1grow (obstackp, '\"'); obstack_1grow (obstackp, '\n'); } while (c > ' ') /* ASCII dependent... */ { obstack_1grow (obstackp, c); if (c == '{') { look_for_lbrac = 0; blev++; } else if (c == '}') { blev--; if (blev == 0 && !look_for_semicolon) { if (pyychar == TRY) { if (peekyylex () == CATCH) { yylex (); obstack_grow (obstackp, " catch ", 7); look_for_lbrac = 1; } else { yychar = '{'; goto done; } } else { goto done; } } } else if (c == '\\') { /* Don't act on the next character...e.g, doing an escaped double-quote. */ c = getch (); if (c == EOF) { error_with_file_and_line (starting_filename, starting_lineno, "end of file read inside definition"); goto done; } obstack_1grow (obstackp, c); } else if (c == '\"') consume_string (obstackp, c); else if (c == '\'') consume_string (obstackp, c); else if (c == ';') { if (look_for_lbrac) { error ("function body for constructor missing"); obstack_1grow (obstackp, '{'); obstack_1grow (obstackp, '}'); len += 2; goto done; } else if (look_for_semicolon && blev == 0) goto done; } c = getch (); } if (c == EOF) { error_with_file_and_line (starting_filename, starting_lineno, "end of file read inside definition"); goto done; } else if (c != '\n') { obstack_1grow (obstackp, c); c = getch (); } } done: obstack_1grow (obstackp, '\0');}/* Consume a no-commas expression -- actually, a default argument -- and save it away on the specified obstack. */static voidreinit_parse_for_expr (obstackp) struct obstack *obstackp;{ register int c = 0; int starting_lineno = lineno; char *starting_filename = input_filename; int len; int plev = 0; if (nextchar != EOF) { c = nextchar; nextchar = EOF; } else c = getch (); while (c != EOF) { int this_lineno = lineno; c = skip_white_space (c); /* Don't lose our cool if there are lots of comments. */ if (lineno == this_lineno + 1) obstack_1grow (obstackp, '\n'); else if (lineno == this_lineno) ; else if (lineno - this_lineno < 10) { int i; for (i = lineno - this_lineno; i > 0; --i) obstack_1grow (obstackp, '\n'); } else { char buf[16]; sprintf (buf, "\n# %d \"", lineno); len = strlen (buf); obstack_grow (obstackp, buf, len); len = strlen (input_filename); obstack_grow (obstackp, input_filename, len); obstack_1grow (obstackp, '\"'); obstack_1grow (obstackp, '\n'); } while (c > ' ') /* ASCII dependent... */ { if (plev <= 0 && (c == ')' || c == ',')) { put_back (c); goto done; } obstack_1grow (obstackp, c); if (c == '(' || c == '[') ++plev; else if (c == ']' || c == ')') --plev; else if (c == '\\') { /* Don't act on the next character...e.g, doing an escaped double-quote. */ c = getch (); if (c == EOF) { error_with_file_and_line (starting_filename, starting_lineno, "end of file read inside definition"); goto done; } obstack_1grow (obstackp, c); } else if (c == '\"') consume_string (obstackp, c); else if (c == '\'') consume_string (obstackp, c); c = getch (); } if (c == EOF) { error_with_file_and_line (starting_filename, starting_lineno, "end of file read inside definition"); goto done; } else if (c != '\n') { obstack_1grow (obstackp, c); c = getch (); } } done: obstack_1grow (obstackp, '\0');}int do_snarf_defarg;/* Decide whether the default argument we are about to see should be gobbled up as text for later parsing. */voidmaybe_snarf_defarg (){ if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) do_snarf_defarg = 1;}/* 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. */tree defarg_fns;tree defarg_parm;treesnarf_defarg (){ int len; char *buf; tree arg; reinit_parse_for_expr (&inline_text_obstack); len = obstack_object_size (&inline_text_obstack); buf = obstack_finish (&inline_text_obstack); push_obstacks (&inline_text_obstack, &inline_text_obstack); arg = make_node (DEFAULT_ARG); DEFARG_LENGTH (arg) = len - 1; DEFARG_POINTER (arg) = buf; pop_obstacks (); return arg;}/* Called from grokfndecl to note a function decl with unparsed default arguments for later processing. Also called from grokdeclarator for function types with unparsed defargs; the call from grokfndecl will always come second, so we can overwrite the entry from the type. */voidadd_defarg_fn (decl) tree decl;{ if (TREE_CODE (decl) == FUNCTION_DECL) TREE_VALUE (defarg_fns) = decl; else { push_obstacks (&inline_text_obstack, &inline_text_obstack); defarg_fns = tree_cons (current_class_type, decl, defarg_fns); pop_obstacks (); }}/* Helper for do_pending_defargs. Starts the parsing of a default arg. */static voidfeed_defarg (f, p) tree f, p;{ tree d = TREE_PURPOSE (p); feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d)); if (TREE_CODE (f) == FUNCTION_DECL) { lineno = DECL_SOURCE_LINE (f); input_filename = DECL_SOURCE_FILE (f); } yychar = DEFARG_MARKER; yylval.ttype = p;}/* Helper for do_pending_defargs. Ends the parsing of a default arg. */static voidfinish_defarg (){ 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; end_input ();} /* Main function for deferred parsing of default arguments. Called from the parser. */voiddo_pending_defargs (){ if (defarg_parm) finish_defarg (); for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns)) { tree defarg_fn = TREE_VALUE (defarg_fns); if (defarg_parm == NULL_TREE) { push_nested_class (TREE_PURPOSE (defarg_fns), 1); pushlevel (0); if (TREE_CODE (defarg_fn) == FUNCTION_DECL) maybe_begin_member_template_processing (defarg_fn); if (TREE_CODE (defarg_fn) == FUNCTION_DECL) {#if 0 tree p; for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p)) pushdecl (copy_node (p));#endif defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn)); } else defarg_parm = TYPE_ARG_TYPES (defarg_fn); } else defarg_parm = TREE_CHAIN (defarg_parm); for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -