diff options
Diffstat (limited to 'gcc/cp/lex.c')
-rw-r--r-- | gcc/cp/lex.c | 4099 |
1 files changed, 447 insertions, 3652 deletions
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 94679b4c718..1d6ca77168c 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -31,10 +31,11 @@ Boston, MA 02111-1307, USA. */ #include "input.h" #include "tree.h" #include "cp-tree.h" +#include "cpplib.h" +#include "c-lex.h" #include "lex.h" #include "parse.h" #include "flags.h" -#include "obstack.h" #include "c-pragma.h" #include "toplev.h" #include "output.h" @@ -48,98 +49,57 @@ Boston, MA 02111-1307, USA. */ #include <locale.h> #endif -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); -static tree get_time_identifier PARAMS ((const char *)); -static int check_newline PARAMS ((void)); -static int whitespace_cr PARAMS ((int)); -static int skip_white_space PARAMS ((int)); -static void finish_defarg PARAMS ((void)); static int interface_strcmp PARAMS ((const char *)); -static int readescape PARAMS ((int *)); -static char *extend_token_buffer PARAMS ((const char *)); -static void consume_string PARAMS ((struct obstack *, int)); -static void feed_defarg PARAMS ((tree, tree)); -static void store_pending_inline PARAMS ((tree, struct pending_inline *)); -static void reinit_parse_for_expr PARAMS ((struct obstack *)); static int *init_cpp_parse PARAMS ((void)); -static void cp_pragma_interface PARAMS ((const char *)); -static void cp_pragma_implementation PARAMS ((const char *)); -static int handle_cp_pragma PARAMS ((const char *)); -#ifdef HANDLE_GENERIC_PRAGMAS -static int handle_generic_pragma PARAMS ((int)); -#endif +static void init_reswords PARAMS ((void)); +static void init_cp_pragma PARAMS ((void)); +static void mark_impl_file_chain PARAMS ((PTR)); + +static tree parse_strconst_pragma PARAMS ((const char *, int)); +static void handle_pragma_vtable PARAMS ((cpp_reader *)); +static void handle_pragma_unit PARAMS ((cpp_reader *)); +static void handle_pragma_interface PARAMS ((cpp_reader *)); +static void handle_pragma_implementation PARAMS ((cpp_reader *)); + #ifdef GATHER_STATISTICS #ifdef REDUCE_LENGTH static int reduce_cmp PARAMS ((int *, int *)); static int token_cmp PARAMS ((int *, int *)); #endif #endif -static void begin_definition_of_inclass_inline PARAMS ((struct pending_inline*)); -static void parse_float PARAMS ((PTR)); static int is_global PARAMS ((tree)); -static void init_filename_times PARAMS ((void)); -static void extend_token_buffer_to PARAMS ((int)); -#ifdef HANDLE_PRAGMA -static int pragma_getc PARAMS ((void)); -static void pragma_ungetc PARAMS ((int)); -#endif -static int read_line_number PARAMS ((int *)); -static int token_getch PARAMS ((void)); -static void token_put_back PARAMS ((int)); -static void mark_impl_file_chain PARAMS ((void *)); -static int read_ucs PARAMS ((int)); -static int is_extended_char PARAMS ((int)); -static int is_extended_char_1 PARAMS ((int)); static void init_operators PARAMS ((void)); -/* This obstack is needed to hold text. It is not safe to use - TOKEN_BUFFER because `check_newline' calls `yylex'. */ -struct obstack inline_text_obstack; -char *inline_text_firstobj; - -/* Nonzero if parse output is being saved to an obstack for later parsing. */ -static int saving_parse_to_obstack = 0; +/* A constraint that can be tested at compile time. */ +#ifdef __STDC__ +#define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1] +#else +#define CONSTRAINT(name, expr) extern int constraint_/**/name [(expr) ? 1 : -1] +#endif -#if USE_CPPLIB #include "cpplib.h" +#if USE_CPPLIB extern cpp_reader parse_in; -extern cpp_options parse_options; -extern unsigned char *yy_cur, *yy_lim; -extern enum cpp_token cpp_token; #else FILE *finput; -#endif -int end_of_file; int linemode; +#endif /* Pending language change. Positive is push count, negative is pop count. */ int pending_lang_change = 0; -/* Wrap the current header file in extern "C". */ -static int c_header_level = 0; - -extern int first_token; -extern struct obstack token_obstack; - -/* ??? Don't really know where this goes yet. */ -#include "input.c" - - extern int yychar; /* the lookahead symbol */ extern YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ -#if 0 -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - +/* These flags are used by c-lex.c. In C++, they're always off and on, + respectively. */ +int warn_traditional = 0; +int flag_digraphs = 1; /* the declaration found for the last IDENTIFIER token read in. yylex must look this up to detect typedefs, which get token type TYPENAME, @@ -147,24 +107,9 @@ YYLTYPE yylloc; /* location data for the lookahead */ used in a context which makes it a reference to a variable. */ tree lastiddecl; -/* We may keep statistics about how long which files took to compile. */ -static int header_time, body_time; -static tree filename_times; -static tree this_filename_time; - /* Array for holding counts of the numbers of tokens seen. */ extern int *token_count; -/* 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. */ - -static tree defarg_fns; -static tree defarg_parm; - /* Functions and data structures for #pragma interface. `#pragma implementation' means that the main file being compiled @@ -255,9 +200,6 @@ make_call_declarator (target, parms, cv_qualifiers, exception_specification) tree target, parms, cv_qualifiers, exception_specification; { target = build_parse_node (CALL_EXPR, target, - /* Both build_parse_node and - decl_tree_cons build on the - temp_decl_obstack. */ decl_tree_cons (parms, cv_qualifiers, NULL_TREE), /* The third operand is really RTL. We shouldn't put anything there. */ @@ -279,49 +221,6 @@ int interface_only; /* whether or not current file is only for int interface_unknown; /* whether or not we know this class to behave according to #pragma interface. */ -/* lexical analyzer */ - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node) - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. */ - -static int indent_level; /* Number of { minus number of }. */ - -#include "hash.h" - - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag; - -static tree -get_time_identifier (name) - const char *name; -{ - tree time_identifier; - int len = strlen (name); - char *buf = (char *) alloca (len + 6); - strcpy (buf, "file "); - bcopy (name, buf+5, len); - buf[len+5] = '\0'; - time_identifier = get_identifier (buf); - if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE) - { - TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0); - TIME_IDENTIFIER_FILEINFO (time_identifier) - = build_int_2 (0, 1); - SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times); - filename_times = time_identifier; - } - return time_identifier; -} - - /* Tree code classes. */ #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, @@ -360,10 +259,8 @@ void lang_init_options () { #if USE_CPPLIB + cpp_init (); cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); - parse_options.cplusplus = 1; #endif /* Default exceptions on. */ @@ -385,10 +282,13 @@ lang_init () if (flag_bounds_check < 0) flag_bounds_check = flag_bounded_pointers; +#if !USE_CPPLIB /* the beginning of the file is a new line; check for # */ /* With luck, we discover the real source file's name from that and put it in input_filename. */ - put_back (check_newline ()); + ungetc (check_newline (), finput); +#endif + if (flag_gnu_xref) GNU_xref_begin (input_filename); init_repo (input_filename); } @@ -405,19 +305,6 @@ lang_identify () return "cplusplus"; } -static void -init_filename_times () -{ - this_filename_time = get_time_identifier ("<top level>"); - if (flag_detailed_statistics) - { - header_time = 0; - body_time = get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - = body_time; - } -} - static int * init_cpp_parse () { @@ -439,6 +326,11 @@ operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE]; /* Initialize data structures that keep track of operator names. */ +#define DEF_OPERATOR(NAME, C, NM, OM, AR, AP) \ + CONSTRAINT (C, sizeof "operator " + sizeof NAME <= 256); +#include "operators.def" +#undef DEF_OPERATOR + static void init_operators () { @@ -447,9 +339,6 @@ init_operators () struct operator_name_info_t *oni; #define DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY, ASSN_P) \ - my_friendly_assert ((strlen ("operator ") + strlen (NAME) + 1 \ - + ISALPHA (NAME[0]) <= 256), \ - 20000526); \ sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \ identifier = get_identifier (buffer); \ IDENTIFIER_OPNAME_P (identifier) = 1; \ @@ -507,57 +396,326 @@ init_operators () = "(round %=)"; } -const char * -init_parse (filename) - const char *filename; +/* The reserved keyword table. */ +struct resword { - extern int flag_no_gnu_keywords; - extern int flag_operator_names; + const char *word; + ENUM_BITFIELD(rid) rid : 16; + unsigned int disable : 16; +}; -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); - literal_codeset = getenv ("LANG"); -#endif +/* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is + _true_. */ +#define D_EXT 0x01 /* GCC extension */ +#define D_ASM 0x02 /* in C99, but has a switch to turn it off */ +#define D_OPNAME 0x04 /* operator names */ + +CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT); + +static const struct resword reswords[] = +{ + { "__alignof", RID_ALIGNOF, 0 }, + { "__alignof__", RID_ALIGNOF, 0 }, + { "__asm", RID_ASM, 0 }, + { "__asm__", RID_ASM, 0 }, + { "__attribute", RID_ATTRIBUTE, 0 }, + { "__attribute__", RID_ATTRIBUTE, 0 }, + { "__builtin_va_arg", RID_VA_ARG, 0 }, + { "__complex", RID_COMPLEX, 0 }, + { "__complex__", RID_COMPLEX, 0 }, + { "__const", RID_CONST, 0 }, + { "__const__", RID_CONST, 0 }, + { "__extension__", RID_EXTENSION, 0 }, + { "__imag", RID_IMAGPART, 0 }, + { "__imag__", RID_IMAGPART, 0 }, + { "__inline", RID_INLINE, 0 }, + { "__inline__", RID_INLINE, 0 }, + { "__label__", RID_LABEL, 0 }, + { "__null", RID_NULL, 0 }, + { "__real", RID_REALPART, 0 }, + { "__real__", RID_REALPART, 0 }, + { "__restrict", RID_RESTRICT, 0 }, + { "__restrict__", RID_RESTRICT, 0 }, + { "__signed", RID_SIGNED, 0 }, + { "__signed__", RID_SIGNED, 0 }, + { "__typeof", RID_TYPEOF, 0 }, + { "__typeof__", RID_TYPEOF, 0 }, + { "__volatile", RID_VOLATILE, 0 }, + { "__volatile__", RID_VOLATILE, 0 }, + { "__wchar_t", RID_WCHAR, 0 }, + { "asm", RID_ASM, D_ASM }, + { "and", RID_AND, D_OPNAME }, + { "and_eq", RID_AND_EQ, D_OPNAME }, + { "auto", RID_AUTO, 0 }, + { "bitand", RID_BITAND, D_OPNAME }, + { "bitor", RID_BITOR, D_OPNAME }, + { "bool", RID_BOOL, 0 }, + { "break", RID_BREAK, 0 }, + { "case", RID_CASE, 0 }, + { "catch", RID_CATCH, 0 }, + { "char", RID_CHAR, 0 }, + { "class", RID_CLASS, 0 }, + { "compl", RID_COMPL, D_OPNAME }, + { "const", RID_CONST, 0 }, + { "const_cast", RID_CONSTCAST, 0 }, + { "continue", RID_CONTINUE, 0 }, + { "default", RID_DEFAULT, 0 }, + { "delete", RID_DELETE, 0 }, + { "do", RID_DO, 0 }, + { "double", RID_DOUBLE, 0 }, + { "dynamic_cast", RID_DYNCAST, 0 }, + { "else", RID_ELSE, 0 }, + { "enum", RID_ENUM, 0 }, + { "explicit", RID_EXPLICIT, 0 }, + { "export", RID_EXPORT, 0 }, + { "extern", RID_EXTERN, 0 }, + { "false", RID_FALSE, 0 }, + { "float", RID_FLOAT, 0 }, + { "for", RID_FOR, 0 }, + { "friend", RID_FRIEND, 0 }, + { "goto", RID_GOTO, 0 }, + { "if", RID_IF, 0 }, + { "inline", RID_INLINE, 0 }, + { "int", RID_INT, 0 }, + { "long", RID_LONG, 0 }, + { "mutable", RID_MUTABLE, 0 }, + { "namespace", RID_NAMESPACE, 0 }, + { "new", RID_NEW, 0 }, + { "not", RID_NOT, D_OPNAME }, + { "not_eq", RID_NOT_EQ, D_OPNAME }, + { "operator", RID_OPERATOR, 0 }, + { "or", RID_OR, D_OPNAME }, + { "or_eq", RID_OR_EQ, D_OPNAME }, + { "private", RID_PRIVATE, 0 }, + { "protected", RID_PROTECTED, 0 }, + { "public", RID_PUBLIC, 0 }, + { "register", RID_REGISTER, 0 }, + { "reinterpret_cast", RID_REINTCAST, 0 }, + { "return", RID_RETURN, 0 }, + { "short", RID_SHORT, 0 }, + { "signed", RID_SIGNED, 0 }, + { "sizeof", RID_SIZEOF, 0 }, + { "static", RID_STATIC, 0 }, + { "static_cast", RID_STATCAST, 0 }, + { "struct", RID_STRUCT, 0 }, + { "switch", RID_SWITCH, 0 }, + { "template", RID_TEMPLATE, 0 }, + { "this", RID_THIS, 0 }, + { "throw", RID_THROW, 0 }, + { "true", RID_TRUE, 0 }, + { "try", RID_TRY, 0 }, + { "typedef", RID_TYPEDEF, 0 }, + { "typename", RID_TYPENAME, 0 }, + { "typeid", RID_TYPEID, 0 }, + { "typeof", RID_TYPEOF, D_ASM|D_EXT }, + { "union", RID_UNION, 0 }, + { "unsigned", RID_UNSIGNED, 0 }, + { "using", RID_USING, 0 }, + { "virtual", RID_VIRTUAL, 0 }, + { "void", RID_VOID, 0 }, + { "volatile", RID_VOLATILE, 0 }, + { "while", RID_WHILE, 0 }, + { "xor", RID_XOR, D_OPNAME }, + { "xor_eq", RID_XOR_EQ, D_OPNAME }, -#if !USE_CPPLIB - /* Open input file. */ - if (filename == 0 || !strcmp (filename, "-")) +}; +#define N_reswords (sizeof reswords / sizeof (struct resword)) + +/* Table mapping from RID_* constants to yacc token numbers. + Unfortunately we have to have entries for all the keywords in all + three languages. */ +const short rid_to_yy[RID_MAX] = +{ + /* RID_STATIC */ SCSPEC, + /* RID_UNSIGNED */ TYPESPEC, + /* RID_LONG */ TYPESPEC, + /* RID_CONST */ CV_QUALIFIER, + /* RID_EXTERN */ SCSPEC, + /* RID_REGISTER */ SCSPEC, + /* RID_TYPEDEF */ SCSPEC, + /* RID_SHORT */ TYPESPEC, + /* RID_INLINE */ SCSPEC, + /* RID_VOLATILE */ CV_QUALIFIER, + /* RID_SIGNED */ TYPESPEC, + /* RID_AUTO */ SCSPEC, + /* RID_RESTRICT */ CV_QUALIFIER, + + /* C extensions. Bounded pointers are not yet in C++ */ + /* RID_BOUNDED */ 0, + /* RID_UNBOUNDED */ 0, + /* RID_COMPLEX */ TYPESPEC, + + /* C++ */ + /* RID_FRIEND */ SCSPEC, + /* RID_VIRTUAL */ SCSPEC, + /* RID_EXPLICIT */ SCSPEC, + /* RID_EXPORT */ SCSPEC, + /* RID_MUTABLE */ SCSPEC, + + /* ObjC */ + /* RID_IN */ 0, + /* RID_OUT */ 0, + /* RID_INOUT */ 0, + /* RID_BYCOPY */ 0, + /* RID_BYREF */ 0, + /* RID_ONEWAY */ 0, + + /* C */ + /* RID_INT */ TYPESPEC, + /* RID_CHAR */ TYPESPEC, + /* RID_FLOAT */ TYPESPEC, + /* RID_DOUBLE */ TYPESPEC, + /* RID_VOID */ TYPESPEC, + /* RID_ENUM */ ENUM, + /* RID_STRUCT */ AGGR, + /* RID_UNION */ AGGR, + /* RID_IF */ IF, + /* RID_ELSE */ ELSE, + /* RID_WHILE */ WHILE, + /* RID_DO */ DO, + /* RID_FOR */ FOR, + /* RID_SWITCH */ SWITCH, + /* RID_CASE */ CASE, + /* RID_DEFAULT */ DEFAULT, + /* RID_BREAK */ BREAK, + /* RID_CONTINUE */ CONTINUE, + /* RID_RETURN */ RETURN_KEYWORD, + /* RID_GOTO */ GOTO, + /* RID_SIZEOF */ SIZEOF, + + /* C extensions */ + /* RID_ASM */ ASM_KEYWORD, + /* RID_TYPEOF */ TYPEOF, + /* RID_ALIGNOF */ ALIGNOF, + /* RID_ATTRIBUTE */ ATTRIBUTE, + /* RID_VA_ARG */ VA_ARG, + /* RID_EXTENSION */ EXTENSION, + /* RID_IMAGPART */ IMAGPART, + /* RID_REALPART */ REALPART, + /* RID_LABEL */ LABEL, + /* RID_PTRBASE */ 0, + /* RID_PTREXTENT */ 0, + /* RID_PTRVALUE */ 0, + + /* C++ */ + /* RID_BOOL */ TYPESPEC, + /* RID_WCHAR */ TYPESPEC, + /* RID_CLASS */ AGGR, + /* RID_PUBLIC */ VISSPEC, + /* RID_PRIVATE */ VISSPEC, + /* RID_PROTECTED */ VISSPEC, + /* RID_TEMPLATE */ TEMPLATE, + /* RID_NULL */ CONSTANT, + /* RID_CATCH */ CATCH, + /* RID_DELETE */ DELETE, + /* RID_FALSE */ CXX_FALSE, + /* RID_NAMESPACE */ NAMESPACE, + /* RID_NEW */ NEW, + /* RID_OPERATOR */ OPERATOR, + /* RID_THIS */ THIS, + /* RID_THROW */ THROW, + /* RID_TRUE */ CXX_TRUE, + /* RID_TRY */ TRY, + /* RID_TYPENAME */ TYPENAME_KEYWORD, + /* RID_TYPEID */ TYPEID, + /* RID_USING */ USING, + + /* casts */ + /* RID_CONSTCAST */ CONST_CAST, + /* RID_DYNCAST */ DYNAMIC_CAST, + /* RID_REINTCAST */ REINTERPRET_CAST, + /* RID_STATCAST */ STATIC_CAST, + + /* alternate spellings */ + /* RID_AND */ ANDAND, + /* RID_AND_EQ */ ASSIGN, + /* RID_NOT */ '!', + /* RID_NOT_EQ */ EQCOMPARE, + /* RID_OR */ OROR, + /* RID_OR_EQ */ ASSIGN, + /* RID_XOR */ '^', + /* RID_XOR_EQ */ ASSIGN, + /* RID_BITAND */ '&', + /* RID_BITOR */ '|', + /* RID_COMPL */ '~', + + /* Objective C */ + /* RID_ID */ 0, + /* RID_AT_ENCODE */ 0, + /* RID_AT_END */ 0, + /* RID_AT_CLASS */ 0, + /* RID_AT_ALIAS */ 0, + /* RID_AT_DEFS */ 0, + /* RID_AT_PRIVATE */ 0, + /* RID_AT_PROTECTED */ 0, + /* RID_AT_PUBLIC */ 0, + /* RID_AT_PROTOCOL */ 0, + /* RID_AT_SELECTOR */ 0, + /* RID_AT_INTERFACE */ 0, + /* RID_AT_IMPLEMENTATION */ 0 +}; + +static void +init_reswords () +{ + unsigned int i; + tree id; + int mask = ((flag_operator_names ? 0 : D_OPNAME) + | (flag_no_asm ? D_ASM : 0) + | (flag_no_gnu_keywords ? D_EXT : 0)); + + /* It is not necessary to register ridpointers as a GC root, because + all the trees it points to are permanently interned in the + get_identifier hash anyway. */ + ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); + for (i = 0; i < N_reswords; i++) { - finput = stdin; - filename = "stdin"; + id = get_identifier (reswords[i].word); + C_RID_CODE (id) = reswords[i].rid; + ridpointers [(int) reswords[i].rid] = id; + if (! (reswords[i].disable & mask)) + C_IS_RESERVED_WORD (id) = 1; } - else - finput = fopen (filename, "r"); - if (finput == 0) - pfatal_with_name (filename); +} -#ifdef IO_BUFFER_SIZE - setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); +static void +init_cp_pragma () +{ +#if USE_CPPLIB +#define pfile &parse_in +#else +#define pfile 0 #endif -#else /* !USE_CPPLIB */ - parse_in.show_column = 1; - if (! cpp_start_read (&parse_in, filename)) - abort (); - - if (filename == 0 || !strcmp (filename, "-")) - filename = "stdin"; + cpp_register_pragma (pfile, 0, "vtable", handle_pragma_vtable); + cpp_register_pragma (pfile, 0, "unit", handle_pragma_unit); - /* cpp_start_read always puts at least one line directive into the - token buffer. We must arrange to read it out here. */ - yy_cur = parse_in.token_buffer; - yy_lim = CPP_PWRITTEN (&parse_in); - cpp_token = CPP_DIRECTIVE; + cpp_register_pragma (pfile, 0, "interface", handle_pragma_interface); + cpp_register_pragma (pfile, 0, "implementation", + handle_pragma_implementation); -#endif /* !USE_CPPLIB */ - - /* Initialize the lookahead machinery. */ - init_spew (); + cpp_register_pragma_space (pfile, "GCC"); + cpp_register_pragma (pfile, "GCC", "interface", handle_pragma_interface); + cpp_register_pragma (pfile, "GCC", "implementation", + handle_pragma_implementation); +} +const char * +init_parse (filename) + const char *filename; +{ /* Make identifier nodes long enough for the language-specific slots. */ set_identifier_size (sizeof (struct lang_identifier)); decl_printable_name = lang_printable_name; + internal_filename = ggc_alloc_string (INTERNAL_FILENAME, + sizeof (INTERNAL_FILENAME)); + input_filename = internal_filename; + + init_reswords (); + init_pragma (); + init_cp_pragma (); + + init_spew (); init_tree (); init_cplus_expand (); @@ -576,53 +734,16 @@ init_parse (filename) init_operators (); init_method (); init_error (); - gcc_obstack_init (&inline_text_obstack); - inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); - internal_filename = ggc_alloc_string (INTERNAL_FILENAME, - sizeof (INTERNAL_FILENAME)); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - input_filename = internal_filename; current_function_decl = NULL; - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - my_friendly_assert ((int) CP_RID_MAX < 64, 20000630); - ridpointers = (tree *) xcalloc ((int) CP_RID_MAX, sizeof (tree)); - ridpointers[(int) RID_INT] = get_identifier ("int"); - ridpointers[(int) RID_BOOL] = get_identifier ("bool"); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict"); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex"); - - /* C++ extensions. These are probably not correctly named. */ - ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); class_type_node = build_int_2 (class_type, 0); TREE_TYPE (class_type_node) = class_type_node; ridpointers[(int) RID_CLASS] = class_type_node; record_type_node = build_int_2 (record_type, 0); TREE_TYPE (record_type_node) = record_type_node; - ridpointers[(int) RID_RECORD] = record_type_node; + ridpointers[(int) RID_STRUCT] = record_type_node; union_type_node = build_int_2 (union_type, 0); TREE_TYPE (union_type_node) = union_type_node; @@ -632,18 +753,6 @@ init_parse (filename) TREE_TYPE (enum_type_node) = enum_type_node; ridpointers[(int) RID_ENUM] = enum_type_node; - ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); - ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit"); - ridpointers[(int) RID_EXPORT] = get_identifier ("export"); - ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); - - ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); - ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); - ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); - ridpointers[(int) RID_TEMPLATE] = get_identifier ("template"); - /* This is for ANSI C++. */ - ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); - /* Create the built-in __null node. Note that we can't yet call for type_for_size here because integer_type_node and so forth are not set up. Therefore, we don't set the type of these nodes until @@ -651,61 +760,21 @@ init_parse (filename) null_node = build_int_2 (0, 0); ridpointers[RID_NULL] = null_node; - init_filename_times (); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - -#if 0 - /* let's parse things, and if they use it, then give them an error. */ - if (!flag_exceptions) - { - UNSET_RESERVED_WORD ("throw"); - UNSET_RESERVED_WORD ("try"); - UNSET_RESERVED_WORD ("catch"); - } -#endif - - if (flag_no_asm || flag_no_gnu_keywords) - UNSET_RESERVED_WORD ("typeof"); - if (! flag_operator_names) - { - /* These are new ANSI keywords that may break code. */ - UNSET_RESERVED_WORD ("and"); - UNSET_RESERVED_WORD ("and_eq"); - UNSET_RESERVED_WORD ("bitand"); - UNSET_RESERVED_WORD ("bitor"); - UNSET_RESERVED_WORD ("compl"); - UNSET_RESERVED_WORD ("not"); - UNSET_RESERVED_WORD ("not_eq"); - UNSET_RESERVED_WORD ("or"); - UNSET_RESERVED_WORD ("or_eq"); - UNSET_RESERVED_WORD ("xor"); - UNSET_RESERVED_WORD ("xor_eq"); - } - token_count = init_cpp_parse (); interface_unknown = 1; ggc_add_string_root (&internal_filename, 1); - ggc_add_tree_root (ridpointers, CP_RID_MAX); - ggc_add_tree_root (&defarg_fns, 1); - ggc_add_tree_root (&defarg_parm, 1); - ggc_add_tree_root (&this_filename_time, 1); - ggc_add_tree_root (&filename_times, 1); ggc_add_root (&impl_file_chain, 1, sizeof (impl_file_chain), mark_impl_file_chain); - return filename; + + return init_c_lex (filename); } void finish_parse () { #if USE_CPPLIB - cpp_finish (&parse_in); + cpp_finish (&parse_in, 0 /* no printer */); errorcount += parse_in.errors; #else fclose (finput); @@ -906,20 +975,23 @@ mark_impl_file_chain (arg) void extract_interface_info () { - tree fileinfo = 0; + struct c_fileinfo *finfo = 0; if (flag_alt_external_templates) { tree til = tinst_for_decl (); if (til) - fileinfo = get_time_identifier (TINST_FILE (til)); + finfo = get_fileinfo (TINST_FILE (til)); } - if (!fileinfo) - fileinfo = get_time_identifier (input_filename); - fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo); - interface_only = TREE_INT_CST_LOW (fileinfo); - interface_unknown = TREE_INT_CST_HIGH (fileinfo); + if (!finfo) + finfo = get_fileinfo (input_filename); + + interface_only = finfo->interface_only; + interface_unknown = finfo->interface_unknown; + + /* This happens to be a convenient place to put this. */ + if (flag_gnu_xref) GNU_xref_file (input_filename); } /* Return nonzero if S is not considered part of an @@ -963,781 +1035,6 @@ interface_strcmp (s) return 1; } -static void -cp_pragma_interface (main_filename) - const char *main_filename; -{ - tree fileinfo - = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); - - if (impl_file_chain == 0) - { - /* If this is zero at this point, then we are - auto-implementing. */ - if (main_input_filename == 0) - main_input_filename = input_filename; - -#ifdef AUTO_IMPLEMENT - filename = file_name_nondirectory (main_input_filename); - fi = get_time_identifier (filename); - fi = TIME_IDENTIFIER_FILEINFO (fi); - TREE_INT_CST_LOW (fi) = 0; - TREE_INT_CST_HIGH (fi) = 1; - /* Get default. */ - impl_file_chain - = (struct impl_files *) xmalloc (sizeof (struct impl_files)); - impl_file_chain->filename = ggc_alloc_string (filename, -1); - impl_file_chain->next = 0; -#endif - } - - interface_only = interface_strcmp (main_filename); -#ifdef MULTIPLE_SYMBOL_SPACES - if (! interface_only) - interface_unknown = 0; -#else /* MULTIPLE_SYMBOL_SPACES */ - interface_unknown = 0; -#endif /* MULTIPLE_SYMBOL_SPACES */ - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; -} - -/* Note that we have seen a #pragma implementation for the key MAIN_FILENAME. - We used to only allow this at toplevel, but that restriction was buggy - in older compilers and it seems reasonable to allow it in the headers - themselves, too. It only needs to precede the matching #p interface. - - We don't touch interface_only or interface_unknown; the user must specify - a matching #p interface for this to have any effect. */ - -static void -cp_pragma_implementation (main_filename) - const char *main_filename; -{ - struct impl_files *ifiles = impl_file_chain; - for (; ifiles; ifiles = ifiles->next) - { - if (! strcmp (ifiles->filename, main_filename)) - break; - } - if (ifiles == 0) - { - ifiles = (struct impl_files*) xmalloc (sizeof (struct impl_files)); - ifiles->filename = ggc_alloc_string (main_filename, -1); - ifiles->next = impl_file_chain; - impl_file_chain = ifiles; - } -} - -/* Set up the state required to correctly handle the definition of the - inline function whose preparsed state has been saved in PI. */ - -static void -begin_definition_of_inclass_inline (pi) - struct pending_inline* pi; -{ - tree context; - - if (!pi->fndecl) - return; - - /* If this is an inline function in a local class, we must make sure - that we save all pertinent information about the function - surrounding the local class. */ - context = decl_function_context (pi->fndecl); - if (context) - push_function_context_to (context); - - feed_input (pi->buf, pi->len, pi->filename, pi->lineno); - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.pi = pi; - /* Pass back a handle to the rest of the inline functions, so that they - can be processed later. */ - DECL_PENDING_INLINE_INFO (pi->fndecl) = 0; - DECL_PENDING_INLINE_P (pi->fndecl) = 0; - interface_unknown = pi->interface == 1; - interface_only = pi->interface == 0; -} - -/* Called from the top level: if there are any pending inlines to - do, set up to process them now. This function sets up the first function - to be parsed; after it has been, the rule for fndef in parse.y will - call process_next_inline to start working on the next one. */ - -void -do_pending_inlines () -{ - struct pending_inline *t; - - /* Oops, we're still dealing with the last batch. */ - if (yychar == PRE_PARSED_FUNCTION_DECL) - return; - - /* Reverse the pending inline functions, since - they were cons'd instead of appended. */ - { - struct pending_inline *prev = 0, *tail; - t = pending_inlines; - pending_inlines = 0; - - for (; t; t = tail) - { - tail = t->next; - t->next = prev; - t->deja_vu = 1; - prev = t; - } - t = prev; - } - - if (t == 0) - return; - - /* Now start processing the first inline function. */ - begin_definition_of_inclass_inline (t); -} - -/* Called from the fndecl rule in the parser when the function just parsed - was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from - do_pending_inlines). */ - -void -process_next_inline (i) - struct pending_inline *i; -{ - tree context; - context = decl_function_context (i->fndecl); - if (context) - pop_function_context_from (context); - 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. */ - } - yychar = YYEMPTY; - end_input (); - if (i) - begin_definition_of_inclass_inline (i); - 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. */ - -static void -consume_string (this_obstack, matching_char) - register struct obstack *this_obstack; - int matching_char; -{ - register int c; - int starting_lineno; - -#if USE_CPPLIB - if (cpp_token == CPP_STRING) - { - /* The C preprocessor will warn about newlines in strings. */ - obstack_grow (this_obstack, yy_cur, (yy_lim - yy_cur)); - yy_cur = yy_lim; - lineno = parse_in.lineno; - return; - } -#endif - - starting_lineno = lineno; - do - { - c = getch (); - if (c == EOF) - { - int save_lineno = lineno; - lineno = starting_lineno; - if (matching_char == '"') - error ("end of file encountered inside string constant"); - else - error ("end of file encountered inside character constant"); - lineno = save_lineno; - return; - } - if (c == '\\') - { - obstack_1grow (this_obstack, c); - c = getch (); - obstack_1grow (this_obstack, c); - - /* Make sure we continue the loop */ - c = 0; - continue; - } - if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C++ forbids newline in string constant"); - lineno++; - } - obstack_1grow (this_obstack, c); - } - while (c != matching_char); -} - -struct pending_input { - int yychar, eof; - YYSTYPE yylval; - 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->yychar = yychar; - p->yylval = yylval; - p->eof = end_of_file; - yychar = YYEMPTY; - p->first_token = first_token; - p->token_obstack = token_obstack; - - first_token = 0; - gcc_obstack_init (&token_obstack); - end_of_file = 0; - return p; -} - -void -restore_pending_input (p) - struct pending_input *p; -{ - my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); - yychar = p->yychar; - yylval = p->yylval; - first_token = p->first_token; - obstack_free (&token_obstack, (char *) 0); - token_obstack = p->token_obstack; - end_of_file = p->eof; - free (p); -} - -/* Unget character CH from the input stream. - If RESCAN is non-zero, then we want to `see' this - character as the next input token. */ - -void -yyungetc (ch, rescan) - int ch; - int rescan; -{ - /* Unget a character from the input stream. */ - if (yychar == YYEMPTY || rescan == 0) - { - /* 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++; - - put_back (ch); - } - else - { - yychar = ch; - } -} - -void -clear_inline_text_obstack () -{ - obstack_free (&inline_text_obstack, inline_text_firstobj); -} - -/* 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 void -store_pending_inline (decl, t) - tree decl; - struct pending_inline *t; -{ - t->fndecl = decl; - DECL_PENDING_INLINE_INFO (decl) = t; - DECL_PENDING_INLINE_P (decl) = 1; - - /* Because we use obstacks, we must process these in precise order. */ - t->next = pending_inlines; - pending_inlines = t; -} - -void -reinit_parse_for_method (yychar, decl) - int yychar; - tree decl; -{ - int len; - int starting_lineno = lineno; - const char *starting_filename = input_filename; - - reinit_parse_for_block (yychar, &inline_text_obstack); - - len = obstack_object_size (&inline_text_obstack); - 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. */ - -void -reinit_parse_for_block (pyychar, obstackp) - int pyychar; - struct obstack *obstackp; -{ - register int c; - int blev = 1; - int starting_lineno = lineno; - const char *starting_filename = input_filename; - int len; - int look_for_semicolon = 0; - int look_for_lbrac = 0; - - if (pyychar == '{') - { - obstack_1grow (obstackp, '{'); - /* We incremented indent_level in yylex; undo that. */ - indent_level--; - } - 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, '{'); - } - - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - saving_parse_to_obstack = 1; - c = skip_white_space (c); - saving_parse_to_obstack = 0; - - /* 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 void -reinit_parse_for_expr (obstackp) - struct obstack *obstackp; -{ - register int c; - int starting_lineno = lineno; - const char *starting_filename = input_filename; - int len; - int plev = 0; - - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - saving_parse_to_obstack = 1; - c = skip_white_space (c); - saving_parse_to_obstack = 0; - - /* 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. */ - -void -maybe_snarf_defarg () -{ - if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) - do_snarf_defarg = 1; -} - -tree -snarf_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); - - arg = make_node (DEFAULT_ARG); - DEFARG_LENGTH (arg) = len - 1; - DEFARG_POINTER (arg) = buf; - - 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. */ - -void -add_defarg_fn (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - TREE_VALUE (defarg_fns) = decl; - else - defarg_fns = tree_cons (current_class_type, decl, defarg_fns); -} - -/* Helper for do_pending_defargs. Starts the parsing of a default arg. */ - -static void -feed_defarg (f, p) - tree f, p; -{ - tree d = TREE_PURPOSE (p); - const char *file; - int line; - if (TREE_CODE (f) == FUNCTION_DECL) - { - line = DECL_SOURCE_LINE (f); - file = DECL_SOURCE_FILE (f); - } - else - { - line = lineno; - file = input_filename; - } - - feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d), file, line); - yychar = DEFARG_MARKER; - yylval.ttype = p; -} - -/* Helper for do_pending_defargs. Ends the parsing of a default arg. */ - -static void -finish_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. */ - } - yychar = YYEMPTY; - end_input (); -} - -/* Main function for deferred parsing of default arguments. Called from - the parser. */ - -void -do_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)) - if (TREE_PURPOSE (defarg_parm) - && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG) - { - feed_defarg (defarg_fn, defarg_parm); - - /* Return to the parser, which will process this defarg - and call us again. */ - return; - } - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { - maybe_end_member_template_processing (); - check_default_args (defarg_fn); - } - - poplevel (0, 0, 0); - pop_nested_class (); - } -} - /* Heuristic to tell whether the user is missing a semicolon after a struct or enum declaration. Emit an error message if we know the user has blown it. */ @@ -1755,7 +1052,7 @@ check_for_missing_semicolon (type) && yychar != TYPENAME && yychar != CV_QUALIFIER && yychar != SELFNAME) - || end_of_file) + || yychar == 0 /* EOF */) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) error ("semicolon missing after %s declaration", @@ -1793,1239 +1090,147 @@ note_list_got_semicolon (declspecs) clear_anon_tags (); } -/* Iff C is a carriage return, warn about it - if appropriate - - and return nonzero. */ -static int -whitespace_cr (c) - int c; + +/* Parse a #pragma whose sole argument is a string constant. + If OPT is true, the argument is optional. */ +static tree +parse_strconst_pragma (name, opt) + const char *name; + int opt; { - static int newline_warning = 0; + tree result, x; + enum cpp_ttype t; - if (c == '\r') + t = c_lex (&x); + if (t == CPP_STRING) { - /* ANSI C says the effects of a carriage return in a source file - are undefined. */ - if (pedantic && !newline_warning) - { - warning ("carriage return in source file (we only warn about the first carriage return)"); - newline_warning = 1; - } - return 1; + result = x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma %s", name); + return result; } - return 0; -} - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - for (;;) - { - switch (c) - { - /* We don't recognize comments here, because - cpp output can include / and * consecutively as operators. - Also, there's no need, since cpp removes all comments. */ - case '\n': - if (linemode) - { - put_back (c); - return EOF; - } - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': -#if USE_CPPLIB - /* While processing a # directive we don't get CPP_HSPACE - tokens, so we also need to handle whitespace the normal way. */ - if (cpp_token == CPP_HSPACE) - c = yy_get_token (); - else -#endif - c = getch (); - break; - - case '\r': - whitespace_cr (c); - c = getch (); - break; - - case '\\': - c = getch (); - if (c == '\n') - { - lineno++; - c = getch (); - } - else if (c == 'u') - c = read_ucs (4); - else if (c == 'U') - c = read_ucs (8); - else - error ("stray '\\' in program"); - break; + if (t == CPP_EOF && opt) + return 0; - default: - return (c); - } - } + error ("invalid #pragma %s", name); + return (tree)-1; } - -/* 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 void -extend_token_buffer_to (size) - int size; +handle_pragma_vtable (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; { - do - maxtoken = maxtoken * 2 + 10; - while (maxtoken < size); - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); -} + tree vtbl = parse_strconst_pragma ("vtable", 0); -static char * -extend_token_buffer (p) - const char *p; -{ - int offset = p - token_buffer; - extend_token_buffer_to (offset); - return token_buffer + offset; -} - -#if defined HANDLE_PRAGMA -/* Local versions of these macros, that can be passed as function pointers. */ -static int -pragma_getc () -{ - return getch (); + if (vtbl && vtbl != (tree)-1) + pending_vtables = tree_cons (NULL_TREE, + get_identifier (TREE_STRING_POINTER (vtbl)), + pending_vtables); } static void -pragma_ungetc (arg) - int arg; +handle_pragma_unit (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; { - put_back (arg); + /* Validate syntax, but don't do anything. */ + parse_strconst_pragma ("unit", 0); } -#endif -static int -read_line_number (num) - int *num; +static void +handle_pragma_interface (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; { - register int token = real_yylex (); + tree fname = parse_strconst_pragma ("interface", 1); + struct c_fileinfo *finfo; + const char *main_filename; - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - *num = TREE_INT_CST_LOW (yylval.ttype); - return 1; - } + if (fname == (tree)-1) + return; + else if (fname == 0) + main_filename = file_name_nondirectory (input_filename); else - { - if (token != END_OF_LINE) - error ("invalid #-line"); - return 0; - } -} - -/* 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. - - Note that in the case of USE_CPPLIB, we get the whole line as one - CPP_DIRECTIVE token. */ - -static int -check_newline () -{ - register int c; - register int token; - int saw_line; - enum { act_none, act_push, act_pop } action; - int action_number, l; - int entering_c_header; - char *new_file; - - restart: - /* Read first nonwhite char on the line. Do this before incrementing the - line number, in case we're at the end of saved text. */ - -#ifdef USE_CPPLIB - c = getch (); - /* In some cases where we're leaving an include file, we can get multiple - CPP_HSPACE tokens in a row, so we need to loop. */ - while (cpp_token == CPP_HSPACE) - c = yy_get_token (); -#else - do - c = getch (); - while (c == ' ' || c == '\t'); -#endif + main_filename = TREE_STRING_POINTER (fname); - lineno++; - - if (c != '#') - { - /* Sequences of multiple newlines are very common; optimize them. */ - if (c == '\n') - goto restart; + finfo = get_fileinfo (input_filename); - /* If not #, return it so caller will use it. */ - return c; - } - - /* Don't read beyond this line. */ - saw_line = 0; - linemode = 1; - -#if USE_CPPLIB - if (cpp_token == CPP_VSPACE) + if (impl_file_chain == 0) { - /* Format is "<space> <line number> <filename> <newline>". - Only the line number is interesting, and even that - we can get more efficiently than scanning the line. */ - yy_cur = yy_lim - 1; - lineno = parse_in.lineno - 1; - goto skipline; + /* If this is zero at this point, then we are + auto-implementing. */ + if (main_input_filename == 0) + main_input_filename = input_filename; } -#endif - - token = real_yylex (); - - if (token == IDENTIFIER) - { - /* 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'. */ - - const char *name = IDENTIFIER_POINTER (yylval.ttype); - - if (!strcmp (name, "pragma")) - { - token = real_yylex (); - if (token != IDENTIFIER - || TREE_CODE (yylval.ttype) != IDENTIFIER_NODE) - goto skipline; - - /* If this is 1, we handled it; if it's -1, it was one we - wanted but had something wrong with it. Only if it's - 0 was it not handled. */ - if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; - -#ifdef HANDLE_PRAGMA - /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS - (if both are defined), in order to give the back - end a chance to override the interpretation of - SYSV style pragmas. */ - if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, - IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; -#endif /* HANDLE_PRAGMA */ - -#ifdef HANDLE_GENERIC_PRAGMAS - if (handle_generic_pragma (token)) - goto skipline; -#endif /* HANDLE_GENERIC_PRAGMAS */ - - /* Issue a warning message if we have been asked to do so. - Ignoring unknown pragmas in system header file unless - an explcit -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > 1 - || (warn_unknown_pragmas && ! in_system_header)) - warning ("ignoring pragma: %s", token_buffer); - - goto skipline; - } - else if (!strcmp (name, "define")) - { - debug_define (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - else if (!strcmp (name, "undef")) - { - debug_undef (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - else if (!strcmp (name, "line")) - { - saw_line = 1; - token = real_yylex (); - goto linenum; - } - else if (!strcmp (name, "ident")) - { - /* #ident. The pedantic warning is now in cpp. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - token = real_yylex (); - if (token == END_OF_LINE) - goto skipline; - 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)); + interface_only = interface_strcmp (main_filename); +#ifdef MULTIPLE_SYMBOL_SPACES + if (! interface_only) #endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - - error ("undefined or invalid # directive `%s'", name); - goto skipline; - } - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (token == END_OF_LINE) - goto skipline; - -linenum: - /* Here we have either `#line' or `# <nonletter>'. - In either case, it should be a line number; a digit should follow. */ - - if (token != CONSTANT - || TREE_CODE (yylval.ttype) != INTEGER_CST) - { - error ("invalid #-line"); - goto skipline; - } - - /* subtract one, because it is the following line that - gets the specified number */ - - l = TREE_INT_CST_LOW (yylval.ttype) - 1; - - /* More follows: it must be a string constant (filename). - It would be neat to use cpplib to quickly process the string, but - (1) we don't have a handy tokenization of the string, and - (2) I don't know how well that would work in the presense - of filenames that contain wide characters. */ - - if (saw_line || saving_parse_to_obstack) - { - /* Don't treat \ as special if we are processing #line 1 "...". - If you want it to be treated specially, use # 1 "...". Also - ignore these if saving to an obstack for later parsing. */ - ignore_escape_flag = 1; - } - - /* Read the string constant. */ - token = real_yylex (); - - ignore_escape_flag = 0; - - if (token == END_OF_LINE) - { - /* No more: store the line number and check following line. */ - lineno = l; - goto skipline; - } - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - /* Changing files again. This means currently collected time - is charged against header time, and body time starts back at 0. */ - if (flag_detailed_statistics) - { - int this_time = get_run_time (); - tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); - header_time += this_time - body_time; - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - this_filename_time = time_identifier; - body_time = this_time; - } - - new_file = TREE_STRING_POINTER (yylval.ttype); - - GNU_xref_file (new_file); - - if (main_input_filename == 0) - { - struct impl_files *ifiles = impl_file_chain; - - if (ifiles) - { - while (ifiles->next) - ifiles = ifiles->next; - ifiles->filename = file_name_nondirectory (new_file); - } - - main_input_filename = new_file; - } - - action = act_none; - action_number = 0; - - /* Each change of file name - reinitializes whether we are now in a system header. */ - in_system_header = 0; - entering_c_header = 0; - - if (!read_line_number (&action_number) && input_file_stack) - { - input_file_stack->name = input_filename = new_file; - input_file_stack->line = lineno = l; - } - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (action_number == 1) - { - action = act_push; - read_line_number (&action_number); - } - else if (action_number == 2) - { - action = act_pop; - read_line_number (&action_number); - } - if (action_number == 3) - { - /* `3' after file name means this is a system header file. */ - in_system_header = 1; - read_line_number (&action_number); - } - if (action_number == 4) - { - /* `4' after file name means this is a C header file. */ - entering_c_header = 1; - read_line_number (&action_number); - } - - /* Do the actions implied by the preceding numbers. */ - - if (action == act_push) - { - /* Pushing to a new file. */ - push_srcloc (new_file, l); - input_file_stack->indent_level = indent_level; - debug_start_source_file (input_filename); - if (c_header_level) - ++c_header_level; - else if (entering_c_header) - { - c_header_level = 1; - ++pending_lang_change; - } - } - else if (action == act_pop) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - if (c_header_level && --c_header_level == 0) - { - if (entering_c_header) - warning ("badly nested C headers from preprocessor"); - --pending_lang_change; - } - - if (indent_level != input_file_stack->indent_level) - { - warning_with_file_and_line - (input_filename, lineno, - "This file contains more `%c's than `%c's.", - indent_level > input_file_stack->indent_level ? '{' : '}', - indent_level > input_file_stack->indent_level ? '}' : '{'); - } - - pop_srcloc (); - input_file_stack->name = new_file; - debug_end_source_file (input_file_stack->line); - } - else - error ("#-lines for entering and leaving files don't match"); - } - - input_filename = new_file; - lineno = l; - - extract_interface_info (); - - /* skip the rest of this line. */ - skipline: - linemode = 0; - end_of_file = 0; + interface_unknown = 0; - do - c = getch (); - while (c != '\n' && c != EOF); - return c; + finfo->interface_only = interface_only; + finfo->interface_unknown = interface_unknown; } - -#ifdef HANDLE_GENERIC_PRAGMAS - -/* Handle a #pragma directive. - TOKEN is the token we read after `#pragma'. Processes the entire input - line and return non-zero iff the pragma has been successfully parsed. */ - -/* This function has to be in this file, in order to get at - the token types. */ - -static int -handle_generic_pragma (token) - register int token; -{ - for (;;) - { - switch (token) - { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); - break; - - case LEFT_RIGHT: - handle_pragma_token ("(", NULL_TREE); - handle_pragma_token (")", NULL_TREE); - break; - case END_OF_LINE: - return handle_pragma_token (NULL_PTR, NULL_TREE); +/* Note that we have seen a #pragma implementation for the key MAIN_FILENAME. + We used to only allow this at toplevel, but that restriction was buggy + in older compilers and it seems reasonable to allow it in the headers + themselves, too. It only needs to precede the matching #p interface. - default: - handle_pragma_token (token_buffer, NULL_TREE); - } - - token = real_yylex (); - } -} -#endif /* HANDLE_GENERIC_PRAGMAS */ + We don't touch interface_only or interface_unknown; the user must specify + a matching #p interface for this to have any effect. */ -static int -handle_cp_pragma (pname) - const char *pname; +static void +handle_pragma_implementation (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; { - register int token; - - if (! strcmp (pname, "vtable")) - { - /* 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"); - return -1; - } - - pending_vtables - = tree_cons (NULL_TREE, - get_identifier (TREE_STRING_POINTER (yylval.ttype)), - pending_vtables); - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "unit")) - { - /* 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"); - return -1; - } - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "interface")) - { - const char *main_filename = input_filename; - - main_filename = file_name_nondirectory (main_filename); - - token = real_yylex (); - - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma interface'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma interface' ignored"); + tree fname = parse_strconst_pragma ("implementation", 1); + const char *main_filename; + struct impl_files *ifiles = impl_file_chain; - cp_pragma_interface (main_filename); + if (fname == (tree)-1) + return; - return 1; - } - else if (! strcmp (pname, "implementation")) + if (fname == 0) { - const char *main_filename = main_input_filename ? main_input_filename : input_filename; - + if (main_input_filename) + main_filename = main_input_filename; + else + main_filename = input_filename; main_filename = file_name_nondirectory (main_filename); - - token = real_yylex (); - - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma implementation'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma implementation' ignored"); - - cp_pragma_implementation (main_filename); - - return 1; - } - - return 0; -} - -void -do_pending_lang_change () -{ - for (; pending_lang_change > 0; --pending_lang_change) - push_lang_context (lang_name_c); - for (; pending_lang_change < 0; ++pending_lang_change) - pop_lang_context (); -} - -/* Parse a '\uNNNN' or '\UNNNNNNNN' sequence. - - [lex.charset]: The character designated by the universal-character-name - \UNNNNNNNN is that character whose character short name in ISO/IEC 10646 - is NNNNNNNN; the character designated by the universal-character-name - \uNNNN is that character whose character short name in ISO/IEC 10646 is - 0000NNNN. If the hexadecimal value for a universal character name is - less than 0x20 or in the range 0x7F-0x9F (inclusive), or if the - universal character name designates a character in the basic source - character set, then the program is ill-formed. - - We assume that wchar_t is Unicode, so we don't need to do any - mapping. Is this ever wrong? */ - -static int -read_ucs (length) - int length; -{ - unsigned int code = 0; - int c; - - for (; length; --length) - { - c = getch (); - if (! ISXDIGIT (c)) - { - error ("non hex digit '%c' in universal-character-name", c); - put_back (c); - break; - } - code <<= 4; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - } - -#ifdef TARGET_EBCDIC - sorry ("universal-character-name on EBCDIC target"); - return 0x3F; -#endif - - if (code > 0x9f && !(code & 0x80000000)) - /* True extended character, OK. */; - else if (code >= 0x20 && code < 0x7f) - { - /* ASCII printable character. The C character set consists of all of - these except $, @ and `. We use hex escapes so that this also - works with EBCDIC hosts. */ - if (code != 0x24 && code != 0x40 && code != 0x60) - error ("universal-character-name designates `%c', part of the basic source character set", code); } else - error ("invalid universal-character-name"); - return code; -} - -/* Returns nonzero if C is a universal-character-name. Give an error if it - is not one which may appear in an identifier, as per [extendid]. */ - -static inline int -is_extended_char (c) - int c; -{ -#ifdef TARGET_EBCDIC - return 0; -#else - /* ASCII. */ - if (c < 0x7f) - return 0; - - return is_extended_char_1 (c); -#endif -} - -static int -is_extended_char_1 (c) - int c; -{ - /* None of the valid chars are outside the Basic Multilingual Plane (the - low 16 bits). */ - if (c > 0xffff) { - error ("universal-character-name `\\U%08x' not valid in identifier", c); - return 1; - } - - /* Latin */ - if ((c >= 0x00c0 && c <= 0x00d6) - || (c >= 0x00d8 && c <= 0x00f6) - || (c >= 0x00f8 && c <= 0x01f5) - || (c >= 0x01fa && c <= 0x0217) - || (c >= 0x0250 && c <= 0x02a8) - || (c >= 0x1e00 && c <= 0x1e9a) - || (c >= 0x1ea0 && c <= 0x1ef9)) - return 1; - - /* Greek */ - if ((c == 0x0384) - || (c >= 0x0388 && c <= 0x038a) - || (c == 0x038c) - || (c >= 0x038e && c <= 0x03a1) - || (c >= 0x03a3 && c <= 0x03ce) - || (c >= 0x03d0 && c <= 0x03d6) - || (c == 0x03da) - || (c == 0x03dc) - || (c == 0x03de) - || (c == 0x03e0) - || (c >= 0x03e2 && c <= 0x03f3) - || (c >= 0x1f00 && c <= 0x1f15) - || (c >= 0x1f18 && c <= 0x1f1d) - || (c >= 0x1f20 && c <= 0x1f45) - || (c >= 0x1f48 && c <= 0x1f4d) - || (c >= 0x1f50 && c <= 0x1f57) - || (c == 0x1f59) - || (c == 0x1f5b) - || (c == 0x1f5d) - || (c >= 0x1f5f && c <= 0x1f7d) - || (c >= 0x1f80 && c <= 0x1fb4) - || (c >= 0x1fb6 && c <= 0x1fbc) - || (c >= 0x1fc2 && c <= 0x1fc4) - || (c >= 0x1fc6 && c <= 0x1fcc) - || (c >= 0x1fd0 && c <= 0x1fd3) - || (c >= 0x1fd6 && c <= 0x1fdb) - || (c >= 0x1fe0 && c <= 0x1fec) - || (c >= 0x1ff2 && c <= 0x1ff4) - || (c >= 0x1ff6 && c <= 0x1ffc)) - return 1; - - /* Cyrillic */ - if ((c >= 0x0401 && c <= 0x040d) - || (c >= 0x040f && c <= 0x044f) - || (c >= 0x0451 && c <= 0x045c) - || (c >= 0x045e && c <= 0x0481) - || (c >= 0x0490 && c <= 0x04c4) - || (c >= 0x04c7 && c <= 0x04c8) - || (c >= 0x04cb && c <= 0x04cc) - || (c >= 0x04d0 && c <= 0x04eb) - || (c >= 0x04ee && c <= 0x04f5) - || (c >= 0x04f8 && c <= 0x04f9)) - return 1; - - /* Armenian */ - if ((c >= 0x0531 && c <= 0x0556) - || (c >= 0x0561 && c <= 0x0587)) - return 1; - - /* Hebrew */ - if ((c >= 0x05d0 && c <= 0x05ea) - || (c >= 0x05f0 && c <= 0x05f4)) - return 1; - - /* Arabic */ - if ((c >= 0x0621 && c <= 0x063a) - || (c >= 0x0640 && c <= 0x0652) - || (c >= 0x0670 && c <= 0x06b7) - || (c >= 0x06ba && c <= 0x06be) - || (c >= 0x06c0 && c <= 0x06ce) - || (c >= 0x06e5 && c <= 0x06e7)) - return 1; - - /* Devanagari */ - if ((c >= 0x0905 && c <= 0x0939) - || (c >= 0x0958 && c <= 0x0962)) - return 1; - - /* Bengali */ - if ((c >= 0x0985 && c <= 0x098c) - || (c >= 0x098f && c <= 0x0990) - || (c >= 0x0993 && c <= 0x09a8) - || (c >= 0x09aa && c <= 0x09b0) - || (c == 0x09b2) - || (c >= 0x09b6 && c <= 0x09b9) - || (c >= 0x09dc && c <= 0x09dd) - || (c >= 0x09df && c <= 0x09e1) - || (c >= 0x09f0 && c <= 0x09f1)) - return 1; - - /* Gurmukhi */ - if ((c >= 0x0a05 && c <= 0x0a0a) - || (c >= 0x0a0f && c <= 0x0a10) - || (c >= 0x0a13 && c <= 0x0a28) - || (c >= 0x0a2a && c <= 0x0a30) - || (c >= 0x0a32 && c <= 0x0a33) - || (c >= 0x0a35 && c <= 0x0a36) - || (c >= 0x0a38 && c <= 0x0a39) - || (c >= 0x0a59 && c <= 0x0a5c) - || (c == 0x0a5e)) - return 1; - - /* Gujarati */ - if ((c >= 0x0a85 && c <= 0x0a8b) - || (c == 0x0a8d) - || (c >= 0x0a8f && c <= 0x0a91) - || (c >= 0x0a93 && c <= 0x0aa8) - || (c >= 0x0aaa && c <= 0x0ab0) - || (c >= 0x0ab2 && c <= 0x0ab3) - || (c >= 0x0ab5 && c <= 0x0ab9) - || (c == 0x0ae0)) - return 1; - - /* Oriya */ - if ((c >= 0x0b05 && c <= 0x0b0c) - || (c >= 0x0b0f && c <= 0x0b10) - || (c >= 0x0b13 && c <= 0x0b28) - || (c >= 0x0b2a && c <= 0x0b30) - || (c >= 0x0b32 && c <= 0x0b33) - || (c >= 0x0b36 && c <= 0x0b39) - || (c >= 0x0b5c && c <= 0x0b5d) - || (c >= 0x0b5f && c <= 0x0b61)) - return 1; - - /* Tamil */ - if ((c >= 0x0b85 && c <= 0x0b8a) - || (c >= 0x0b8e && c <= 0x0b90) - || (c >= 0x0b92 && c <= 0x0b95) - || (c >= 0x0b99 && c <= 0x0b9a) - || (c == 0x0b9c) - || (c >= 0x0b9e && c <= 0x0b9f) - || (c >= 0x0ba3 && c <= 0x0ba4) - || (c >= 0x0ba8 && c <= 0x0baa) - || (c >= 0x0bae && c <= 0x0bb5) - || (c >= 0x0bb7 && c <= 0x0bb9)) - return 1; - - /* Telugu */ - if ((c >= 0x0c05 && c <= 0x0c0c) - || (c >= 0x0c0e && c <= 0x0c10) - || (c >= 0x0c12 && c <= 0x0c28) - || (c >= 0x0c2a && c <= 0x0c33) - || (c >= 0x0c35 && c <= 0x0c39) - || (c >= 0x0c60 && c <= 0x0c61)) - return 1; - - /* Kannada */ - if ((c >= 0x0c85 && c <= 0x0c8c) - || (c >= 0x0c8e && c <= 0x0c90) - || (c >= 0x0c92 && c <= 0x0ca8) - || (c >= 0x0caa && c <= 0x0cb3) - || (c >= 0x0cb5 && c <= 0x0cb9) - || (c >= 0x0ce0 && c <= 0x0ce1)) - return 1; - - /* Malayalam */ - if ((c >= 0x0d05 && c <= 0x0d0c) - || (c >= 0x0d0e && c <= 0x0d10) - || (c >= 0x0d12 && c <= 0x0d28) - || (c >= 0x0d2a && c <= 0x0d39) - || (c >= 0x0d60 && c <= 0x0d61)) - return 1; - - /* Thai */ - if ((c >= 0x0e01 && c <= 0x0e30) - || (c >= 0x0e32 && c <= 0x0e33) - || (c >= 0x0e40 && c <= 0x0e46) - || (c >= 0x0e4f && c <= 0x0e5b)) - return 1; - - /* Lao */ - if ((c >= 0x0e81 && c <= 0x0e82) - || (c == 0x0e84) - || (c == 0x0e87) - || (c == 0x0e88) - || (c == 0x0e8a) - || (c == 0x0e0d) - || (c >= 0x0e94 && c <= 0x0e97) - || (c >= 0x0e99 && c <= 0x0e9f) - || (c >= 0x0ea1 && c <= 0x0ea3) - || (c == 0x0ea5) - || (c == 0x0ea7) - || (c == 0x0eaa) - || (c == 0x0eab) - || (c >= 0x0ead && c <= 0x0eb0) - || (c == 0x0eb2) - || (c == 0x0eb3) - || (c == 0x0ebd) - || (c >= 0x0ec0 && c <= 0x0ec4) - || (c == 0x0ec6)) - return 1; - - /* Georgian */ - if ((c >= 0x10a0 && c <= 0x10c5) - || (c >= 0x10d0 && c <= 0x10f6)) - return 1; - - /* Hiragana */ - if ((c >= 0x3041 && c <= 0x3094) - || (c >= 0x309b && c <= 0x309e)) - return 1; - - /* Katakana */ - if ((c >= 0x30a1 && c <= 0x30fe)) - return 1; - - /* Bopmofo */ - if ((c >= 0x3105 && c <= 0x312c)) - return 1; - - /* Hangul */ - if ((c >= 0x1100 && c <= 0x1159) - || (c >= 0x1161 && c <= 0x11a2) - || (c >= 0x11a8 && c <= 0x11f9)) - return 1; - - /* CJK Unified Ideographs */ - if ((c >= 0xf900 && c <= 0xfa2d) - || (c >= 0xfb1f && c <= 0xfb36) - || (c >= 0xfb38 && c <= 0xfb3c) - || (c == 0xfb3e) - || (c >= 0xfb40 && c <= 0xfb41) - || (c >= 0xfb42 && c <= 0xfb44) - || (c >= 0xfb46 && c <= 0xfbb1) - || (c >= 0xfbd3 && c <= 0xfd3f) - || (c >= 0xfd50 && c <= 0xfd8f) - || (c >= 0xfd92 && c <= 0xfdc7) - || (c >= 0xfdf0 && c <= 0xfdfb) - || (c >= 0xfe70 && c <= 0xfe72) - || (c == 0xfe74) - || (c >= 0xfe76 && c <= 0xfefc) - || (c >= 0xff21 && c <= 0xff3a) - || (c >= 0xff41 && c <= 0xff5a) - || (c >= 0xff66 && c <= 0xffbe) - || (c >= 0xffc2 && c <= 0xffc7) - || (c >= 0xffca && c <= 0xffcf) - || (c >= 0xffd2 && c <= 0xffd7) - || (c >= 0xffda && c <= 0xffdc) - || (c >= 0x4e00 && c <= 0x9fa5)) - return 1; - - error ("universal-character-name `\\u%04x' not valid in identifier", c); - return 1; -} - -#if 0 -/* Add the UTF-8 representation of C to the token_buffer. */ - -static void -utf8_extend_token (c) - int c; -{ - int shift, mask; - - if (c <= 0x0000007f) - { - extend_token (c); - return; - } - else if (c <= 0x000007ff) - shift = 6, mask = 0xc0; - else if (c <= 0x0000ffff) - shift = 12, mask = 0xe0; - else if (c <= 0x001fffff) - shift = 18, mask = 0xf0; - else if (c <= 0x03ffffff) - shift = 24, mask = 0xf8; - else - shift = 30, mask = 0xfc; + main_filename = TREE_STRING_POINTER (fname); +#if USE_CPPLIB - extend_token (mask | (c >> shift)); - do - { - shift -= 6; - extend_token ((unsigned char) (0x80 | (c >> shift))); - } - while (shift); -} + if (cpp_included (&parse_in, main_filename)) + warning ("#pragma implementation for %s appears after file is included", + main_filename); #endif - -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getch (); - register int code; - register unsigned count; - unsigned firstdig = 0; - int nonnull; - - switch (c) - { - case 'x': - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getch (); - if (! ISXDIGIT (c)) - { - put_back (c); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && (((unsigned)1 - << (TYPE_PRECISION (integer_type_node) - - (count - 1) * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getch (); - } - put_back (c); - return code; - - case 'U': - return read_ucs (8); - case 'u': - return read_ucs (4); - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - return TARGET_BELL; - - case 'v': - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ISO-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("unknown escape sequence `\\%c'", c); - return c; } - if (ISGRAPH (c)) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -void -yyerror (string) - const char *string; -{ - extern int end_of_file; - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - { - if (input_redirected ()) - error ("%s at end of saved text", string); - else - error ("%s at end of input", string); - } - else if (token_buffer[0] == 0) - error ("%s at null character", string); - else if (token_buffer[0] == '"') - error ("%s before string constant", string); - else if (token_buffer[0] == '\'') - error ("%s before character constant", string); - else if (!ISGRAPH ((unsigned char)token_buffer[0])) - error ("%s before character 0%o", string, (unsigned char) token_buffer[0]); - else - error ("%s before `%s'", string, token_buffer); -} - -/* Value is 1 (or 2) if we should try to make the next identifier look like - a typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. */ -int looking_for_typename; -inline int -identifier_type (decl) - tree decl; -{ - tree t; - - if (TREE_CODE (decl) == TEMPLATE_DECL) + for (; ifiles; ifiles = ifiles->next) { - if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL) - return PTYPENAME; - else if (looking_for_template) - return PFUNCNAME; + if (! strcmp (ifiles->filename, main_filename)) + break; } - if (looking_for_template && really_overloaded_fn (decl)) + if (ifiles == 0) { - /* See through a baselink. */ - if (TREE_CODE (decl) == TREE_LIST) - decl = TREE_VALUE (decl); - - for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) - if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) - return PFUNCNAME; + ifiles = (struct impl_files*) xmalloc (sizeof (struct impl_files)); + ifiles->filename = ggc_alloc_string (main_filename, -1); + ifiles->next = impl_file_chain; + impl_file_chain = ifiles; } - if (TREE_CODE (decl) == NAMESPACE_DECL) - return NSNAME; - if (TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) - return SELFNAME; - - /* A constructor declarator for a template type will get here as an - implicit typename, a TYPENAME_TYPE with a type. */ - t = got_scope; - if (t && TREE_CODE (t) == TYPENAME_TYPE) - t = TREE_TYPE (t); - decl = TREE_TYPE (decl); - if (TREE_CODE (decl) == TYPENAME_TYPE) - decl = TREE_TYPE (decl); - if (t && t == decl) - return SELFNAME; - - return TYPENAME; } void -see_typename () +do_pending_lang_change () { - /* Only types expected, not even namespaces. */ - looking_for_typename = 2; - if (yychar < 0) - if ((yychar = yylex ()) < 0) yychar = 0; - looking_for_typename = 0; - if (yychar == IDENTIFIER) - { - lastiddecl = lookup_name (yylval.ttype, -2); - if (lastiddecl == 0) - { - if (flag_labels_ok) - lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); - } - else - yychar = identifier_type (lastiddecl); - } + for (; pending_lang_change > 0; --pending_lang_change) + push_lang_context (lang_name_c); + for (; pending_lang_change < 0; ++pending_lang_change) + pop_lang_context (); } /* Return true if d is in a global scope. */ @@ -3187,9 +1392,6 @@ do_identifier (token, parsing, args) local variables and then finding matching instantiations. */ if (current_template_parms && (is_overloaded_fn (id) - /* Some local VAR_DECLs (such as those for local variables - in member functions of local classes) are built on the - permanent obstack. */ || (TREE_CODE (id) == VAR_DECL && CP_DECL_CONTEXT (id) && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL) @@ -3295,1386 +1497,6 @@ identifier_typedecl_value (node) return NULL_TREE; } -struct pf_args -{ - /* Input */ - int base; - char * p; - /* I/O */ - int c; - /* Output */ - int imag; - tree type; - int conversion_errno; - REAL_VALUE_TYPE value; -}; - -static void -parse_float (data) - PTR data; -{ - struct pf_args * args = (struct pf_args *) data; - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (args->p - token_buffer + 1); - bcopy (token_buffer, copy, args->p - token_buffer + 1); - args->imag = 0; - args->conversion_errno = 0; - args->type = double_type_node; - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (args->c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (args->imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ISO C++ forbids imaginary numeric constants"); - args->imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (args->p >= token_buffer + maxtoken - 3) - args->p = extend_token_buffer (args->p); - *(args->p++) = args->c; - *(args->p) = 0; - args->c = getch (); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - args->type = float_type_node; - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, because some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - args->type = long_double_type_node; - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `long double'"); - } - else - { - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `double'"); - } -} - -/* Get the next character, staying within the current token if possible. - If we're lexing a token, we don't want to look beyond the end of the - token cpplib has prepared for us; otherwise, we end up reading in the - next token, which screws up feed_input. So just return a null - character. */ - -static int -token_getch () -{ -#if USE_CPPLIB - if (yy_cur == yy_lim) - return '\0'; -#endif - return getch (); -} - -static void -token_put_back (ch) - int ch; -{ -#if USE_CPPLIB - if (ch == '\0') - return; -#endif - put_back (ch); -} - -/* Read a single token from the input stream, and assign it lexical - semantics. - - Note: We used to do token pasting here, to produce compound tokens like - LEFT_RIGHT and EXTERN_LANG_STRING. That's now handled in spew.c, along - with symbol table interaction and other context-sensitivity. */ - -int -real_yylex () -{ - register int c; - register char *p; - register int value; - int wide_flag = 0; - - c = getch (); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': -#if USE_CPPLIB - if (cpp_token == CPP_HSPACE) - c = yy_get_token (); - else -#endif - c = getch (); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - end_of_file = 1; - token_buffer[0] = 0; - if (linemode) - value = END_OF_LINE; - else if (input_redirected ()) - value = END_OF_SAVED_INPUT; - else - value = ENDFILE; - break; - - case 'L': -#if USE_CPPLIB - if (cpp_token == CPP_NAME) - goto letter; -#endif - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = token_getch (); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - token_put_back (c); - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '_': - case '$': - letter: -#if USE_CPPLIB - if (cpp_token == CPP_NAME) - { - /* Note that one character has already been read from - yy_cur into token_buffer. Also, cpplib complains about - $ in identifiers, so we don't have to. */ - - int len = yy_lim - yy_cur + 1; - if (len >= maxtoken) - extend_token_buffer_to (len + 1); - memcpy (token_buffer + 1, yy_cur, len); - p = token_buffer + len; - yy_cur = yy_lim; - } - else -#endif - { - p = token_buffer; - while (1) - { - /* Make sure this char really belongs in an identifier. */ - if (ISALNUM (c) || c == '_') - /* OK */; - else if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - /* FIXME we should use some sort of multibyte character - encoding. Locale-dependent? Always UTF-8? */ - else if (is_extended_char (c)) - { - sorry ("universal characters in identifiers"); - c = '_'; - } - else - break; - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - - idtryagain: - c = token_getch (); - - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto idtryagain; - } - } - - *p = 0; - token_put_back (c); - } - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if ((ptr = is_reserved_word (token_buffer, p - token_buffer))) - { - if (ptr->rid) - { - if (ptr->token == VISSPEC) - { - switch (ptr->rid) - { - case RID_PUBLIC: - yylval.ttype = access_public_node; - break; - case RID_PRIVATE: - yylval.ttype = access_private_node; - break; - case RID_PROTECTED: - yylval.ttype = access_protected_node; - break; - default: - my_friendly_abort (63); - } - } - else - yylval.ttype = ridpointers[(int) ptr->rid]; - } - else switch (ptr->token) - { - case EQCOMPARE: - yylval.code = NE_EXPR; - token_buffer[0] = '!'; - token_buffer[1] = '='; - token_buffer[2] = 0; - break; - - case ASSIGN: - if (strcmp ("and_eq", token_buffer) == 0) - { - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - } - else if (strcmp ("or_eq", token_buffer) == 0) - { - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - } - else if (strcmp ("xor_eq", token_buffer) == 0) - { - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - } - token_buffer[1] = '='; - token_buffer[2] = 0; - break; - - case '&': - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - token_buffer[1] = 0; - break; - - case '|': - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - token_buffer[1] = 0; - break; - - case '^': - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - token_buffer[1] = 0; - break; - } - - value = (int) ptr->token; - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER || value == TYPESPEC) - GNU_xref_ref (current_function_decl, token_buffer); - - if (value == IDENTIFIER) - { - register tree tmp = get_identifier (token_buffer); - -#if !defined(VMS) && defined(JOINER) - /* Make sure that user does not collide with our internal - naming scheme. */ - if (JOINER == '$' - && (THIS_NAME_P (tmp) - || VPTR_NAME_P (tmp) - || DESTRUCTOR_NAME_P (tmp) - || VTABLE_NAME_P (tmp) - || TEMP_NAME_P (tmp) - || ANON_AGGRNAME_P (tmp) - || ANON_PARMNAME_P (tmp))) - warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", - token_buffer); -#endif - - yylval.ttype = tmp; - } - if (value == NEW && ! global_bindings_p ()) - { - value = NEW; - goto done; - } - break; - - case '.': -#if USE_CPPLIB - if (yy_cur < yy_lim) -#endif - { - /* It's hard to preserve tokenization on '.' because - it could be a symbol by itself, or it could be the - start of a floating point number and cpp won't tell us. */ - register int c1 = token_getch (); - token_buffer[1] = c1; - if (c1 == '*') - { - value = DOT_STAR; - token_buffer[2] = 0; - goto done; - } - if (c1 == '.') - { - c1 = token_getch (); - if (c1 == '.') - { - token_buffer[2] = c1; - token_buffer[3] = 0; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); - } - if (ISDIGIT (c1)) - { - token_put_back (c1); - goto number; - } - token_put_back (c1); - } - value = '.'; - token_buffer[1] = 0; - break; - - case '0': case '1': - /* Optimize for most frequent case. */ - { - register int cond; - -#if USE_CPPLIB - cond = (yy_cur == yy_lim); -#else - register int c1 = token_getch (); - token_put_back (c1); - cond = (! ISALNUM (c1) && c1 != '.'); -#endif - if (cond) - { - yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node; - value = CONSTANT; - break; - } - /*FALLTHRU*/ - } - case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - number: - { - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - int overflow = 0; - - /* We actually store only HOST_BITS_PER_CHAR bits in each part. - The code below which fills the parts array assumes that a host - int is at least twice as wide as a host char, and that - HOST_BITS_PER_WIDE_INT is an even multiple of HOST_BITS_PER_CHAR. - Two HOST_WIDE_INTs is the largest int literal we can store. - In order to detect overflow below, the number of parts (TOTAL_PARTS) - must be exactly the number of parts needed to hold the bits - of two HOST_WIDE_INTs. */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2) - unsigned int parts[TOTAL_PARTS]; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON } - floatflag = NOT_FLOAT; - - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; - - p = token_buffer; - *p++ = c; - - if (c == '0') - { - *p++ = (c = token_getch ()); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = token_getch ()); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (ISALNUM (c) && c != 'l' && c != 'L' - && c != 'u' && c != 'U' - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT - || ((base != 16) && (c != 'f') && (c != 'F')) - || base == 16))) - { - if (c == '.') - { - if (base == 16 && pedantic) - pedwarn ("floating constant may not be in radix 16"); - if (floatflag == TOO_MANY_POINTS) - /* We have already emitted an error. Don't need another. */ - ; - else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - /* Avoid another error from atof by forcing all characters - from here on to be ignored. */ - p[-1] = '\0'; - } - else - floatflag = AFTER_POINT; - - if (base == 8) - base = 10; - *p++ = c = token_getch (); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. */ - if (p == token_buffer + 2 && !ISDIGIT (c)) - my_friendly_abort (990710); - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (ISDIGIT (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_EXPON; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (base == 16 && (c == 'p' || c == 'P')) - { - floatflag = AFTER_EXPON; - break; /* start of exponent */ - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; - } - - /* If the highest-order part overflows (gets larger than - a host char will hold) then the whole number has - overflowed. Record this and truncate the highest-order - part. */ - if (parts[TOTAL_PARTS - 1] >> HOST_BITS_PER_CHAR) - { - overflow = 1; - parts[TOTAL_PARTS - 1] &= (1 << HOST_BITS_PER_CHAR) - 1; - } - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = token_getch ()); - } - } - - /* This can happen on input like `int i = 0x;' */ - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the - string. */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type; - int imag, conversion_errno; - REAL_VALUE_TYPE value; - struct pf_args args; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((base == 10 && ((c == 'e') || (c == 'E'))) - || (base == 16 && (c == 'p' || c == 'P'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = token_getch (); - } - /* Exponent is decimal, even if string is a hex float. */ - if (! ISDIGIT (c)) - error ("floating constant exponent has no digits"); - while (ISDIGIT (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - } - } - if (base == 16 && floatflag != AFTER_EXPON) - error ("hexadecimal floating constant has no exponent"); - - *p = 0; - - /* Setup input for parse_float() */ - args.base = base; - args.p = p; - args.c = c; - - /* Convert string to a double, checking for overflow. */ - if (do_float_handler (parse_float, (PTR) &args)) - { - /* Receive output from parse_float() */ - value = args.value; - } - else - { - /* We got an exception from parse_float() */ - error ("floating constant out of range"); - value = dconst0; - } - - /* Receive output from parse_float() */ - c = args.c; - imag = args.imag; - type = args.type; - conversion_errno = args.conversion_errno; - -#ifdef ERANGE - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (conversion_errno == ERANGE && pedantic - && (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1))) - warning ("floating point number exceeds range of `double'"); -#endif - - /* If the result is not a number, assume it must have been - due to some error message above, so silently convert - it to a zero. */ - if (REAL_VALUE_ISNAN (value)) - value = dconst0; - - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (NULL_TREE, - convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - } - else - { - tree type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int spec_imag = 0; - int warn = 0; - int i; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic && ! in_system_header && warn_long_long) - pedwarn ("ISO C++ forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ISO C++ forbids imaginary numeric constants"); - spec_imag = 1; - } - else - break; - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - } - - /* If the literal overflowed, pedwarn about it now. */ - if (overflow) - { - warn = 1; - pedwarn ("integer constant is too large for this configuration of the compiler - truncated to %d bits", HOST_BITS_PER_WIDE_INT * 2); - } - - /* This is simplified by the fact that our constant - is always positive. */ - - high = low = 0; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } - - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; - - /* Calculate the ANSI type. */ - if (! spec_long && ! spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - type = integer_type_node; - else if (! spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - type = unsigned_type_node; - else if (! spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - type = long_integer_type_node; - else if (! spec_long_long - && int_fits_type_p (yylval.ttype, - long_unsigned_type_node)) - type = long_unsigned_type_node; - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - type = long_long_integer_type_node; - else if (int_fits_type_p (yylval.ttype, - long_long_unsigned_type_node)) - type = long_long_unsigned_type_node; - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - widest_integer_literal_type_node)) - type = widest_integer_literal_type_node; - else - type = widest_unsigned_literal_type_node; - - if (pedantic && !spec_long_long && !warn - && (TYPE_PRECISION (long_integer_type_node) - < TYPE_PRECISION (type))) - { - warn = 1; - pedwarn ("integer constant larger than the maximum value of an unsigned long int"); - } - - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal constant is so large that it is unsigned"); - - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (NULL_TREE, integer_zero_node, - convert (integer_type_node, - yylval.ttype)); - else - error ("complex integer constant is too wide for `__complex int'"); - } - else - TREE_TYPE (yylval.ttype) = type; - - - /* If it's still an integer (not a complex), and it doesn't - fit in the type we choose for it, then pedwarn. */ - - if (! warn - && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE - && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype))) - pedwarn ("integer constant is larger than the maximum value for its type"); - } - - token_put_back (c); - *p = 0; - - if (ISALNUM (c) || c == '.' || c == '_' || c == '$' - || ((c == '-' || c == '+') - && (p[-1] == 'e' || p[-1] == 'E'))) - error ("missing white space after number `%s'", token_buffer); - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - int chars_seen = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - max_chars = TYPE_PRECISION (integer_type_node) / width; - if (wide_flag) - width = WCHAR_TYPE_SIZE; - - while (1) - { - tryagain: - c = token_getch (); - - if (c == '\'' || c == EOF) - break; - - ++chars_seen; - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (ISPRINT (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C++ forbids newline in character constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 1; i <= longest_char; ++i) - { - if (i > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[i] = c; - char_len = local_mbtowc (& wc, - token_buffer + 1, - i); - if (char_len != -1) - break; - c = token_getch (); - } - if (char_len > 1) - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len < i) - token_put_back (c); - if (! wide_flag) - { - /* Merge character into result; ignore excess chars. */ - for (i = 1; i <= char_len; ++i) - { - if (i > max_chars) - break; - if (width < HOST_BITS_PER_INT) - result = (result << width) - | (token_buffer[i] - & ((1 << width) - 1)); - else - result = token_buffer[i]; - } - num_chars += char_len; - goto tryagain; - } - c = wc; - } - else - { - if (char_len == -1) - { - warning ("Ignoring invalid multibyte character"); - /* Replace all but the first byte. */ - for (--i; i > 1; --i) - token_put_back (token_buffer[i]); - wc = token_buffer[1]; - } -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (wc); -#else - c = wc; -#endif - } -#else /* ! MULTIBYTE_CHARS */ -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (c); -#endif -#endif /* ! MULTIBYTE_CHARS */ - } - - if (wide_flag) - { - if (chars_seen == 1) /* only keep the first one */ - result = c; - goto tryagain; - } - - /* Merge character into result; ignore excess chars. */ - num_chars += (width / TYPE_PRECISION (char_type_node)); - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - } - } - - if (c != '\'') - error ("malformatted character constant"); - else if (chars_seen == 0) - error ("empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - error ("character constant too long"); - } - else if (chars_seen != 1 && warn_multichar) - warning ("multi-character character constant"); - - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - if (num_bits == 0) - /* We already got an error; avoid invalid shift. */ - yylval.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - /* In C, a character constant has type 'int'; in C++, 'char'. */ - if (chars_seen <= 1) - TREE_TYPE (yylval.ttype) = char_type_node; - else - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - unsigned width = wide_flag ? WCHAR_TYPE_SIZE - : TYPE_PRECISION (char_type_node); -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - c = token_getch (); - p = token_buffer + 1; - - while (c != '"' && c != EOF) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C++ forbids newline in string constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 0; i < longest_char; ++i) - { - if (p + i >= token_buffer + maxtoken) - p = extend_token_buffer (p); - p[i] = c; - - char_len = local_mbtowc (& wc, p, i + 1); - if (char_len != -1) - break; - c = token_getch (); - } - if (char_len == -1) - { - warning ("Ignoring invalid multibyte character"); - /* Replace all except the first byte. */ - token_put_back (c); - for (--i; i > 0; --i) - token_put_back (p[i]); - char_len = 1; - } - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len <= i) - token_put_back (c); - if (! wide_flag) - { - p += (i + 1); - c = token_getch (); - continue; - } - c = wc; -#endif /* MULTIBYTE_CHARS */ - } - - /* Add this single character into the buffer either as a wchar_t - or as a single byte. */ - if (wide_flag) - { - unsigned width = TYPE_PRECISION (char_type_node); - unsigned bytemask = (1 << width) - 1; - int byte; - - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - - for (byte = 0; byte < WCHAR_BYTES; ++byte) - { - int value; - if (byte >= (int) sizeof (c)) - value = 0; - else - value = (c >> (byte * width)) & bytemask; - if (BYTES_BIG_ENDIAN) - p[WCHAR_BYTES - byte - 1] = value; - else - p[byte] = value; - } - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - } - - skipnewline: - c = token_getch (); - } - - /* Terminate the string value, either with a single byte zero - or with a wide zero. */ - if (wide_flag) - { - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - bzero (p, WCHAR_BYTES); - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = 0; - } - - if (c == EOF) - error ("Unterminated string constant"); - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1); - - if (wide_flag) - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - else - TREE_TYPE (yylval.ttype) = char_array_type_node; - - value = STRING; break; - } - - case '+': - case '-': - case '&': - case '|': - case ':': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = token_getch (); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - case ':': - value = SCOPE; - yylval.itype = 1; - goto done; - } - else if (c1 == '?' && (c == '<' || c == '>')) - { - token_buffer[3] = 0; - - c1 = token_getch (); - yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); - if (c1 == '=') - { - /* <?= or >?= expression. */ - token_buffer[2] = c1; - value = ASSIGN; - } - else - { - value = MIN_MAX; - token_put_back (c1); - } - if (pedantic) - pedwarn ("use of `operator %s' is not standard C++", - token_buffer); - goto done; - } - else - switch (c) - { - case '-': - if (c1 == '>') - { - c1 = token_getch (); - if (c1 == '*') - value = POINTSAT_STAR; - else - { - token_put_back (c1); - value = POINTSAT; - } - goto done; - } - break; - - /* digraphs */ - case ':': - if (c1 == '>') - { value = ']'; goto done; } - break; - case '<': - if (c1 == '%') - { value = '{'; indent_level++; goto done; } - if (c1 == ':') - { value = '['; goto done; } - break; - case '%': - if (c1 == '>') - { value = '}'; indent_level--; goto done; } - break; - } - - token_put_back (c1); - token_buffer[1] = 0; - - /* Here the C frontend changes < and > to ARITHCOMPARE. We don't - do that because of templates. */ - - value = c; - break; - } - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - case '{': - indent_level++; - value = c; - break; - - case '}': - indent_level--; - value = c; - break; - - default: - if (is_extended_char (c)) - goto letter; - value = c; - } - -done: -/* yylloc.last_line = lineno; */ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH - token_count[value] += 1; -#endif -#endif - - return value; -} - -int -is_rid (t) - tree t; -{ - return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); -} - #ifdef GATHER_STATISTICS /* The original for tree_node_kind is in the toplevel tree.c; changes there need to be brought into here, unless this were actually put into a header @@ -4839,33 +1661,6 @@ make_aggr_type (code) } void -dump_time_statistics () -{ - register tree prev = 0, decl, next; - int this_time = get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - - fprintf (stderr, "\n******\n"); - print_time ("header files (total)", header_time); - print_time ("main file (total)", this_time - body_time); - fprintf (stderr, "ratio = %g : 1\n", - (double)header_time / (double)(this_time - body_time)); - fprintf (stderr, "\n******\n"); - - for (decl = filename_times; decl; decl = next) - { - next = IDENTIFIER_GLOBAL_VALUE (decl); - SET_IDENTIFIER_GLOBAL_VALUE (decl, prev); - prev = decl; - } - - for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) - print_time (IDENTIFIER_POINTER (decl), - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl))); -} - -void compiler_error VPARAMS ((const char *msg, ...)) { #ifndef ANSI_PROTOTYPES @@ -4884,7 +1679,7 @@ compiler_error VPARAMS ((const char *msg, ...)) va_end (ap); error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); } - + /* Return the type-qualifier corresponding to the identifier given by RID. */ |