From: borutr Date: Fri, 1 Jun 2007 15:23:01 +0000 (+0000) Subject: * SDCPP synchronized with GCC CPP release version 4.2.0, X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=19b70bb7288cec628005857171ee3351a4ea4f44;p=fw%2Fsdcc * SDCPP synchronized with GCC CPP release version 4.2.0, currently the latest release: * support/cpp2/c-incpath.c, support/cpp2/c-incpath.h, support/cpp2/c-ppoutput.c, support/cpp2/cppdefault.c, support/cpp2/cppdefault.h, support/cpp2/except.h, support/cpp2/libcpp/directives.c, support/cpp2/libcpp/expr.c, support/cpp2/libcpp/files.c, support/cpp2/libcpp/include/cpplib.h, support/cpp2/libcpp/init.c, support/cpp2/libcpp/internal.h, support/cpp2/libcpp/lex.c, support/cpp2/libcpp/macro.c, support/cpp2/libcpp/mkdeps.c, support/cpp2/libiberty/getpwd.c, support/cpp2/libiberty/hashtab.c, support/cpp2/optc-gen.awk, support/cpp2/opth-gen.awk, support/cpp2/opts.c, support/cpp2/opts.h, support/cpp2/output.h, support/cpp2/prefix.c, support/cpp2/sdcpp-opts.c, support/cpp2/sdcpp.dsp, support/cpp2/sdcpp.opt, support/cpp2/system.h, support/cpp2/version.c: modified * support/cpp2/opts-common.c: added git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4824 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index bf19116f..18a169f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2007-06-01 Borut Razem + + * SDCPP synchronized with GCC CPP release version 4.2.0, + currently the latest release: + * support/cpp2/c-incpath.c, support/cpp2/c-incpath.h, + support/cpp2/c-ppoutput.c, support/cpp2/cppdefault.c, + support/cpp2/cppdefault.h, support/cpp2/except.h, + support/cpp2/libcpp/directives.c, support/cpp2/libcpp/expr.c, + support/cpp2/libcpp/files.c, support/cpp2/libcpp/include/cpplib.h, + support/cpp2/libcpp/init.c, support/cpp2/libcpp/internal.h, + support/cpp2/libcpp/lex.c, support/cpp2/libcpp/macro.c, + support/cpp2/libcpp/mkdeps.c, support/cpp2/libiberty/getpwd.c, + support/cpp2/libiberty/hashtab.c, support/cpp2/optc-gen.awk, + support/cpp2/opth-gen.awk, support/cpp2/opts.c, + support/cpp2/opts.h, support/cpp2/output.h, + support/cpp2/prefix.c, support/cpp2/sdcpp-opts.c, + support/cpp2/sdcpp.dsp, support/cpp2/sdcpp.opt, + support/cpp2/system.h, support/cpp2/version.c: modified + * support/cpp2/opts-common.c: added + 2007-06-01 Raphael Neider * device/lib/pic/libdev/pic12f683.c, diff --git a/support/cpp2/c-incpath.c b/support/cpp2/c-incpath.c index 014f8def..3933dee2 100644 --- a/support/cpp2/c-incpath.c +++ b/support/cpp2/c-incpath.c @@ -1,6 +1,7 @@ /* Set up combined include path chain for the preprocessor. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003. @@ -41,8 +42,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # define INO_T_COPY(DEST, SRC) (DEST) = (SRC) #endif +static const char dir_separator_str[] = { DIR_SEPARATOR, 0 }; + static void add_env_var_paths (const char *, int); -static void add_standard_paths (const char *, const char *, int); +static void add_standard_paths (const char *, const char *, const char *, int); static void free_path (struct cpp_dir *, int); static void merge_include_chains (cpp_reader *, int); static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *, @@ -105,7 +108,7 @@ add_env_var_paths (const char *env_var, int chain) path = xstrdup ("."); else { - path = xmalloc (q - p + 1); + path = XNEWVEC (char, q - p + 1); memcpy (path, p, q - p); path[q - p] = '\0'; } @@ -116,7 +119,8 @@ add_env_var_paths (const char *env_var, int chain) /* Append the standard include chain defined in cppdefault.c. */ static void -add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) +add_standard_paths (const char *sysroot, const char *iprefix, + const char *imultilib, int cxx_stdinc) { const struct default_include *p; size_t len; @@ -138,6 +142,8 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len)) { char *str = concat (iprefix, p->fname + len, NULL); + if (p->multilib && imultilib) + str = concat (str, dir_separator_str, imultilib, NULL); add_path (str, SYSTEM, p->cxx_aware, false); } } @@ -156,6 +162,9 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) else str = update_path (p->fname, p->component); + if (p->multilib && imultilib) + str = concat (str, dir_separator_str, imultilib, NULL); + add_path (str, SYSTEM, p->cxx_aware, false); } } @@ -336,7 +345,7 @@ add_path (char *path, int chain, int cxx_aware, bool user_supplied_p) if (*c == '\\') *c = '/'; #endif - p = xmalloc (sizeof (cpp_dir)); + p = XNEW (cpp_dir); p->next = NULL; p->name = path; if (chain == SYSTEM || chain == AFTER) @@ -353,8 +362,8 @@ add_path (char *path, int chain, int cxx_aware, bool user_supplied_p) removal, and registration with cpplib. */ void register_include_chains (cpp_reader *pfile, const char *sysroot, - const char *iprefix, int stdinc, int cxx_stdinc, - int verbose) + const char *iprefix, const char *imultilib, + int stdinc, int cxx_stdinc, int verbose) { static const char *const lang_env_vars[] = { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH", @@ -376,7 +385,7 @@ register_include_chains (cpp_reader *pfile, const char *sysroot, /* Finally chain on the standard directories. */ if (stdinc) - add_standard_paths (sysroot, iprefix, cxx_stdinc); + add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc); target_c_incpath.extra_includes (sysroot, iprefix, stdinc); diff --git a/support/cpp2/c-incpath.h b/support/cpp2/c-incpath.h index c309844c..3f268b79 100644 --- a/support/cpp2/c-incpath.h +++ b/support/cpp2/c-incpath.h @@ -1,5 +1,5 @@ /* Set up combined include path for the preprocessor. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -18,7 +18,8 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ extern void split_quote_chain (void); extern void add_path (char *, int, int, bool); extern void register_include_chains (cpp_reader *, const char *, - const char *, int, int, int); + const char *, const char *, + int, int, int); extern void add_cpp_dir_path (struct cpp_dir *, int); struct target_c_incpath_s { diff --git a/support/cpp2/c-ppoutput.c b/support/cpp2/c-ppoutput.c index 30dbc077..90855835 100644 --- a/support/cpp2/c-ppoutput.c +++ b/support/cpp2/c-ppoutput.c @@ -245,7 +245,8 @@ print_line (source_location src_loc, const char *special_flags) const struct line_map *map = linemap_lookup (&line_table, src_loc); size_t to_file_len = strlen (map->to_file); - unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1); + unsigned char *to_file_quoted = + (unsigned char *) alloca (to_file_len * 4 + 1); unsigned char *p; print.src_line = SOURCE_LINE (map, src_loc); @@ -322,7 +323,8 @@ cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node) fputs ((const char *) NODE_NAME (node), print.outf); putc ('\n', print.outf); - print.src_line++; + if (linemap_lookup (&line_table, line)->to_line != 0) + print.src_line++; } static void @@ -367,7 +369,8 @@ void pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) { size_t to_file_len = strlen (dir); - unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1); + unsigned char *to_file_quoted = + (unsigned char *) alloca (to_file_len * 4 + 1); unsigned char *p; /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ diff --git a/support/cpp2/cppdefault.c b/support/cpp2/cppdefault.c index 862ea12e..283742bf 100644 --- a/support/cpp2/cppdefault.c +++ b/support/cpp2/cppdefault.c @@ -1,6 +1,6 @@ /* CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -46,44 +46,44 @@ const struct default_include cpp_include_defaults[] = { #ifdef GPLUSPLUS_INCLUDE_DIR /* Pick up GNU C++ generic include files. */ - { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 }, + { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0, 0 }, #endif #ifdef GPLUSPLUS_TOOL_INCLUDE_DIR /* Pick up GNU C++ target-dependent include files. */ - { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0 }, + { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0, 1 }, #endif #ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR /* Pick up GNU C++ backward and deprecated include files. */ - { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0 }, + { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0, 0 }, #endif #ifdef LOCAL_INCLUDE_DIR /* /usr/local/include comes before the fixincluded header files. */ - { LOCAL_INCLUDE_DIR, 0, 0, 1, 1 }, + { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 }, #endif #ifdef PREFIX_INCLUDE_DIR - { PREFIX_INCLUDE_DIR, 0, 0, 1, 0 }, + { PREFIX_INCLUDE_DIR, 0, 0, 1, 0, 0 }, #endif #ifdef GCC_INCLUDE_DIR /* This is the dir for fixincludes and for gcc's private headers. */ - { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 }, + { GCC_INCLUDE_DIR, "GCC", 0, 0, 0, 0 }, #endif #ifdef CROSS_INCLUDE_DIR /* One place the target system's headers might be. */ - { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 }, + { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0, 0 }, #endif #ifdef TOOL_INCLUDE_DIR /* Another place the target system's headers might be. */ - { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0 }, + { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0, 0 }, #endif #ifdef SYSTEM_INCLUDE_DIR /* Some systems have an extra dir of include files. */ - { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1 }, + { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1, 0 }, #endif #ifdef STANDARD_INCLUDE_DIR /* /usr/include comes dead last. */ - { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1 }, + { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 0 }, #endif - { 0, 0, 0, 0, 0 } + { 0, 0, 0, 0, 0, 0 } }; #endif /* no INCLUDE_DEFAULTS */ diff --git a/support/cpp2/cppdefault.h b/support/cpp2/cppdefault.h index f5b38884..a3a24169 100644 --- a/support/cpp2/cppdefault.h +++ b/support/cpp2/cppdefault.h @@ -1,6 +1,6 @@ /* CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -43,6 +43,9 @@ struct default_include C++. */ const char add_sysroot; /* FNAME should be prefixed by cpp_SYSROOT. */ + const char multilib; /* FNAME should have the multilib path + specified with -imultilib + appended. */ }; extern const struct default_include cpp_include_defaults[]; diff --git a/support/cpp2/except.h b/support/cpp2/except.h index d5e391d9..1f96477f 100644 --- a/support/cpp2/except.h +++ b/support/cpp2/except.h @@ -52,7 +52,7 @@ extern bool can_throw_external_1 (int, bool); extern bool can_throw_external (rtx); /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ -extern void set_nothrow_function_flags (void); +extern unsigned int set_nothrow_function_flags (void); /* After initial rtl generation, call back to finish generating exception support code. */ @@ -65,7 +65,7 @@ extern rtx reachable_handlers (rtx); extern void maybe_remove_eh_handler (rtx); extern void convert_from_eh_region_ranges (void); -extern void convert_to_eh_region_ranges (void); +extern unsigned int convert_to_eh_region_ranges (void); extern void find_exception_handler_labels (void); extern bool current_function_has_exception_handlers (void); extern void output_function_exception_table (void); @@ -82,7 +82,8 @@ extern rtx expand_builtin_extend_pointer (tree); extern rtx get_exception_pointer (struct function *); extern rtx get_exception_filter (struct function *); typedef tree (*duplicate_eh_regions_map) (tree, void *); -extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, void *, int); +extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, + void *, int, int); extern void sjlj_emit_function_exit_after (rtx); extern void default_init_unwind_resume_libfunc (void); @@ -106,6 +107,8 @@ extern void collect_eh_region_array (void); extern void expand_resx_expr (tree); extern void verify_eh_tree (struct function *); extern void dump_eh_tree (FILE *, struct function *); +extern bool eh_region_outer_p (struct function *, int, int); +extern int eh_region_outermost (struct function *, int, int); /* tree-eh.c */ extern void add_stmt_to_eh_region_fn (struct function *, tree, int); @@ -173,3 +176,7 @@ struct throw_stmt_node GTY(()) extern struct htab *get_eh_throw_stmt_table (struct function *); extern void set_eh_throw_stmt_table (struct function *, struct htab *); + +#ifdef ENABLE_CHECKING +extern void verify_eh_throw_table_statements (void); +#endif diff --git a/support/cpp2/libcpp/directives.c b/support/cpp2/libcpp/directives.c index ac2127ac..7fb142e4 100644 --- a/support/cpp2/libcpp/directives.c +++ b/support/cpp2/libcpp/directives.c @@ -1,7 +1,6 @@ /* CPP Library. (Directive handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -46,11 +45,13 @@ struct pragma_entry struct pragma_entry *next; const cpp_hashnode *pragma; /* Name and length. */ bool is_nspace; - bool allow_expansion; bool is_internal; + bool is_deferred; + bool allow_expansion; union { pragma_cb handler; struct pragma_entry *space; + unsigned int ident; } u; }; @@ -106,13 +107,6 @@ static int undefine_macros (cpp_reader *, cpp_hashnode *, void *); static void do_include_common (cpp_reader *, enum include_type); static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *, const cpp_hashnode *); -static struct pragma_entry *insert_pragma_entry (cpp_reader *, - struct pragma_entry **, - const cpp_hashnode *, - pragma_cb, - bool, bool); -static void register_pragma (cpp_reader *, const char *, const char *, - pragma_cb, bool, bool); static int count_registered_pragmas (struct pragma_entry *); static char ** save_registered_pragmas (struct pragma_entry *, char **); static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *, @@ -278,7 +272,9 @@ start_directive (cpp_reader *pfile) static void end_directive (cpp_reader *pfile, int skip_line) { - if (CPP_OPTION (pfile, traditional)) + if (pfile->state.in_deferred_pragma) + ; + else if (CPP_OPTION (pfile, traditional)) { /* Revert change of prepare_directive_trad. */ pfile->state.prevent_expansion--; @@ -491,9 +487,6 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count) { cpp_push_buffer (pfile, (const uchar *) buf, count, /* from_stage3 */ true); - /* Disgusting hack. */ - if (dir_no == T_PRAGMA && pfile->buffer->prev) - pfile->buffer->file = pfile->buffer->prev->file; start_directive (pfile); /* This is a short-term fix to prevent a leading '#' being @@ -505,8 +498,6 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count) prepare_directive_trad (pfile); pfile->directive->handler (pfile); end_directive (pfile, 1); - if (dir_no == T_PRAGMA) - pfile->buffer->file = NULL; _cpp_pop_buffer (pfile); } @@ -1040,86 +1031,97 @@ lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma) return chain; } -/* Create and insert a pragma entry for NAME at the beginning of a - singly-linked CHAIN. If handler is NULL, it is a namespace, - otherwise it is a pragma and its handler. If INTERNAL is true - this pragma is being inserted by libcpp itself. */ +/* Create and insert a blank pragma entry at the beginning of a + singly-linked CHAIN. */ static struct pragma_entry * -insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain, - const cpp_hashnode *pragma, pragma_cb handler, - bool allow_expansion, bool internal) +new_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain) { struct pragma_entry *new_entry; new_entry = (struct pragma_entry *) _cpp_aligned_alloc (pfile, sizeof (struct pragma_entry)); - new_entry->pragma = pragma; - if (handler) - { - new_entry->is_nspace = 0; - new_entry->u.handler = handler; - } - else - { - new_entry->is_nspace = 1; - new_entry->u.space = NULL; - } - new_entry->allow_expansion = allow_expansion; - new_entry->is_internal = internal; + memset (new_entry, 0, sizeof (struct pragma_entry)); new_entry->next = *chain; + *chain = new_entry; return new_entry; } /* Register a pragma NAME in namespace SPACE. If SPACE is null, it - goes in the global namespace. HANDLER is the handler it will call, - which must be non-NULL. If ALLOW_EXPANSION is set, allow macro - expansion while parsing pragma NAME. INTERNAL is true if this is a - pragma registered by cpplib itself, false if it is registered via - cpp_register_pragma */ -static void -register_pragma (cpp_reader *pfile, const char *space, const char *name, - pragma_cb handler, bool allow_expansion, bool internal) + goes in the global namespace. */ +static struct pragma_entry * +register_pragma_1 (cpp_reader *pfile, const char *space, const char *name, + bool allow_name_expansion) { struct pragma_entry **chain = &pfile->pragmas; struct pragma_entry *entry; const cpp_hashnode *node; - if (!handler) - abort (); - if (space) { node = cpp_lookup (pfile, U space, strlen (space)); entry = lookup_pragma_entry (*chain, node); if (!entry) - entry = insert_pragma_entry (pfile, chain, node, NULL, - allow_expansion, internal); + { + entry = new_pragma_entry (pfile, chain); + entry->pragma = node; + entry->is_nspace = true; + entry->allow_expansion = allow_name_expansion; + } else if (!entry->is_nspace) goto clash; + else if (entry->allow_expansion != allow_name_expansion) + { + cpp_error (pfile, CPP_DL_ICE, + "registering pragmas in namespace \"%s\" with mismatched " + "name expansion", space); + return NULL; + } chain = &entry->u.space; } + else if (allow_name_expansion) + { + cpp_error (pfile, CPP_DL_ICE, + "registering pragma \"%s\" with name expansion " + "and no namespace", name); + return NULL; + } /* Check for duplicates. */ node = cpp_lookup (pfile, U name, strlen (name)); entry = lookup_pragma_entry (*chain, node); - if (entry) + if (entry == NULL) { - if (entry->is_nspace) - clash: - cpp_error (pfile, CPP_DL_ICE, - "registering \"%s\" as both a pragma and a pragma namespace", - NODE_NAME (node)); - else if (space) - cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered", - space, name); - else - cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name); + entry = new_pragma_entry (pfile, chain); + entry->pragma = node; + return entry; } + + if (entry->is_nspace) + clash: + cpp_error (pfile, CPP_DL_ICE, + "registering \"%s\" as both a pragma and a pragma namespace", + NODE_NAME (node)); + else if (space) + cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered", + space, name); else - insert_pragma_entry (pfile, chain, node, handler, allow_expansion, - internal); + cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name); + + return NULL; +} + +/* Register a cpplib internal pragma SPACE NAME with HANDLER. */ +static void +register_pragma_internal (cpp_reader *pfile, const char *space, + const char *name, pragma_cb handler) +{ + struct pragma_entry *entry; + + entry = register_pragma_1 (pfile, space, name, false); + entry->is_internal = true; + entry->u.handler = handler; } /* Register a pragma NAME in namespace SPACE. If SPACE is null, it @@ -1131,22 +1133,53 @@ void cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, pragma_cb handler, bool allow_expansion) { - register_pragma (pfile, space, name, handler, allow_expansion, false); + struct pragma_entry *entry; + + if (!handler) + { + cpp_error (pfile, CPP_DL_ICE, "registering pragma with NULL handler"); + return; + } + + entry = register_pragma_1 (pfile, space, name, false); + if (entry) + { + entry->allow_expansion = allow_expansion; + entry->u.handler = handler; + } } +/* Similarly, but create mark the pragma for deferred processing. + When found, a CPP_PRAGMA token will be insertted into the stream + with IDENT in the token->u.pragma slot. */ +void +cpp_register_deferred_pragma (cpp_reader *pfile, const char *space, + const char *name, unsigned int ident, + bool allow_expansion, bool allow_name_expansion) +{ + struct pragma_entry *entry; + + entry = register_pragma_1 (pfile, space, name, allow_name_expansion); + if (entry) + { + entry->is_deferred = true; + entry->allow_expansion = allow_expansion; + entry->u.ident = ident; + } +} + /* Register the pragmas the preprocessor itself handles. */ void _cpp_init_internal_pragmas (cpp_reader *pfile) { /* Pragmas in the global namespace. */ - register_pragma (pfile, 0, "once", do_pragma_once, false, true); + register_pragma_internal (pfile, 0, "once", do_pragma_once); /* New GCC-specific pragmas should be put in the GCC namespace. */ - register_pragma (pfile, "GCC", "poison", do_pragma_poison, false, true); - register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, - false, true); - register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, - false, true); + register_pragma_internal (pfile, "GCC", "poison", do_pragma_poison); + register_pragma_internal (pfile, "GCC", "system_header", + do_pragma_system_header); + register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency); } /* Return the number of registered pragmas in PE. */ @@ -1224,130 +1257,85 @@ _cpp_restore_pragma_names (cpp_reader *pfile, char **saved) front end. C99 defines three pragmas and says that no macro expansion is to be performed on them; whether or not macro expansion happens for other pragmas is implementation defined. - This implementation never macro-expands the text after #pragma. - - The library user has the option of deferring execution of - #pragmas not handled by cpplib, in which case they are converted - to CPP_PRAGMA tokens and inserted into the output stream. */ + This implementation allows for a mix of both, since GCC did not + traditionally macro expand its (few) pragmas, whereas OpenMP + specifies that macro expansion should happen. */ static void do_pragma (cpp_reader *pfile) { const struct pragma_entry *p = NULL; const cpp_token *token, *pragma_token = pfile->cur_token; + cpp_token ns_token; unsigned int count = 1; - /* Save the current position so that defer_pragmas mode can - copy the entire current line to a string. It will not work - to use _cpp_backup_tokens as that does not reverse buffer->cur. */ - const uchar *line_start = CPP_BUFFER (pfile)->cur; - pfile->state.prevent_expansion++; token = cpp_get_token (pfile); + ns_token = *token; if (token->type == CPP_NAME) { p = lookup_pragma_entry (pfile->pragmas, token->val.node); if (p && p->is_nspace) { - count = 2; + bool allow_name_expansion = p->allow_expansion; + if (allow_name_expansion) + pfile->state.prevent_expansion--; token = cpp_get_token (pfile); if (token->type == CPP_NAME) p = lookup_pragma_entry (p->u.space, token->val.node); else p = NULL; + if (allow_name_expansion) + pfile->state.prevent_expansion++; + count = 2; } } if (p) { - if (p->is_internal || !CPP_OPTION (pfile, defer_pragmas)) + if (p->is_deferred) + { + pfile->directive_result.src_loc = pragma_token->src_loc; + pfile->directive_result.type = CPP_PRAGMA; + pfile->directive_result.flags = pragma_token->flags; + pfile->directive_result.val.pragma = p->u.ident; + pfile->state.in_deferred_pragma = true; + pfile->state.pragma_allow_expansion = p->allow_expansion; + if (!p->allow_expansion) + pfile->state.prevent_expansion++; + } + else { - /* Since the handler below doesn't get the line number, that it - might need for diagnostics, make sure it has the right + /* Since the handler below doesn't get the line number, that + it might need for diagnostics, make sure it has the right numbers in place. */ if (pfile->cb.line_change) (*pfile->cb.line_change) (pfile, pragma_token, false); - /* Never expand macros if handling a deferred pragma, since - the macro definitions now applicable may be different - from those at the point the pragma appeared. */ - if (p->allow_expansion && !pfile->state.in_deferred_pragma) + if (p->allow_expansion) pfile->state.prevent_expansion--; (*p->u.handler) (pfile); - if (p->allow_expansion && !pfile->state.in_deferred_pragma) + if (p->allow_expansion) pfile->state.prevent_expansion++; } - else - { - /* Squirrel away the pragma text. Pragmas are - newline-terminated. */ - const uchar *line_end; - uchar *s, c, cc; - cpp_string body; - cpp_token *ptok; - - for (line_end = line_start; (c = *line_end) != '\n'; line_end++) - if (c == '"' || c == '\'') - { - /* Skip over string literal. */ - do - { - cc = *++line_end; - if (cc == '\\' && line_end[1] != '\n') - line_end++; - else if (cc == '\n') - { - line_end--; - break; - } - } - while (cc != c); - } - else if (c == '/') - { - if (line_end[1] == '*') - { - /* Skip over C block comment, unless it is multi-line. - When encountering multi-line block comment, terminate - the pragma token right before that block comment. */ - const uchar *le = line_end + 2; - while (*le != '\n') - if (*le++ == '*' && *le == '/') - { - line_end = le; - break; - } - if (line_end < le) - break; - } - else if (line_end[1] == '/' - && (CPP_OPTION (pfile, cplusplus_comments) - || cpp_in_system_header (pfile))) - { - line_end += 2; - while (*line_end != '\n') - line_end++; - break; - } - } - - body.len = (line_end - line_start) + 1; - s = _cpp_unaligned_alloc (pfile, body.len + 1); - memcpy (s, line_start, body.len - 1); - s[body.len - 1] = '\n'; - s[body.len] = '\0'; - body.text = s; - - /* Create a CPP_PRAGMA token. */ - ptok = &pfile->directive_result; - ptok->src_loc = pragma_token->src_loc; - ptok->type = CPP_PRAGMA; - ptok->flags = pragma_token->flags | NO_EXPAND; - ptok->val.str = body; - } } else if (pfile->cb.def_pragma) { - _cpp_backup_tokens (pfile, count); + if (count == 1 || pfile->context->prev == NULL) + _cpp_backup_tokens (pfile, count); + else + { + /* Invalid name comes from macro expansion, _cpp_backup_tokens + won't allow backing 2 tokens. */ + /* ??? The token buffer is leaked. Perhaps if def_pragma hook + reads both tokens, we could perhaps free it, but if it doesn't, + we don't know the exact lifespan. */ + cpp_token *toks = XNEWVEC (cpp_token, 2); + toks[0] = ns_token; + toks[0].flags |= NO_EXPAND; + toks[1] = *token; + toks[1].flags |= NO_EXPAND; + _cpp_push_token_context (pfile, NULL, toks, 2); + } pfile->cb.def_pragma (pfile, pfile->directive_line); } @@ -1490,6 +1478,11 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) { const unsigned char *src, *limit; char *dest, *result; + cpp_context *saved_context; + cpp_token *saved_cur_token; + tokenrun *saved_cur_run; + cpp_token *toks; + int count; dest = result = (char *) alloca (in->len - 1); src = in->text + 1 + (in->text[0] == 'L'); @@ -1511,36 +1504,85 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) Something like line-at-a-time lexing should remove the need for this. */ - { - cpp_context *saved_context = pfile->context; - cpp_token *saved_cur_token = pfile->cur_token; - tokenrun *saved_cur_run = pfile->cur_run; - - pfile->context = XNEW (cpp_context); - pfile->context->macro = 0; - pfile->context->prev = 0; - run_directive (pfile, T_PRAGMA, result, dest - result); - XDELETE (pfile->context); - pfile->context = saved_context; - pfile->cur_token = saved_cur_token; - pfile->cur_run = saved_cur_run; - } + saved_context = pfile->context; + saved_cur_token = pfile->cur_token; + saved_cur_run = pfile->cur_run; - /* See above comment. For the moment, we'd like + pfile->context = XNEW (cpp_context); + pfile->context->macro = 0; + pfile->context->prev = 0; + pfile->context->next = 0; + + /* Inline run_directive, since we need to delay the _cpp_pop_buffer + until we've read all of the tokens that we want. */ + cpp_push_buffer (pfile, (const uchar *) result, dest - result, + /* from_stage3 */ true); + /* ??? Antique Disgusting Hack. What does this do? */ + if (pfile->buffer->prev) + pfile->buffer->file = pfile->buffer->prev->file; - token1 _Pragma ("foo") token2 + start_directive (pfile); + _cpp_clean_line (pfile); + do_pragma (pfile); + end_directive (pfile, 1); - to be output as + /* We always insert at least one token, the directive result. It'll + either be a CPP_PADDING or a CPP_PRAGMA. In the later case, we + need to insert *all* of the tokens, including the CPP_PRAGMA_EOL. */ + + /* If we're not handling the pragma internally, read all of the tokens from + the string buffer now, while the string buffer is still installed. */ + /* ??? Note that the token buffer allocated here is leaked. It's not clear + to me what the true lifespan of the tokens are. It would appear that + the lifespan is the entire parse of the main input stream, in which case + this may not be wrong. */ + if (pfile->directive_result.type == CPP_PRAGMA) + { + int maxcount; - token1 - # 7 "file.c" - #pragma foo - # 7 "file.c" - token2 + count = 1; + maxcount = 50; + toks = XNEWVEC (cpp_token, maxcount); + toks[0] = pfile->directive_result; - Getting the line markers is a little tricky. */ - if (pfile->cb.line_change) - pfile->cb.line_change (pfile, pfile->cur_token, false); + do + { + if (count == maxcount) + { + maxcount = maxcount * 3 / 2; + toks = XRESIZEVEC (cpp_token, toks, maxcount); + } + toks[count] = *cpp_get_token (pfile); + /* Macros have been already expanded by cpp_get_token + if the pragma allowed expansion. */ + toks[count++].flags |= NO_EXPAND; + } + while (toks[count-1].type != CPP_PRAGMA_EOL); + } + else + { + count = 1; + toks = XNEW (cpp_token); + toks[0] = pfile->directive_result; + + /* If we handled the entire pragma internally, make sure we get the + line number correct for the next token. */ + if (pfile->cb.line_change) + pfile->cb.line_change (pfile, pfile->cur_token, false); + } + + /* Finish inlining run_directive. */ + pfile->buffer->file = NULL; + _cpp_pop_buffer (pfile); + + /* Reset the old macro state before ... */ + XDELETE (pfile->context); + pfile->context = saved_context; + pfile->cur_token = saved_cur_token; + pfile->cur_run = saved_cur_run; + + /* ... inserting the new tokens we collected. */ + _cpp_push_token_context (pfile, NULL, toks, count); } /* Handle the _Pragma operator. */ @@ -1557,35 +1599,6 @@ _cpp_do__Pragma (cpp_reader *pfile) "_Pragma takes a parenthesized string literal"); } -/* Handle a pragma that the front end deferred until now. */ -void -cpp_handle_deferred_pragma (cpp_reader *pfile, const cpp_string *s) -{ - cpp_context *saved_context = pfile->context; - cpp_token *saved_cur_token = pfile->cur_token; - tokenrun *saved_cur_run = pfile->cur_run; - bool saved_defer_pragmas = CPP_OPTION (pfile, defer_pragmas); - void (*saved_line_change) (cpp_reader *, const cpp_token *, int) - = pfile->cb.line_change; - - pfile->context = XNEW (cpp_context); - pfile->context->macro = 0; - pfile->context->prev = 0; - pfile->cb.line_change = NULL; - pfile->state.in_deferred_pragma = true; - CPP_OPTION (pfile, defer_pragmas) = false; - - run_directive (pfile, T_PRAGMA, (const char *)s->text, s->len); - - XDELETE (pfile->context); - pfile->context = saved_context; - pfile->cur_token = saved_cur_token; - pfile->cur_run = saved_cur_run; - pfile->cb.line_change = saved_line_change; - pfile->state.in_deferred_pragma = false; - CPP_OPTION (pfile, defer_pragmas) = saved_defer_pragmas; -} - /* Handle #ifdef. */ static void do_ifdef (cpp_reader *pfile) diff --git a/support/cpp2/libcpp/expr.c b/support/cpp2/libcpp/expr.c index 32b17238..574b85ff 100644 --- a/support/cpp2/libcpp/expr.c +++ b/support/cpp2/libcpp/expr.c @@ -82,7 +82,7 @@ static void check_promotion (cpp_reader *, const struct op *); static unsigned int interpret_float_suffix (const uchar *s, size_t len) { - size_t f = 0, l = 0, i = 0; + size_t f = 0, l = 0, i = 0, d = 0; while (len--) switch (s[len]) @@ -91,6 +91,12 @@ interpret_float_suffix (const uchar *s, size_t len) case 'l': case 'L': l++; break; case 'i': case 'I': case 'j': case 'J': i++; break; + case 'd': case 'D': + /* Disallow fd, ld suffixes. */ + if (d && (f || l)) + return 0; + d++; + break; default: return 0; } @@ -98,9 +104,14 @@ interpret_float_suffix (const uchar *s, size_t len) if (f + l > 1 || i > 1) return 0; + /* Allow dd, df, dl suffixes for decimal float constants. */ + if (d && ((d + f + l != 2) || i)) + return 0; + return ((i ? CPP_N_IMAGINARY : 0) | (f ? CPP_N_SMALL : - l ? CPP_N_LARGE : CPP_N_MEDIUM)); + l ? CPP_N_LARGE : CPP_N_MEDIUM) + | (d ? CPP_N_DFLOAT : 0)); } /* Subroutine of cpp_classify_number. S points to an integer suffix @@ -250,6 +261,15 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) "traditional C rejects the \"%.*s\" suffix", (int) (limit - str), str); + /* Radix must be 10 for decimal floats. */ + if ((result & CPP_N_DFLOAT) && radix != 10) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid suffix \"%.*s\" with hexadecimal floating constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } + result |= CPP_N_FLOATING; } else @@ -648,9 +668,6 @@ static const struct cpp_operator /* RSHIFT */ {13, LEFT_ASSOC}, /* LSHIFT */ {13, LEFT_ASSOC}, - /* MIN */ {10, LEFT_ASSOC | CHECK_PROMOTION}, - /* MAX */ {10, LEFT_ASSOC | CHECK_PROMOTION}, - /* COMPL */ {16, NO_L_OPERAND}, /* AND_AND */ {6, LEFT_ASSOC}, /* OR_OR */ {5, LEFT_ASSOC}, @@ -862,8 +879,6 @@ reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op) case CPP_MINUS: case CPP_RSHIFT: case CPP_LSHIFT: - case CPP_MIN: - case CPP_MAX: case CPP_COMMA: top[-1].value = num_binary_op (pfile, top[-1].value, top->value, top->op); @@ -1289,7 +1304,6 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) { cpp_num result; size_t precision = CPP_OPTION (pfile, precision); - bool gte; size_t n; switch (op) @@ -1316,21 +1330,6 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) lhs = num_rshift (lhs, precision, n); break; - /* Min / Max. */ - case CPP_MIN: - case CPP_MAX: - { - bool unsignedp = lhs.unsignedp || rhs.unsignedp; - - gte = num_greater_eq (lhs, rhs, precision); - if (op == CPP_MIN) - gte = !gte; - if (!gte) - lhs = rhs; - lhs.unsignedp = unsignedp; - } - break; - /* Arithmetic. */ case CPP_MINUS: rhs = num_negate (rhs, precision); diff --git a/support/cpp2/libcpp/files.c b/support/cpp2/libcpp/files.c index 702aa4c8..57643822 100644 --- a/support/cpp2/libcpp/files.c +++ b/support/cpp2/libcpp/files.c @@ -1158,6 +1158,13 @@ _cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file) } } +/* Inteface to file statistics record in _cpp_file structure. */ +struct stat * +_cpp_get_file_stat (_cpp_file *file) +{ + return &file->st; +} + /* Set the include chain for "" to QUOTE, for <> to BRACKET. If QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the directory of the including file. diff --git a/support/cpp2/libcpp/include/cpplib.h b/support/cpp2/libcpp/include/cpplib.h index 4e879b9d..dc02b6b7 100644 --- a/support/cpp2/libcpp/include/cpplib.h +++ b/support/cpp2/libcpp/include/cpplib.h @@ -51,7 +51,10 @@ struct _cpp_file; The first group, to CPP_LAST_EQ, can be immediately followed by an '='. The lexer needs operators ending in '=', like ">>=", to be in - the same order as their counterparts without the '=', like ">>". */ + the same order as their counterparts without the '=', like ">>". + + See the cpp_operator table optab in expr.c if you change the order or + add or remove anything in the first group. */ #define TTYPE_TABLE \ OP(EQ, "=") \ @@ -68,8 +71,6 @@ struct _cpp_file; OP(XOR, "^") \ OP(RSHIFT, ">>") \ OP(LSHIFT, "<<") \ - OP(MIN, "?") \ \ OP(COMPL, "~") \ OP(AND_AND, "&&") /* logical */ \ @@ -97,8 +98,6 @@ struct _cpp_file; OP(XOR_EQ, "^=") \ OP(RSHIFT_EQ, ">>=") \ OP(LSHIFT_EQ, "<<=") \ - OP(MIN_EQ, "?=") \ /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ OP(HASH, "#") /* digraphs */ \ OP(PASTE, "##") \ @@ -134,7 +133,8 @@ struct _cpp_file; TK(COMMENT, LITERAL) /* Only if output comments. */ \ /* SPELL_LITERAL happens to DTRT. */ \ TK(MACRO_ARG, NONE) /* Macro argument. */ \ - TK(PRAGMA, NONE) /* Only if deferring pragmas */ \ + TK(PRAGMA, NONE) /* Only for deferred pragmas. */ \ + TK(PRAGMA_EOL, NONE) /* End-of-line for deferred pragmas. */ \ TK(PADDING, NONE) /* Whitespace for -E. */ \ \ /* SDCC _asm specific */ \ @@ -148,9 +148,9 @@ enum cpp_ttype N_TTYPES, /* Positions in the table. */ - CPP_LAST_EQ = CPP_MAX, + CPP_LAST_EQ = CPP_LSHIFT, CPP_FIRST_DIGRAPH = CPP_HASH, - CPP_LAST_PUNCTUATOR= CPP_DOT_STAR, + CPP_LAST_PUNCTUATOR= CPP_ATSIGN, CPP_LAST_CPP_OP = CPP_LESS_EQ }; #undef OP @@ -175,6 +175,8 @@ struct cpp_string GTY(()) #define NAMED_OP (1 << 4) /* C++ named operators. */ #define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ #define BOL (1 << 6) /* Token at beginning of line. */ +#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, + set in c-lex.c. */ /* Specify which field, if any, of the cpp_token union is used. */ @@ -183,6 +185,7 @@ enum cpp_token_fld_kind { CPP_TOKEN_FLD_SOURCE, CPP_TOKEN_FLD_STR, CPP_TOKEN_FLD_ARG_NO, + CPP_TOKEN_FLD_PRAGMA, CPP_TOKEN_FLD_NONE }; @@ -212,6 +215,9 @@ struct cpp_token GTY(()) /* Argument no. for a CPP_MACRO_ARG. */ unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no; + + /* Caller-supplied identifier for a CPP_PRAGMA. */ + unsigned int GTY ((tag ("CPP_TOKEN_FLD_PRAGMA"))) pragma; } GTY ((desc ("cpp_token_val_index (&%1)"))) val; }; @@ -452,10 +458,6 @@ struct cpp_options /* Nonzero means __STDC__ should have the value 0 in system headers. */ unsigned char stdc_0_in_system_headers; - /* True means return pragmas as tokens rather than processing - them directly. */ - bool defer_pragmas; - /* True means error callback should be used for diagnostics. */ bool client_diagnostic; }; @@ -572,7 +574,8 @@ enum builtin_type BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ BT_TIME, /* `__TIME__' */ BT_STDC, /* `__STDC__' */ - BT_PRAGMA /* `_Pragma' operator */ + BT_PRAGMA, /* `_Pragma' operator */ + BT_TIMESTAMP /* `__TIMESTAMP__' */ }; #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) @@ -691,7 +694,8 @@ extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *, unsigned char *, bool); extern void cpp_register_pragma (cpp_reader *, const char *, const char *, void (*) (cpp_reader *), bool); -extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *); +extern void cpp_register_deferred_pragma (cpp_reader *, const char *, + const char *, unsigned, bool, bool); extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, const cpp_token *); extern const cpp_token *cpp_get_token (cpp_reader *); @@ -763,6 +767,7 @@ struct cpp_num #define CPP_N_UNSIGNED 0x1000 /* Properties. */ #define CPP_N_IMAGINARY 0x2000 +#define CPP_N_DFLOAT 0x4000 /* Classify a CPP_NUMBER token. The return value is a combination of the flags from the above sets. */ diff --git a/support/cpp2/libcpp/init.c b/support/cpp2/libcpp/init.c index b0544115..20e4545c 100644 --- a/support/cpp2/libcpp/init.c +++ b/support/cpp2/libcpp/init.c @@ -303,6 +303,7 @@ struct builtin #define B(n, t) { DSC(n), t } static const struct builtin builtin_array[] = { + B("__TIMESTAMP__", BT_TIMESTAMP), B("__TIME__", BT_TIME), B("__DATE__", BT_DATE), B("__FILE__", BT_FILE), diff --git a/support/cpp2/libcpp/internal.h b/support/cpp2/libcpp/internal.h index 960f153e..d8e07e38 100644 --- a/support/cpp2/libcpp/internal.h +++ b/support/cpp2/libcpp/internal.h @@ -205,9 +205,6 @@ struct lexer_state /* Nonzero to prevent macro expansion. */ unsigned char prevent_expansion; - /* Nonzero when handling a deferred pragma. */ - unsigned char in_deferred_pragma; - /* Nonzero when parsing arguments to a function-like macro. */ unsigned char parsing_args; @@ -217,6 +214,12 @@ struct lexer_state /* Nonzero to skip evaluating part of an expression. */ unsigned int skip_eval; + + /* Nonzero when handling a deferred pragma. */ + unsigned char in_deferred_pragma; + + /* Nonzero if the deferred pragma being handled allows macro expansion. */ + unsigned char pragma_allow_expansion; }; /* Special nodes - identifiers with predefined significance. */ @@ -263,6 +266,10 @@ struct cpp_buffer Used for include_next and to record control macros. */ struct _cpp_file *file; + /* Saved value of __TIMESTAMP__ macro - date and time of last modification + of the assotiated file. */ + const unsigned char *timestamp; + /* Value of if_stack at start of this file. Used to prohibit unmatched #endif (etc) in an include file. */ struct if_stack *if_stack; @@ -498,7 +505,10 @@ extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *, unsigned int); extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, cpp_hashnode *); -int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); +extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); +extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *, + const cpp_token *, unsigned int); + /* In identifiers.c */ extern void _cpp_init_hashtable (cpp_reader *, hash_table *); extern void _cpp_destroy_hashtable (cpp_reader *); @@ -520,6 +530,7 @@ extern void _cpp_cleanup_files (cpp_reader *); extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *); extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f); extern bool _cpp_read_file_entries (cpp_reader *, FILE *); +extern struct stat *_cpp_get_file_stat (_cpp_file *); /* In expr.c */ extern bool _cpp_parse_expr (cpp_reader *); diff --git a/support/cpp2/libcpp/lex.c b/support/cpp2/libcpp/lex.c index be96d97b..22dc7e7e 100644 --- a/support/cpp2/libcpp/lex.c +++ b/support/cpp2/libcpp/lex.c @@ -937,6 +937,10 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) cpp_error (pfile, CPP_DL_WARNING, "null character(s) preserved in literal"); + if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character", + (int) terminator); + pfile->buffer->cur = cur; create_literal (pfile, token, base, cur - base, type); } @@ -1111,24 +1115,24 @@ _cpp_lex_token (cpp_reader *pfile) /* 6.10.3 p 11: Directives in a list of macro arguments gives undefined behavior. This implementation handles the directive as normal. */ - && pfile->state.parsing_args != 1 - && _cpp_handle_directive (pfile, result->flags & PREV_WHITE)) + && pfile->state.parsing_args != 1) { - if (pfile->directive_result.type == CPP_PADDING) - continue; - else + if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE)) { + if (pfile->directive_result.type == CPP_PADDING) + continue; result = &pfile->directive_result; - break; } } + else if (pfile->state.in_deferred_pragma) + result = &pfile->directive_result; if (pfile->cb.line_change && !pfile->state.skipping) pfile->cb.line_change (pfile, result, pfile->state.parsing_args); } /* We don't skip tokens in directives. */ - if (pfile->state.in_directive) + if (pfile->state.in_directive || pfile->state.in_deferred_pragma) break; /* Outside a directive, invalidate controlling macros. At file @@ -1222,6 +1226,14 @@ _cpp_lex_direct (cpp_reader *pfile) buffer = pfile->buffer; if (buffer->need_line) { + if (pfile->state.in_deferred_pragma) + { + result->type = CPP_PRAGMA_EOL; + pfile->state.in_deferred_pragma = false; + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion--; + return result; + } if (!_cpp_get_fresh_line (pfile)) { result->type = CPP_EOF; @@ -1401,11 +1413,6 @@ _cpp_lex_direct (cpp_reader *pfile) buffer->cur++; IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT); } - else if (*buffer->cur == '?' && CPP_OPTION (pfile, cplusplus)) - { - buffer->cur++; - IF_NEXT_IS ('=', CPP_MIN_EQ, CPP_MIN); - } else if (CPP_OPTION (pfile, digraphs)) { if (*buffer->cur == ':') @@ -1432,11 +1439,6 @@ _cpp_lex_direct (cpp_reader *pfile) buffer->cur++; IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT); } - else if (*buffer->cur == '?' && CPP_OPTION (pfile, cplusplus)) - { - buffer->cur++; - IF_NEXT_IS ('=', CPP_MAX_EQ, CPP_MAX); - } break; case '%': @@ -1824,8 +1826,8 @@ cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1, switch (a) { - case CPP_GREATER: return c == '>' || c == '?'; - case CPP_LESS: return c == '<' || c == '?' || c == '%' || c == ':'; + case CPP_GREATER: return c == '>'; + case CPP_LESS: return c == '<' || c == '%' || c == ':'; case CPP_PLUS: return c == '+'; case CPP_MINUS: return c == '-' || c == '>'; case CPP_DIV: return c == '/' || c == '*'; /* Comments. */ @@ -2057,7 +2059,7 @@ cpp_token_val_index (cpp_token *tok) else if (tok->type == CPP_PADDING) return CPP_TOKEN_FLD_SOURCE; else if (tok->type == CPP_PRAGMA) - return CPP_TOKEN_FLD_STR; + return CPP_TOKEN_FLD_PRAGMA; /* else fall through */ default: return CPP_TOKEN_FLD_NONE; diff --git a/support/cpp2/libcpp/macro.c b/support/cpp2/libcpp/macro.c index b4143110..c33b7fce 100644 --- a/support/cpp2/libcpp/macro.c +++ b/support/cpp2/libcpp/macro.c @@ -42,8 +42,6 @@ struct macro_arg static int enter_macro_context (cpp_reader *, cpp_hashnode *); static int builtin_macro (cpp_reader *, cpp_hashnode *); -static void push_token_context (cpp_reader *, cpp_hashnode *, - const cpp_token *, unsigned int); static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, const cpp_token **, unsigned int); static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *); @@ -125,6 +123,44 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) NODE_NAME (node)); break; + case BT_TIMESTAMP: + { + cpp_buffer *pbuffer = cpp_get_buffer (pfile); + if (pbuffer->timestamp == NULL) + { + /* Initialize timestamp value of the assotiated file. */ + struct _cpp_file *file = cpp_get_file (pbuffer); + if (file) + { + /* Generate __TIMESTAMP__ string, that represents + the date and time of the last modification + of the current source file. The string constant + looks like "Sun Sep 16 01:03:52 1973". */ + struct tm *tb = NULL; + struct stat *st = _cpp_get_file_stat (file); + if (st) + tb = localtime (&st->st_mtime); + if (tb) + { + char *str = asctime (tb); + size_t len = strlen (str); + unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); + buf[0] = '"'; + strcpy ((char *) buf + 1, str); + buf[len] = '"'; + pbuffer->timestamp = buf; + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine file timestamp"); + pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\""; + } + } + } + result = pbuffer->timestamp; + } + break; case BT_FILE: case BT_BASE_FILE: { @@ -257,13 +293,6 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) return 0; _cpp_do__Pragma (pfile); - if (pfile->directive_result.type == CPP_PRAGMA) - { - cpp_token *tok = _cpp_temp_token (pfile); - *tok = pfile->directive_result; - push_token_context (pfile, NULL, tok, 1); - } - return 1; } @@ -278,7 +307,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) /* Set pfile->cur_token as required by _cpp_lex_direct. */ pfile->cur_token = _cpp_temp_token (pfile); - push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); + _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); if (pfile->buffer->cur != pfile->buffer->rlimit) cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", NODE_NAME (node)); @@ -401,15 +430,14 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg) static bool paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) { - unsigned char *buf, *end; + unsigned char *buf, *end, *lhsend; const cpp_token *lhs; unsigned int len; - bool valid; lhs = *plhs; len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1; buf = (unsigned char *) alloca (len); - end = cpp_spell_token (pfile, lhs, buf, false); + end = lhsend = cpp_spell_token (pfile, lhs, buf, false); /* Avoid comment headers, since they are still processed in stage 3. It is simpler to insert a space here, rather than modifying the @@ -426,10 +454,22 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) /* Set pfile->cur_token as required by _cpp_lex_direct. */ pfile->cur_token = _cpp_temp_token (pfile); *plhs = _cpp_lex_direct (pfile); - valid = pfile->buffer->cur == pfile->buffer->rlimit; - _cpp_pop_buffer (pfile); + if (pfile->buffer->cur != pfile->buffer->rlimit) + { + _cpp_pop_buffer (pfile); + _cpp_backup_tokens (pfile, 1); + *lhsend = '\0'; - return valid; + /* Mandatory error for all apart from assembler. */ + if (CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error (pfile, CPP_DL_ERROR, + "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", + buf, cpp_token_as_text (pfile, rhs)); + return false; + } + + _cpp_pop_buffer (pfile); + return true; } /* Handles an arbitrarily long sequence of ## operators, with initial @@ -461,22 +501,12 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) abort (); if (!paste_tokens (pfile, &lhs, rhs)) - { - _cpp_backup_tokens (pfile, 1); - - /* Mandatory error for all apart from assembler. */ - if (CPP_OPTION (pfile, lang) != CLK_ASM) - cpp_error (pfile, CPP_DL_ERROR, - "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", - cpp_token_as_text (pfile, lhs), - cpp_token_as_text (pfile, rhs)); - break; - } + break; } while (rhs->flags & PASTE_LEFT); /* Put the resulting token in its own context. */ - push_token_context (pfile, NULL, lhs, 1); + _cpp_push_token_context (pfile, NULL, lhs, 1); } /* Returns TRUE if the number of arguments ARGC supplied in an @@ -690,7 +720,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) too difficult. We re-insert it in its own context. */ _cpp_backup_tokens (pfile, 1); if (padding) - push_token_context (pfile, NULL, padding, 1); + _cpp_push_token_context (pfile, NULL, padding, 1); } return NULL; @@ -746,7 +776,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) macro->used = 1; if (macro->paramc == 0) - push_token_context (pfile, node, macro->exp.tokens, macro->count); + _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count); return 1; } @@ -939,8 +969,8 @@ push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, } /* Push a list of tokens. */ -static void -push_token_context (cpp_reader *pfile, cpp_hashnode *macro, +void +_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, const cpp_token *first, unsigned int count) { cpp_context *context = next_context (pfile); @@ -1151,7 +1181,7 @@ cpp_scan_nooutput (cpp_reader *pfile) pfile->state.prevent_expansion--; } -/* Step back one (or more) tokens. Can only step mack more than 1 if +/* Step back one (or more) tokens. Can only step back more than 1 if they are from the lexer, and not from macro expansion. */ void _cpp_backup_tokens (cpp_reader *pfile, unsigned int count) diff --git a/support/cpp2/libcpp/mkdeps.c b/support/cpp2/libcpp/mkdeps.c index bf07c1ba..d4c838e7 100644 --- a/support/cpp2/libcpp/mkdeps.c +++ b/support/cpp2/libcpp/mkdeps.c @@ -1,5 +1,5 @@ /* Dependency generator for Makefile fragments. - Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2003, 2007 Free Software Foundation, Inc. Contributed by Zack Weinberg, Mar 2000 This program is free software; you can redistribute it and/or modify it @@ -142,7 +142,13 @@ apply_vpath (struct deps *d, const char *t) /* Remove leading ./ in any case. */ while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) - t += 2; + { + t += 2; + /* If we removed a leading ./, then also remove any /s after the + first. */ + while (IS_DIR_SEPARATOR (t[0])) + ++t; + } return t; } diff --git a/support/cpp2/libiberty/getpwd.c b/support/cpp2/libiberty/getpwd.c index ba9546c2..7e05ce2b 100644 --- a/support/cpp2/libiberty/getpwd.c +++ b/support/cpp2/libiberty/getpwd.c @@ -35,10 +35,9 @@ extern int errno; #if HAVE_SYS_STAT_H #include #endif - -/* Prototype these in case the system headers don't provide them. */ -extern char *getpwd (); -extern char *getwd (); +#if HAVE_LIMITS_H +#include +#endif #include "libiberty.h" @@ -47,6 +46,8 @@ extern char *getwd (); the few exceptions to the general rule here. */ #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) +/* Prototype in case the system headers doesn't provide it. */ +extern char *getwd (); #define getcwd(buf,len) getwd(buf) #endif @@ -64,7 +65,7 @@ extern char *getwd (); yield 0 and set errno. */ char * -getpwd () +getpwd (void) { static char *pwd; static int failure_errno; @@ -83,7 +84,7 @@ getpwd () && dotstat.st_dev == pwdstat.st_dev)) /* The shortcut didn't work. Try the slow, ``sure'' way. */ - for (s = GUESSPATHLEN; ! getcwd (p = xmalloc (s), s); s *= 2) + for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2) { int e = errno; free (p); @@ -120,12 +121,12 @@ getpwd () #endif char * -getpwd () +getpwd (void) { static char *pwd = 0; if (!pwd) - pwd = getcwd (xmalloc (MAXPATHLEN + 1), MAXPATHLEN + 1 + pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1 #ifdef VMS , 0 #endif diff --git a/support/cpp2/libiberty/hashtab.c b/support/cpp2/libiberty/hashtab.c index a5671a0a..bf34a6d2 100644 --- a/support/cpp2/libiberty/hashtab.c +++ b/support/cpp2/libiberty/hashtab.c @@ -421,7 +421,28 @@ htab_empty (htab_t htab) if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) (*htab->del_f) (entries[i]); - memset (entries, 0, size * sizeof (PTR)); + /* Instead of clearing megabyte, downsize the table. */ + if (size > 1024*1024 / sizeof (PTR)) + { + int nindex = higher_prime_index (1024 / sizeof (PTR)); + int nsize = prime_tab[nindex].prime; + + if (htab->free_f != NULL) + (*htab->free_f) (htab->entries); + else if (htab->free_with_arg_f != NULL) + (*htab->free_with_arg_f) (htab->alloc_arg, htab->entries); + if (htab->alloc_with_arg_f != NULL) + htab->entries = (PTR *) (*htab->alloc_with_arg_f) (htab->alloc_arg, nsize, + sizeof (PTR *)); + else + htab->entries = (PTR *) (*htab->alloc_f) (nsize, sizeof (PTR *)); + htab->size = nsize; + htab->size_prime_index = nindex; + } + else + memset (entries, 0, size * sizeof (PTR)); + htab->n_deleted = 0; + htab->n_elements = 0; } /* Similar to htab_find_slot, but without several unwanted side effects: diff --git a/support/cpp2/optc-gen.awk b/support/cpp2/optc-gen.awk index 065972b0..aa6bb11a 100644 --- a/support/cpp2/optc-gen.awk +++ b/support/cpp2/optc-gen.awk @@ -62,24 +62,39 @@ for (i = 1; i <= n_headers; i++) print "#include " quote "opts.h" quote print "#include " quote "intl.h" quote print "" +print "#ifdef GCC_DRIVER" +print "int target_flags;" +print "#endif /* GCC_DRIVER */" +print "" for (i = 0; i < n_opts; i++) { name = var_name(flags[i]); if (name == "") continue; - if (flag_set_p("VarExists", flags[i])) - continue; - - init = opt_args("Init", flags[i]) - if (init != "") - init = " = " init; - else if (name in var_seen) - continue; + if (flag_set_p("VarExists", flags[i])) { + # Need it for the gcc driver. + if (name in var_seen) + continue; + init = "" + gcc_driver = 1 + } + else { + init = opt_args("Init", flags[i]) + if (init != "") + init = " = " init; + else if (name in var_seen) + continue; + gcc_driver = 0 + } + if (gcc_driver == 1) + print "#ifdef GCC_DRIVER" print "/* Set by -" opts[i] "." print " " help[i] " */" print var_type(flags[i]) name init ";" + if (gcc_driver == 1) + print "#endif /* GCC_DRIVER */" print "" var_seen[name] = 1; @@ -107,8 +122,21 @@ print "const unsigned int cl_options_count = N_OPTS;\n" print "const struct cl_option cl_options[] =\n{" -for (i = 0; i < n_opts; i++) +j = 0 +for (i = 0; i < n_opts; i++) { back_chain[i] = "N_OPTS"; + indices[opts[i]] = j; + # Combine the flags of identical switches. Switches + # appear many times if they are handled by many front + # ends, for example. + while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { + flags[i + 1] = flags[i] " " flags[i + 1]; + i++; + back_chain[i] = "N_OPTS"; + indices[opts[i]] = j; + } + j++; +} for (i = 0; i < n_opts; i++) { # Combine the flags of identical switches. Switches @@ -147,8 +175,21 @@ for (i = 0; i < n_opts; i++) { else hlp = quote help[i] quote; - printf(" { %c-%s%c,\n %s,\n %s, %u,\n", - quote, opts[i], quote, hlp, back_chain[i], len) + neg = opt_args("Negative", flags[i]); + if (neg != "") + idx = indices[neg] + else { + if (flag_set_p("RejectNegative", flags[i])) + idx = -1; + else { + if (opts[i] ~ "^[Wfm]") + idx = indices[opts[i]]; + else + idx = -1; + } + } + printf(" { %c-%s%c,\n %s,\n %s, %u, %d,\n", + quote, opts[i], quote, hlp, back_chain[i], len, idx) condition = opt_args("Condition", flags[i]) cl_flags = switch_flags(flags[i]) if (condition != "") diff --git a/support/cpp2/opth-gen.awk b/support/cpp2/opth-gen.awk index a6537a1c..e7ffc1a6 100644 --- a/support/cpp2/opth-gen.awk +++ b/support/cpp2/opth-gen.awk @@ -1,4 +1,4 @@ -# Copyright (C) 2003,2004 Free Software Foundation, Inc. +# Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc. # Contributed by Kelley Cook, June 2004. # Original code from Neil Booth, May 2003. # @@ -118,9 +118,18 @@ print "" for (i = 0; i < n_opts; i++) { opt = opt_args("InverseMask", flags[i]) - if (opt ~ ",") - print "#define TARGET_" nth_arg(1, opt) \ - " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)" + if (opt ~ ",") { + vname = var_name(flags[i]) + macro = "OPTION_" + mask = "OPTION_MASK_" + if (vname == "") { + vname = "target_flags" + macro = "TARGET_" + mask = "MASK_" + } + print "#define " macro nth_arg(1, opt) \ + " ((" vname " & " mask nth_arg(0, opt) ") == 0)" + } } print "" diff --git a/support/cpp2/opts-common.c b/support/cpp2/opts-common.c new file mode 100644 index 00000000..dcbbe2c1 --- /dev/null +++ b/support/cpp2/opts-common.c @@ -0,0 +1,236 @@ +/* Command line option handling. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "intl.h" +#include "opts.h" + +/* Perform a binary search to find which option the command-line INPUT + matches. Returns its index in the option array, and N_OPTS + (cl_options_count) on failure. + + This routine is quite subtle. A normal binary search is not good + enough because some options can be suffixed with an argument, and + multiple sub-matches can occur, e.g. input of "-pedantic" matching + the initial substring of "-pedantic-errors". + + A more complicated example is -gstabs. It should match "-g" with + an argument of "stabs". Suppose, however, that the number and list + of switches are such that the binary search tests "-gen-decls" + before having tested "-g". This doesn't match, and as "-gen-decls" + is less than "-gstabs", it will become the lower bound of the + binary search range, and "-g" will never be seen. To resolve this + issue, opts.sh makes "-gen-decls" point, via the back_chain member, + to "-g" so that failed searches that end between "-gen-decls" and + the lexicographically subsequent switch know to go back and see if + "-g" causes a match (which it does in this example). + + This search is done in such a way that the longest match for the + front end in question wins. If there is no match for the current + front end, the longest match for a different front end is returned + (or N_OPTS if none) and the caller emits an error message. */ +size_t +find_opt (const char *input, int lang_mask) +{ + size_t mn, mx, md, opt_len; + size_t match_wrong_lang; + int comp; + + mn = 0; + mx = cl_options_count; + + /* Find mn such this lexicographical inequality holds: + cl_options[mn] <= input < cl_options[mn + 1]. */ + while (mx - mn > 1) + { + md = (mn + mx) / 2; + opt_len = cl_options[md].opt_len; + comp = strncmp (input, cl_options[md].opt_text + 1, opt_len); + + if (comp < 0) + mx = md; + else + mn = md; + } + + /* This is the switch that is the best match but for a different + front end, or cl_options_count if there is no match at all. */ + match_wrong_lang = cl_options_count; + + /* Backtrace the chain of possible matches, returning the longest + one, if any, that fits best. With current GCC switches, this + loop executes at most twice. */ + do + { + const struct cl_option *opt = &cl_options[mn]; + + /* Is the input either an exact match or a prefix that takes a + joined argument? */ + if (!strncmp (input, opt->opt_text + 1, opt->opt_len) + && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED))) + { + /* If language is OK, return it. */ + if (opt->flags & lang_mask) + return mn; + + /* If we haven't remembered a prior match, remember this + one. Any prior match is necessarily better. */ + if (match_wrong_lang == cl_options_count) + match_wrong_lang = mn; + } + + /* Try the next possibility. This is cl_options_count if there + are no more. */ + mn = opt->back_chain; + } + while (mn != cl_options_count); + + /* Return the best wrong match, or cl_options_count if none. */ + return match_wrong_lang; +} + +/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the + next one is the same as ORIG_NEXT_OPT_IDX. */ + +static bool +cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx) +{ + /* An option can be canceled by the same option or an option with + Negative. */ + if (cl_options [next_opt_idx].neg_index == opt_idx) + return true; + + if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx) + return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index, + orig_next_opt_idx); + + return false; +} + +/* Filter out options canceled by the ones after them. */ + +void +prune_options (int *argcp, char ***argvp) +{ + int argc = *argcp; + int *options = xmalloc (argc * sizeof (*options)); + char **argv = xmalloc (argc * sizeof (char *)); + int i, arg_count, need_prune = 0; + const struct cl_option *option; + size_t opt_index; + + /* Scan all arguments. */ + for (i = 1; i < argc; i++) + { + int value = 1; + const char *opt = (*argvp) [i]; + + opt_index = find_opt (opt + 1, -1); + if (opt_index == cl_options_count + && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') + && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + { + char *dup; + + /* Drop the "no-" from negative switches. */ + size_t len = strlen (opt) - 3; + + dup = XNEWVEC (char, len + 1); + dup[0] = '-'; + dup[1] = opt[1]; + memcpy (dup + 2, opt + 5, len - 2 + 1); + opt = dup; + value = 0; + opt_index = find_opt (opt + 1, -1); + free (dup); + } + + if (opt_index == cl_options_count) + { +cont: + options [i] = 0; + continue; + } + + option = &cl_options[opt_index]; + if (option->neg_index < 0) + goto cont; + + /* Skip joined switches. */ + if ((option->flags & CL_JOINED)) + goto cont; + + /* Reject negative form of switches that don't take negatives as + unrecognized. */ + if (!value && (option->flags & CL_REJECT_NEGATIVE)) + goto cont; + + options [i] = (int) opt_index; + need_prune |= options [i]; + } + + if (!need_prune) + goto done; + + /* Remove arguments which are negated by others after them. */ + argv [0] = (*argvp) [0]; + arg_count = 1; + for (i = 1; i < argc; i++) + { + int j, opt_idx; + + opt_idx = options [i]; + if (opt_idx) + { + int next_opt_idx; + for (j = i + 1; j < argc; j++) + { + next_opt_idx = options [j]; + if (next_opt_idx + && cancel_option (opt_idx, next_opt_idx, + next_opt_idx)) + break; + } + } + else + goto keep; + + if (j == argc) + { +keep: + argv [arg_count] = (*argvp) [i]; + arg_count++; + } + } + + if (arg_count != argc) + { + *argcp = arg_count; + *argvp = argv; + } + else + { +done: + free (argv); + } + + free (options); +} diff --git a/support/cpp2/opts.c b/support/cpp2/opts.c index 3d11d851..178c5587 100644 --- a/support/cpp2/opts.c +++ b/support/cpp2/opts.c @@ -1,5 +1,6 @@ /* Command line option handling. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Contributed by Neil Booth. This file is part of GCC. @@ -16,8 +17,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" #include "system.h" @@ -44,7 +45,6 @@ static const char undocumented_msg[] = N_("This switch lacks documentation"); const char **in_fnames; unsigned num_in_fnames; -static size_t find_opt (const char *, int); static int common_handle_option (size_t scode, const char *arg, int value); static unsigned int handle_option (const char **argv, unsigned int lang_mask); static char *write_langs (unsigned int lang_mask); @@ -53,93 +53,9 @@ static void complain_wrong_lang (const char *, const struct cl_option *, static void handle_options (unsigned int, const char **, unsigned int); static void wrap_help (const char *help, const char *item, unsigned int); static void print_help (void); -static void print_filtered_help (unsigned int flag); +static void print_filtered_help (unsigned int); static unsigned int print_switch (const char *text, unsigned int indent); -/* Perform a binary search to find which option the command-line INPUT - matches. Returns its index in the option array, and N_OPTS - (cl_options_count) on failure. - - This routine is quite subtle. A normal binary search is not good - enough because some options can be suffixed with an argument, and - multiple sub-matches can occur, e.g. input of "-pedantic" matching - the initial substring of "-pedantic-errors". - - A more complicated example is -gstabs. It should match "-g" with - an argument of "stabs". Suppose, however, that the number and list - of switches are such that the binary search tests "-gen-decls" - before having tested "-g". This doesn't match, and as "-gen-decls" - is less than "-gstabs", it will become the lower bound of the - binary search range, and "-g" will never be seen. To resolve this - issue, opts.sh makes "-gen-decls" point, via the back_chain member, - to "-g" so that failed searches that end between "-gen-decls" and - the lexicographically subsequent switch know to go back and see if - "-g" causes a match (which it does in this example). - - This search is done in such a way that the longest match for the - front end in question wins. If there is no match for the current - front end, the longest match for a different front end is returned - (or N_OPTS if none) and the caller emits an error message. */ -static size_t -find_opt (const char *input, int lang_mask) -{ - size_t mn, mx, md, opt_len; - size_t match_wrong_lang; - int comp; - - mn = 0; - mx = cl_options_count; - - /* Find mn such this lexicographical inequality holds: - cl_options[mn] <= input < cl_options[mn + 1]. */ - while (mx - mn > 1) - { - md = (mn + mx) / 2; - opt_len = cl_options[md].opt_len; - comp = strncmp (input, cl_options[md].opt_text + 1, opt_len); - - if (comp < 0) - mx = md; - else - mn = md; - } - - /* This is the switch that is the best match but for a different - front end, or cl_options_count if there is no match at all. */ - match_wrong_lang = cl_options_count; - - /* Backtrace the chain of possible matches, returning the longest - one, if any, that fits best. With current GCC switches, this - loop executes at most twice. */ - do - { - const struct cl_option *opt = &cl_options[mn]; - - /* Is the input either an exact match or a prefix that takes a - joined argument? */ - if (!strncmp (input, opt->opt_text + 1, opt->opt_len) - && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED))) - { - /* If language is OK, return it. */ - if (opt->flags & lang_mask) - - - /* If we haven't remembered a prior match, remember this - one. Any prior match is necessarily better. */ - if (match_wrong_lang == cl_options_count) - match_wrong_lang = mn; - } - - /* Try the next possibility. This is cl_options_count if there - are no more. */ - mn = opt->back_chain; - } - while (mn != cl_options_count); - - /* Return the best wrong match, or cl_options_count if none. */ - return match_wrong_lang; -} - /* If ARG is a non-negative integer made up solely of digits, return its value, otherwise return -1. */ static int @@ -168,7 +84,7 @@ write_langs (unsigned int mask) if (mask & (1U << n)) len += strlen (lang_name) + 1; - result = xmalloc (len); + result = XNEWVEC (char, len); len = 0; for (n = 0; (lang_name = lang_names[n]) != 0; n++) if (mask & (1U << n)) @@ -224,7 +140,7 @@ handle_option (const char **argv, unsigned int lang_mask) /* Drop the "no-" from negative switches. */ size_t len = strlen (opt) - 3; - dup = xmalloc (len + 1); + dup = XNEWVEC (char, len + 1); dup[0] = '-'; dup[1] = opt[1]; memcpy (dup + 2, opt + 5, len - 2 + 1); @@ -338,7 +254,7 @@ handle_option (const char **argv, unsigned int lang_mask) } if (option->flags & lang_mask) - if ((*lang_hooks.handle_option) (opt_index, arg, value) == 0) + if (lang_hooks.handle_option (opt_index, arg, value) == 0) result = 0; if (result && (option->flags & CL_COMMON)) @@ -356,7 +272,7 @@ handle_option (const char **argv, unsigned int lang_mask) } /* Handle FILENAME from the command line. */ -void +static void add_input_filename (const char *filename) { num_in_fnames++; diff --git a/support/cpp2/opts.h b/support/cpp2/opts.h index 2c2340c3..3af501fb 100644 --- a/support/cpp2/opts.h +++ b/support/cpp2/opts.h @@ -46,6 +46,7 @@ struct cl_option const char *help; unsigned short back_chain; unsigned char opt_len; + int neg_index; unsigned int flags; void *flag_var; enum cl_var_type var_type; @@ -63,6 +64,7 @@ struct cl_option_state { extern const struct cl_option cl_options[]; extern const unsigned int cl_options_count; extern const char *const lang_names[]; +extern bool no_unit_at_a_time_default; #define CL_DISABLED (1 << 21) /* Disabled in this configuration. */ #define CL_TARGET (1 << 22) /* Target-specific option. */ @@ -83,6 +85,8 @@ extern const char **in_fnames; extern unsigned num_in_fnames; +size_t find_opt (const char *input, int lang_mask); +extern void prune_options (int *argcp, char ***argvp); extern void decode_options (unsigned int argc, const char **argv); extern int option_enabled (int opt_idx); extern bool get_option_state (int, struct cl_option_state *); diff --git a/support/cpp2/output.h b/support/cpp2/output.h index 3cb091fc..fda098bc 100644 --- a/support/cpp2/output.h +++ b/support/cpp2/output.h @@ -23,9 +23,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #ifndef GCC_OUTPUT_H #define GCC_OUTPUT_H -/* Compute branch alignments based on frequency information in the CFG. */ -extern void compute_alignments (void); - /* Initialize data in final at the beginning of a compilation. */ extern void init_final (const char *); @@ -153,77 +150,6 @@ extern int regno_clobbered_at_setjmp (int); /* Functions in varasm.c. */ -/* Tell assembler to switch to text section. */ -extern void text_section (void); - -/* Tell assembler to switch to unlikely-to-be-executed text section. */ -extern void unlikely_text_section (void); - -/* Tell assembler to switch to data section. */ -extern void data_section (void); - -/* Tell assembler to switch to read-only data section. This is normally - the text section. */ -extern void readonly_data_section (void); - -/* Determine if we're in the text section. */ -extern int in_text_section (void); - -/* Determine if we're in the unlikely-to-be-executed text section. */ -extern int in_unlikely_text_section (void); - -#ifdef CTORS_SECTION_ASM_OP -extern void ctors_section (void); -#endif - -#ifdef DTORS_SECTION_ASM_OP -extern void dtors_section (void); -#endif - -#ifdef BSS_SECTION_ASM_OP -extern void bss_section (void); -#endif - -#ifdef INIT_SECTION_ASM_OP -extern void init_section (void); -#endif - -#ifdef FINI_SECTION_ASM_OP -extern void fini_section (void); -#endif - -#ifdef EXPORTS_SECTION_ASM_OP -extern void exports_section (void); -#endif - -#ifdef DRECTVE_SECTION_ASM_OP -extern void drectve_section (void); -#endif - -#ifdef SDATA_SECTION_ASM_OP -extern void sdata_section (void); -#endif - -/* Tell assembler to change to section NAME for DECL. - If DECL is NULL, just switch to section NAME. - If NAME is NULL, get the name from DECL. - If RELOC is 1, the initializer for DECL contains relocs. */ -extern void named_section (tree, const char *, int); - -/* Tell assembler to switch to the section for function DECL. */ -extern void function_section (tree); - -/* Tell assembler to switch to the most recently used text section. */ -extern void current_function_section (tree); - -/* Tell assembler to switch to the section for string merging. */ -extern void mergeable_string_section (tree, unsigned HOST_WIDE_INT, - unsigned int); - -/* Tell assembler to switch to the section for constant merging. */ -extern void mergeable_constant_section (enum machine_mode, - unsigned HOST_WIDE_INT, unsigned int); - /* Declare DECL to be a weak symbol. */ extern void declare_weak (tree); /* Merge weak status. */ @@ -241,10 +167,6 @@ extern void weak_finish (void); Prefixes such as % are optional. */ extern int decode_reg_name (const char *); -/* Make the rtl for variable VAR be volatile. - Use this only for static variables. */ -extern void make_var_volatile (tree); - extern void assemble_alias (tree, tree); extern void default_assemble_visibility (tree, int); @@ -274,6 +196,10 @@ extern void assemble_end_function (tree, const char *); initial value (that will be done by the caller). */ extern void assemble_variable (tree, int, int, int); +/* Compute the alignment of variable specified by DECL. + DONT_OUTPUT_DATA is from assemble_variable. */ +extern void align_variable (tree decl, bool dont_output_data); + /* Output something to declare an external symbol to the assembler. (Most assemblers don't need this, so we normally output nothing.) Do nothing if DECL is not external. */ @@ -346,8 +272,16 @@ extern int get_pool_size (void); extern rtx peephole (rtx); #endif -/* Write all the constants in the constant pool. */ -extern void output_constant_pool (const char *, tree); +extern void output_shared_constant_pool (void); + +extern void output_object_blocks (void); + +/* Whether a constructor CTOR is a valid static constant initializer if all + its elements are. This used to be internal to initializer_constant_valid_p + and has been exposed to let other functions like categorize_ctor_elements + evaluate the property while walking a constructor for other purposes. */ + +extern bool constructor_static_from_elts_p (tree); /* Return nonzero if VALUE is a valid constant-valued expression for use in initializing a static variable; one that can be an @@ -438,33 +372,11 @@ extern rtx this_is_asm_operands; extern int size_directive_output; extern tree last_assemble_variable_decl; -enum in_section { no_section, in_text, in_unlikely_executed_text, in_data, - in_named -#ifdef BSS_SECTION_ASM_OP - , in_bss -#endif -#ifdef CTORS_SECTION_ASM_OP - , in_ctors -#endif -#ifdef DTORS_SECTION_ASM_OP - , in_dtors -#endif -#ifdef READONLY_DATA_SECTION_ASM_OP - , in_readonly_data -#endif -#ifdef EXTRA_SECTIONS - , EXTRA_SECTIONS -#endif -}; - -extern const char *last_text_section_name; -extern enum in_section last_text_section; extern bool first_function_block_is_cold; /* Decide whether DECL needs to be in a writable section. RELOC is the same as for SELECT_SECTION. */ extern bool decl_readonly_section (tree, int); -extern bool decl_readonly_section_1 (tree, int, int); /* This can be used to compute RELOC for the function above, when given a constant expression. */ @@ -476,14 +388,6 @@ extern const char *user_label_prefix; /* Default target function prologue and epilogue assembler output. */ extern void default_function_pro_epilogue (FILE *, HOST_WIDE_INT); -/* Tell assembler to switch to the section for the exception table. */ -extern void default_exception_section (void); - -/* Tell assembler to switch to the section for the EH frames. */ -extern void named_section_eh_frame_section (void); -extern void collect2_eh_frame_section (void); -extern void default_eh_frame_section (void); - /* Default target hook that outputs nothing to a stream. */ extern void no_asm_to_stream (FILE *); @@ -502,7 +406,23 @@ extern void no_asm_to_stream (FILE *); #define SECTION_OVERRIDE 0x20000 /* allow override of default flags */ #define SECTION_TLS 0x40000 /* contains thread-local storage */ #define SECTION_NOTYPE 0x80000 /* don't output @progbits */ -#define SECTION_MACH_DEP 0x100000 /* subsequent bits reserved for target */ +#define SECTION_DECLARED 0x100000 /* section has been used */ +#define SECTION_STYLE_MASK 0x600000 /* bits used for SECTION_STYLE */ +#define SECTION_COMMON 0x800000 /* contains common data */ +#define SECTION_MACH_DEP 0x1000000 /* subsequent bits reserved for target */ + +/* This SECTION_STYLE is used for unnamed sections that we can switch + to using a special assembler directive. */ +#define SECTION_UNNAMED 0x000000 + +/* This SECTION_STYLE is used for named sections that we can switch + to using a general section directive. */ +#define SECTION_NAMED 0x200000 + +/* This SECTION_STYLE is used for sections that we cannot switch to at + all. The choice of section is implied by the directive that we use + to declare the object. */ +#define SECTION_NOSWITCH 0x400000 /* A helper function for default_elf_select_section and default_elf_unique_section. Categorizes the DECL. */ @@ -541,18 +461,119 @@ enum section_category SECCAT_TBSS }; +/* Information that is provided by all instances of the section type. */ +struct section_common GTY(()) { + /* The set of SECTION_* flags that apply to this section. */ + unsigned int flags; +}; + +/* Information about a SECTION_NAMED section. */ +struct named_section GTY(()) { + struct section_common common; + + /* The name of the section. */ + const char *name; + + /* If nonnull, the VAR_DECL or FUNCTION_DECL with which the + section is associated. */ + tree decl; +}; + +/* A callback that writes the assembly code for switching to an unnamed + section. The argument provides callback-specific data. */ +typedef void (*unnamed_section_callback) (const void *); + +/* Information about a SECTION_UNNAMED section. */ +struct unnamed_section GTY(()) { + struct section_common common; + + /* The callback used to switch to the section, and the data that + should be passed to the callback. */ + unnamed_section_callback GTY ((skip)) callback; + const void *GTY ((skip)) data; + + /* The next entry in the chain of unnamed sections. */ + section *next; +}; + +/* A callback that writes the assembly code for a decl in a + SECTION_NOSWITCH section. DECL is the decl that should be assembled + and NAME is the name of its SYMBOL_REF. SIZE is the size of the decl + in bytes and ROUNDED is that size rounded up to the next + BIGGEST_ALIGNMENT / BITS_PER_UNIT boundary. + + Return true if the callback used DECL_ALIGN to set the object's + alignment. A false return value implies that we are relying + on the rounded size to align the decl. */ +typedef bool (*noswitch_section_callback) (tree decl, const char *name, + unsigned HOST_WIDE_INT size, + unsigned HOST_WIDE_INT rounded); + +/* Information about a SECTION_NOSWITCH section. */ +struct noswitch_section GTY(()) { + struct section_common common; + + /* The callback used to assemble decls in this section. */ + noswitch_section_callback GTY ((skip)) callback; +}; + +/* Information about a section, which may be named or unnamed. */ +union section GTY ((desc ("SECTION_STYLE (&(%h))"))) +{ + struct section_common GTY ((skip)) common; + struct named_section GTY ((tag ("SECTION_NAMED"))) named; + struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed; + struct noswitch_section GTY ((tag ("SECTION_NOSWITCH"))) noswitch; +}; + +/* Return the style of section SECT. */ +#define SECTION_STYLE(SECT) ((SECT)->common.flags & SECTION_STYLE_MASK) + +struct object_block; + +/* Special well-known sections. */ +extern GTY(()) section *text_section; +extern GTY(()) section *data_section; +extern GTY(()) section *readonly_data_section; +extern GTY(()) section *sdata_section; +extern GTY(()) section *ctors_section; +extern GTY(()) section *dtors_section; +extern GTY(()) section *bss_section; +extern GTY(()) section *sbss_section; +extern GTY(()) section *exception_section; +extern GTY(()) section *eh_frame_section; +extern GTY(()) section *tls_comm_section; +extern GTY(()) section *comm_section; +extern GTY(()) section *lcomm_section; +extern GTY(()) section *bss_noswitch_section; + +extern GTY(()) section *in_section; +extern GTY(()) bool in_cold_section_p; + +extern section *get_unnamed_section (unsigned int, void (*) (const void *), + const void *); +extern section *get_section (const char *, unsigned int, tree); +extern section *get_named_section (tree, const char *, int); +extern void place_block_symbol (rtx); +extern rtx get_section_anchor (struct object_block *, HOST_WIDE_INT, + enum tls_model); +extern section *mergeable_constant_section (enum machine_mode, + unsigned HOST_WIDE_INT, + unsigned int); +extern section *function_section (tree); +extern section *unlikely_text_section (void); +extern section *current_function_section (void); + +extern bool unlikely_text_section_p (section *); +extern void switch_to_section (section *); +extern void output_section_asm_op (const void *); -extern bool set_named_section_flags (const char *, unsigned int); -#define named_section_flags(NAME, FLAGS) \ - named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE) -extern void named_section_real (const char *, unsigned int, tree); -extern bool named_section_first_declaration (const char *); extern unsigned int default_section_type_flags (tree, const char *, int); -extern unsigned int default_section_type_flags_1 (tree, const char *, int, int); +extern bool have_global_bss_p (void); extern void default_no_named_section (const char *, unsigned int, tree); extern void default_elf_asm_named_section (const char *, unsigned int, tree); -extern enum section_category categorize_decl_for_section (tree, int, int); +extern enum section_category categorize_decl_for_section (tree, int); extern void default_coff_asm_named_section (const char *, unsigned int, tree); extern void default_pe_asm_named_section (const char *, unsigned int, tree); @@ -563,24 +584,24 @@ extern void default_stabs_asm_out_constructor (rtx, int); extern void default_named_section_asm_out_constructor (rtx, int); extern void default_ctor_section_asm_out_constructor (rtx, int); -extern void default_select_section (tree, int, unsigned HOST_WIDE_INT); -extern void default_elf_select_section (tree, int, unsigned HOST_WIDE_INT); -extern void default_elf_select_section_1 (tree, int, - unsigned HOST_WIDE_INT, int); +extern section *default_select_section (tree, int, unsigned HOST_WIDE_INT); +extern section *default_elf_select_section (tree, int, unsigned HOST_WIDE_INT); extern void default_unique_section (tree, int); -extern void default_unique_section_1 (tree, int, int); -extern void default_function_rodata_section (tree); -extern void default_no_function_rodata_section (tree); -extern void default_select_rtx_section (enum machine_mode, rtx, - unsigned HOST_WIDE_INT); -extern void default_elf_select_rtx_section (enum machine_mode, rtx, +extern section *default_function_rodata_section (tree); +extern section *default_no_function_rodata_section (tree); +extern section *default_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); +extern section *default_elf_select_rtx_section (enum machine_mode, rtx, + unsigned HOST_WIDE_INT); extern void default_encode_section_info (tree, rtx, int); extern const char *default_strip_name_encoding (const char *); +extern void default_asm_output_anchor (rtx); +extern bool default_use_anchors_for_symbol_p (rtx); extern bool default_binds_local_p (tree); extern bool default_binds_local_p_1 (tree, int); extern void default_globalize_label (FILE *, const char *); extern void default_emit_unwind_label (FILE *, tree, int, int); +extern void default_emit_except_table_label (FILE *); extern void default_internal_label (FILE *, const char *, unsigned long); extern void default_file_start (void); extern void file_end_indicate_exec_stack (void); diff --git a/support/cpp2/prefix.c b/support/cpp2/prefix.c index a559bcd3..652f49b9 100644 --- a/support/cpp2/prefix.c +++ b/support/cpp2/prefix.c @@ -113,7 +113,7 @@ get_key_value (char *key) static char * save_string (const char *s, int len) { - char *result = xmalloc (len + 1); + char *result = XNEWVEC (char, len + 1); memcpy (result, s, len); result[len] = 0; @@ -199,7 +199,7 @@ translate_name (char *name) keylen++) ; - key = alloca (keylen + 1); + key = (char *) alloca (keylen + 1); strncpy (key, &name[1], keylen); key[keylen] = 0; diff --git a/support/cpp2/sdcpp-opts.c b/support/cpp2/sdcpp-opts.c index e4eea8c8..3f863f47 100644 --- a/support/cpp2/sdcpp-opts.c +++ b/support/cpp2/sdcpp-opts.c @@ -61,6 +61,9 @@ static const char *deps_file; /* The prefix given by -iprefix, if any. */ static const char *iprefix; +/* The multilib directory given by -imultilib, if any. */ +static const char *imultilib; + /* The system root, if any. Overridden by -isysroot. */ static const char *sysroot = TARGET_SYSTEM_ROOT; @@ -416,6 +419,10 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) iprefix = arg; break; + case OPT_imultilib: + imultilib = arg; + break; + case OPT_iquote: add_path (xstrdup (arg), QUOTE, 0, true); break; @@ -544,7 +551,7 @@ sdcpp_common_post_options (const char **pfilename) sanitize_cpp_opts (); - register_include_chains (parse_in, sysroot, iprefix, + register_include_chains (parse_in, sysroot, iprefix, imultilib, std_inc, 0, verbose); /* Open the output now. We must do so even if flag_no_output is diff --git a/support/cpp2/sdcpp.dsp b/support/cpp2/sdcpp.dsp index 87fd8718..f203f500 100644 --- a/support/cpp2/sdcpp.dsp +++ b/support/cpp2/sdcpp.dsp @@ -241,6 +241,10 @@ SOURCE=.\options.c # End Source File # Begin Source File +SOURCE=".\opts-common.c" +# End Source File +# Begin Source File + SOURCE=.\opts.c # End Source File # Begin Source File @@ -316,6 +320,14 @@ SOURCE=.\win32\dirent.h # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File +SOURCE=.\libiberty\filenames.h +# End Source File +# Begin Source File + +SOURCE=.\libiberty\hashtab.h +# End Source File +# Begin Source File + SOURCE=.\libiberty\obstack.h # End Source File # End Group @@ -353,6 +365,10 @@ SOURCE=.\libiberty.h # End Source File # Begin Source File +SOURCE=.\md5.h +# End Source File +# Begin Source File + SOURCE=.\options.h # End Source File # Begin Source File diff --git a/support/cpp2/sdcpp.opt b/support/cpp2/sdcpp.opt index b4d655ad..58f62742 100644 --- a/support/cpp2/sdcpp.opt +++ b/support/cpp2/sdcpp.opt @@ -222,6 +222,10 @@ imacros SDCPP Joined Separate -imacros Accept definition of macros in +imultilib +C ObjC C++ ObjC++ Joined Separate +-imultilib Set to be the multilib include subdirectory + include SDCPP Joined Separate -include Include the contents of before other files diff --git a/support/cpp2/system.h b/support/cpp2/system.h index 6d192ac6..8f669437 100644 --- a/support/cpp2/system.h +++ b/support/cpp2/system.h @@ -231,6 +231,8 @@ extern int errno; # endif #endif +#define ICE_EXIT_CODE 4 + #ifdef HAVE_UNISTD_H # include #endif @@ -619,6 +621,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; # define FALSE false #endif /* !__cplusplus */ +/////* Get definition of double_int. */ +////#include "double-int.h" /* Some compilers do not allow the use of unsigned char in bitfields. */ #define BOOL_BITFIELD unsigned int @@ -738,7 +742,11 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT \ LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE \ TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC \ - PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF + PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF \ + EXTRA_SECTIONS EXTRA_SECTION_FUNCTIONS READONLY_DATA_SECTION \ + TARGET_ASM_EXCEPTION_SECTION TARGET_ASM_EH_FRAME_SECTION \ + SMALL_ARG_MAX ASM_OUTPUT_SHARED_BSS ASM_OUTPUT_SHARED_COMMON \ + ASM_OUTPUT_SHARED_LOCAL UNALIGNED_WORD_ASM_OP /* Hooks that are no longer used. */ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ diff --git a/support/cpp2/version.c b/support/cpp2/version.c index 222bbb0c..310c138e 100644 --- a/support/cpp2/version.c +++ b/support/cpp2/version.c @@ -1,11 +1,17 @@ #include "version.h" -/* This is the string reported as the version number by all components - of the compiler. If you distribute a modified version of GCC, - please modify this string to indicate that, e.g. by putting your - organization's name in parentheses at the end of the string. */ +/* This is the trailing component of the string reported as the + version number by all components of the compiler. For an official + FSF release, it is empty. If you distribute a modified version of + GCC, please change this string to indicate that. The suggested + format is a leading space, followed by your organization's name + in parentheses. You may also wish to include a number indicating + the revision of your modified compiler. */ -const char version_string[] = "4.1.2 + SDCC"; +#define BASEVER "4.2.0" +#define DATESTAMP +#define DEVPHASE +#define VERSUFFIX " + SDCC" /* This is the location of the online document giving instructions for reporting bugs. If you distribute a modified version of GCC, @@ -15,3 +21,8 @@ const char version_string[] = "4.1.2 + SDCC"; not bugs in your modifications.) */ const char bug_report_url[] = ""; + +/* The complete version string, assembled from several pieces. + BASEVER, DATESTAMP, and DEVPHASE are defined by the Makefile. */ + +const char version_string[] = BASEVER DATESTAMP DEVPHASE VERSUFFIX;