📄 cp-lex.c
字号:
case '\r': case '\v': case '\b': do c = getch (); while (c == ' ' || c == '\t'); break; case '\\': c = getch (); if (c == '\n') lineno++; else error ("stray '\\' in program"); c = getch (); break; default: return (c); } }}/* Make the token buffer longer, preserving the data in it. P should point to just beyond the last valid character in the old buffer. The value we return is a pointer to the new buffer at a place corresponding to P. */static char *extend_token_buffer (p) char *p;{ int offset = p - token_buffer; maxtoken = maxtoken * 2 + 10; token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); return token_buffer + offset;}static intget_last_nonwhite_on_line (){ register int c; /* Is this the last nonwhite stuff on the line? */ if (nextchar >= 0) c = nextchar, nextchar = -1; else c = getch (); while (c == ' ' || c == '\t') c = getch (); return c;}/* At the beginning of a line, increment the line number and process any #-directive on this line. If the line is a #-directive, read the entire line and return a newline. Otherwise, return the line's first non-whitespace character. */intcheck_newline (){ register int c; register int token; lineno++; /* Read first nonwhite char on the line. */ do c = getch (); while (c == ' ' || c == '\t'); if (c != '#') { /* If not #, return it so caller will use it. */ return c; } /* Read first nonwhite char after the `#'. */ do c = getch (); while (c == ' ' || c == '\t'); /* If a letter follows, then if the word here is `line', skip it and ignore it; otherwise, ignore the line, with an error if the word isn't `pragma'. */ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { if (c == 'p') { if (getch () == 'r' && getch () == 'a' && getch () == 'g' && getch () == 'm' && getch () == 'a') { /* Read first nonwhite char after the `#pragma'. */ do c = getch (); while (c == ' ' || c == '\t'); if (c == 'v' && getch () == 't' && getch () == 'a' && getch () == 'b' && getch () == 'l' && getch () == 'e' && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) { extern tree pending_vtables; /* More follows: it must be a string constant (class name). */ token = real_yylex (); if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { error ("invalid #pragma vtable"); goto skipline; } if (write_virtuals != 2) { warning ("use `+e2' option to enable #pragma vtable"); goto skipline; } pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables); if (nextchar < 0) nextchar = getch (); c = nextchar; if (c != '\n') warning ("trailing characters ignored"); } else if (c == 'u' && getch () == 'n' && getch () == 'i' && getch () == 't' && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) { /* More follows: it must be a string constant (unit name). */ token = real_yylex (); if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { error ("invalid #pragma unit"); goto skipline; } current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype)); current_unit_language = current_lang_name; if (nextchar < 0) nextchar = getch (); c = nextchar; if (c != '\n') warning ("trailing characters ignored"); } else if (c == 'i') { tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); c = getch (); if (c == 'n' && getch () == 't' && getch () == 'e' && getch () == 'r' && getch () == 'f' && getch () == 'a' && getch () == 'c' && getch () == 'e' && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) { /* read to newline. */ while (c != '\n') c = getch (); write_virtuals = 3; if (impl_file_chain == 0) { char *filename; tree fi; /* If this is zero at this point, then we are auto-implementing. */ if (main_input_filename == 0) main_input_filename = input_filename; filename = FILE_NAME_NONDIRECTORY (main_input_filename); fi = get_time_identifier (filename); fi = IDENTIFIER_CLASS_VALUE (fi); TREE_INT_CST_LOW (fi) = 0; TREE_INT_CST_HIGH (fi) = 1; /* Get default. */ impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); impl_file_chain->filename = filename; impl_file_chain->next = 0; } interface_only = interface_strcmp (input_filename); interface_unknown = 0; TREE_INT_CST_LOW (fileinfo) = interface_only; TREE_INT_CST_HIGH (fileinfo) = interface_unknown; } else if (c == 'm' && getch () == 'p' && getch () == 'l' && getch () == 'e' && getch () == 'm' && getch () == 'e' && getch () == 'n' && getch () == 't' && getch () == 'a' && getch () == 't' && getch () == 'i' && getch () == 'o' && getch () == 'n' && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) { char *main_filename = main_input_filename ? main_input_filename : input_filename; while (c == ' ' || c == '\t') c = getch (); if (c != '\n') { put_back (c); token = real_yylex (); if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { error ("invalid `#pragma implementation'"); goto skipline; } main_filename = TREE_STRING_POINTER (yylval.ttype); } main_filename = FILE_NAME_NONDIRECTORY (main_filename); /* read to newline. */ while (c != '\n') c = getch (); if (write_virtuals == 3) { struct impl_files *ifiles = impl_file_chain; while (ifiles) { if (! strcmp (ifiles->filename, main_filename)) break; ifiles = ifiles->next; } if (ifiles == 0) { ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files)); ifiles->filename = main_filename; ifiles->next = impl_file_chain; impl_file_chain = ifiles; } } else if ((main_input_filename != 0 && ! strcmp (main_input_filename, input_filename)) || ! strcmp (input_filename, main_filename)) { write_virtuals = 3; if (impl_file_chain == 0) { impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files)); impl_file_chain->filename = main_filename; impl_file_chain->next = 0; } } else error ("`#pragma implementation' can only appear at top-level"); interface_only = 0; /* We make this non-zero so that we infer decl linkage in the impl file only for variables first declared in the interface file. */ interface_unknown = 1; TREE_INT_CST_LOW (fileinfo) = interface_only; TREE_INT_CST_HIGH (fileinfo) = interface_unknown; } } } goto skipline; } else if (c == 'd') { if (getch () == 'e' && getch () == 'f' && getch () == 'i' && getch () == 'n' && getch () == 'e' && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) {#ifdef DWARF_DEBUGGING_INFO if ((debug_info_level == DINFO_LEVEL_VERBOSE) && (write_symbols == DWARF_DEBUG)) dwarfout_define (lineno, get_directive_line (finput));#endif /* DWARF_DEBUGGING_INFO */ goto skipline; } } else if (c == 'u') { if (getch () == 'n' && getch () == 'd' && getch () == 'e' && getch () == 'f' && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) {#ifdef DWARF_DEBUGGING_INFO if ((debug_info_level == DINFO_LEVEL_VERBOSE) && (write_symbols == DWARF_DEBUG)) dwarfout_undef (lineno, get_directive_line (finput));#endif /* DWARF_DEBUGGING_INFO */ goto skipline; } } else if (c == 'l') { if (getch () == 'i' && getch () == 'n' && getch () == 'e' && ((c = getch ()) == ' ' || c == '\t')) goto linenum; } else if (c == 'i') { if (getch () == 'd' && getch () == 'e' && getch () == 'n' && getch () == 't' && ((c = getch ()) == ' ' || c == '\t')) {#ifdef ASM_OUTPUT_IDENT extern FILE *asm_out_file;#endif /* #ident. The pedantic warning is now in cccp.c. */ /* Here we have just seen `#ident '. A string constant should follow. */ while (c == ' ' || c == '\t') c = getch (); /* If no argument, ignore the line. */ if (c == '\n') return c; put_back (c); token = real_yylex (); if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { error ("invalid #ident"); goto skipline; } if (! flag_no_ident) {#ifdef ASM_OUTPUT_IDENT ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));#endif } /* Skip the rest of this line. */ goto skipline; } } else if (c == 'n') { if (getch () == 'e' && getch () == 'w' && getch () == 'w' && getch () == 'o' && getch () == 'r' && getch () == 'l' && getch () == 'd' && ((c = getch ()) == ' ' || c == '\t')) { /* Used to test incremental compilation. */ sorry ("#pragma newworld"); goto skipline; } } error ("undefined or invalid # directive"); goto skipline; }linenum: /* Here we have either `#line' or `# <nonletter>'. In either case, it should be a line number; a digit should follow. */ while (c == ' ' || c == '\t') c = getch (); /* If the # is the only nonwhite char on the line, just ignore it. Check the new newline. */ if (c == '\n') return c; /* Something follows the #; read a token. */ put_back (c); token = real_yylex (); if (token == CONSTANT && TREE_CODE (yylval.ttype) == INTEGER_CST) { int old_lineno = lineno; int used_up = 0; /* subtract one, because it is the following line that gets the specified number */ int l = TREE_INT_CST_LOW (yylval.ttype) - 1; c = get_last_nonwhite_on_line (); if (c == '\n') { /* No more: store the line number and check following line. */ lineno = l; return c; } put_back (c); /* More follows: it must be a string constant (filename). */ /* Read the string constant, but don't treat \ as special. */ ignore_escape_flag = 1; token = real_yylex (); ignore_escape_flag = 0; if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { error ("invalid #line"); goto skipline; } /* Changing files again. This means currently collected
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -