From: borutr Date: Sat, 25 Nov 2006 18:38:50 +0000 (+0000) Subject: * synchronized with GCC CPP release version 3.2.3, X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=f500f9d262bb65195b103ebfed59ab09ba9c6c76;p=fw%2Fsdcc * synchronized with GCC CPP release version 3.2.3, the latest before integration of cpp into gcc git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4485 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 2dbe7e57..9e94592b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2006-11-25 Borut Razem + + * support/cpp2/cppexp.c, support/cpp2/hashtable.h, + support/cpp2/configure, support/cpp2/Makefile.in, + support/cpp2/cppfiles.c, support/cpp2/output.h, + support/cpp2/cppinit.c, support/cpp2/cpplib.c, + support/cpp2/config.h, support/cpp2/cpplib.h, + support/cpp2/Makefile.bcc, support/cpp2/cpphash.c, + support/cpp2/cppdefault.c, support/cpp2/config.in, + support/cpp2/system.h, support/cpp2/cpplex.c, + support/cpp2/cpphash.h, support/cpp2/mbchar.c, + support/cpp2/cppdefault.h, support/cpp2/prefix.c + support/cpp2/hwint.h, support/cpp2/mbchar.h, + support/cpp2/prefix.h, support/cpp2/cppmacro.c, + support/cpp2/configure.in, support/cpp2/intl.h, + support/cpp2/sdcpp.dsp, support/cpp2/acconfig.h, + support/cpp2/sdcc.h, support/cpp2/mkdeps.c, + support/cpp2/version.c, support/cpp2/cppmain.c, + support/cpp2/ansidecl.h, support/cpp2/libiberty.h, + support/cpp2/hashtable.c, support/cpp2/aclocal.m4, + support/cpp2/cpperror.c, + support/cpp2/libiberty/safe-ctype.c, + support/cpp2/libiberty/safe-ctype.h, + support/cpp2/libiberty/splay-tree.c, + support/cpp2/libiberty/obstack.c, + support/cpp2/libiberty/lbasename.c, + support/cpp2/libiberty/splay-tree.h, + support/cpp2/libiberty/obstack.h: + synchronized with GCC CPP release version 3.2.3, + the latest before integration of cpp into gcc + * support/cpp2/except.h, support/cpp2/line-map.c, + support/cpp2/line-map.h, + support/cpp2/libiberty/hex.c, + support/cpp2/libiberty/concat.c, + support/cpp2/libiberty/filenames.h: added + * support/cpp2/intl.c: deleted + +2006-11-24 Borut Razem + + * src/SDCC.y: enabled compilation of empty source file + * support/Util/SDCCerr.[ch]: added sdcc warning 190 - + "ISO C forbids an empty source file" + * device/lib/_startup.c, device/lib/printf_tiny.c: disable warning 190 + if all the code is ifdefed out. + 2006-11-24 Erik Petrich * src/hc08/gen.c (genPcall): fix for bug #1601032 diff --git a/support/cpp2/cppfiles.c b/support/cpp2/cppfiles.c index 7bc0ca41..da9ee187 100644 --- a/support/cpp2/cppfiles.c +++ b/support/cpp2/cppfiles.c @@ -250,7 +250,7 @@ open_file (pfile, filename) /* Don't reopen an idempotent file. */ if (DO_NOT_REREAD (file)) return file; - + /* Don't reopen one which is already loaded. */ if (file->buffer != NULL) return file; @@ -310,9 +310,12 @@ stack_include_file (pfile, inc) sysp = MAX ((pfile->map ? pfile->map->sysp : 0), (inc->foundhere ? inc->foundhere->sysp : 0)); - /* For -M, add the file to the dependencies on its first inclusion. */ - if (CPP_OPTION (pfile, print_deps) > sysp && !inc->include_count) - deps_add_dep (pfile->deps, inc->name); + /* Add the file to the dependencies on its first inclusion. */ + if (CPP_OPTION (pfile, print_deps) > !!sysp && !inc->include_count) + { + if (pfile->buffer || CPP_OPTION (pfile, deps_ignore_main_file) == 0) + deps_add_dep (pfile->deps, inc->name); + } /* Not in cache? */ if (! inc->buffer) @@ -527,7 +530,7 @@ cpp_included (pfile, fname) nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname); return (nd && nd->value); } - + /* Search directory path for the file. */ name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2); for (path = CPP_OPTION (pfile, quote_include); path; path = path->next) @@ -743,7 +746,7 @@ _cpp_compare_file_date (pfile, header) const cpp_token *header; { struct include_file *inc = find_include_file (pfile, header, 0); - + if (inc == NULL || inc == NO_INCLUDE_PATH) return -1; @@ -752,7 +755,7 @@ _cpp_compare_file_date (pfile, header) close (inc->fd); inc->fd = -1; } - + return inc->st.st_mtime > pfile->buffer->inc->st.st_mtime; } @@ -981,7 +984,7 @@ read_name_map (pfile, dirname) ptr->map_to[dirlen] = '/'; strcpy (ptr->map_to + dirlen + 1, to); free (to); - } + } ptr->map_next = map_list_ptr->map_list_map; map_list_ptr->map_list_map = ptr; @@ -992,13 +995,13 @@ read_name_map (pfile, dirname) } fclose (f); } - + /* Add this information to the cache. */ map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list); CPP_OPTION (pfile, map_list) = map_list_ptr; return map_list_ptr->map_list_map; -} +} /* Remap an unsimplified path NAME based on the file_name_map (if any) for LOC. */ @@ -1023,10 +1026,10 @@ remap_filename (pfile, name, loc) if (! loc->name_map) return name; } - + /* This works since NAME has not been simplified yet. */ from = name + loc->len + 1; - + for (map = loc->name_map; map; map = map->map_next) if (!strcmp (map->map_from, from)) return map->map_to; @@ -1047,7 +1050,7 @@ remap_filename (pfile, name, loc) memcpy (dir, name, p - name); dir[p - name] = '\0'; from = p + 1; - + for (map = read_name_map (pfile, dir); map; map = map->map_next) if (! strcmp (map->map_from, from)) return map->map_to; @@ -1113,7 +1116,7 @@ _cpp_simplify_pathname (path) /* Convert all backslashes to slashes. */ for (from = path; *from; from++) if (*from == '\\') *from = '/'; - + /* Skip over leading drive letter if present. */ if (ISALPHA (path[0]) && path[1] == ':') from = to = &path[2]; @@ -1122,7 +1125,7 @@ _cpp_simplify_pathname (path) #else from = to = path; #endif - + /* Remove redundant leading /s. */ if (*from == '/') { @@ -1197,7 +1200,7 @@ _cpp_simplify_pathname (path) if (move_base) base = to; } - + /* Change the empty string to "." so that it is not treated as stdin. Null terminate. */ if (to == path) diff --git a/support/cpp2/cppinit.c b/support/cpp2/cppinit.c index fcbbff76..6fd0c0fa 100644 --- a/support/cpp2/cppinit.c +++ b/support/cpp2/cppinit.c @@ -99,12 +99,17 @@ static void path_include PARAMS ((cpp_reader *, char *, int)); static void init_library PARAMS ((void)); static void init_builtins PARAMS ((cpp_reader *)); +static void mark_named_operators PARAMS ((cpp_reader *)); static void append_include_chain PARAMS ((cpp_reader *, char *, int, int)); static struct search_path * remove_dup_dir PARAMS ((cpp_reader *, + struct search_path *, + struct search_path **)); +static struct search_path * remove_dup_nonsys_dirs PARAMS ((cpp_reader *, + struct search_path **, struct search_path *)); static struct search_path * remove_dup_dirs PARAMS ((cpp_reader *, - struct search_path *)); + struct search_path **)); static void merge_include_chains PARAMS ((cpp_reader *)); static bool push_include PARAMS ((cpp_reader *, struct pending_option *)); @@ -188,7 +193,7 @@ path_include (pfile, list, path) name[q - p] = 0; } - append_include_chain (pfile, name, path, 0); + append_include_chain (pfile, name, path, path == SYSTEM); /* Advance past this name. */ if (*q == 0) @@ -271,55 +276,98 @@ append_include_chain (pfile, dir, path, cxx_aware) } /* Handle a duplicated include path. PREV is the link in the chain - before the duplicate. The duplicate is removed from the chain and - freed. Returns PREV. */ + before the duplicate, or NULL if the duplicate is at the head of + the chain. The duplicate is removed from the chain and freed. + Returns PREV. */ static struct search_path * -remove_dup_dir (pfile, prev) +remove_dup_dir (pfile, prev, head_ptr) cpp_reader *pfile; struct search_path *prev; + struct search_path **head_ptr; { - struct search_path *cur = prev->next; + struct search_path *cur; + + if (prev != NULL) + { + cur = prev->next; + prev->next = cur->next; + } + else + { + cur = *head_ptr; + *head_ptr = cur->next; + } if (CPP_OPTION (pfile, verbose)) fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name); - prev->next = cur->next; free ((PTR) cur->name); free (cur); return prev; } +/* Remove duplicate non-system directories for which there is an equivalent + system directory later in the chain. The range for removal is between + *HEAD_PTR and END. Returns the directory before END, or NULL if none. + This algorithm is quadratic in the number of system directories, which is + acceptable since there aren't usually that many of them. */ +static struct search_path * +remove_dup_nonsys_dirs (pfile, head_ptr, end) + cpp_reader *pfile; + struct search_path **head_ptr; + struct search_path *end; +{ + int sysdir = 0; + struct search_path *prev = NULL, *cur, *other; + + for (cur = *head_ptr; cur; cur = cur->next) + { + if (cur->sysp) + { + sysdir = 1; + for (other = *head_ptr, prev = NULL; + other != end; + other = other ? other->next : *head_ptr) + { + if (!other->sysp + && INO_T_EQ (cur->ino, other->ino) + && cur->dev == other->dev) + { + other = remove_dup_dir (pfile, prev, head_ptr); + if (CPP_OPTION (pfile, verbose)) + fprintf (stderr, + _(" as it is a non-system directory that duplicates a system directory\n")); + } + prev = other; + } + } + } + + if (!sysdir) + for (cur = *head_ptr; cur != end; cur = cur->next) + prev = cur; + + return prev; +} + /* Remove duplicate directories from a chain. Returns the tail of the chain, or NULL if the chain is empty. This algorithm is quadratic in the number of -I switches, which is acceptable since there aren't usually that many of them. */ static struct search_path * -remove_dup_dirs (pfile, head) +remove_dup_dirs (pfile, head_ptr) cpp_reader *pfile; - struct search_path *head; + struct search_path **head_ptr; { struct search_path *prev = NULL, *cur, *other; - for (cur = head; cur; cur = cur->next) + for (cur = *head_ptr; cur; cur = cur->next) { - for (other = head; other != cur; other = other->next) + for (other = *head_ptr; other != cur; other = other->next) if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev) { - if (cur->sysp && !other->sysp) - { - cpp_warning (pfile, - "changing search order for system directory \"%s\"", - cur->name); - if (strcmp (cur->name, other->name)) - cpp_warning (pfile, - " as it is the same as non-system directory \"%s\"", - other->name); - else - cpp_warning (pfile, - " as it has already been specified as a non-system directory"); - } - cur = remove_dup_dir (pfile, prev); + cur = remove_dup_dir (pfile, prev, head_ptr); break; } prev = cur; @@ -357,28 +405,33 @@ merge_include_chains (pfile) else brack = systm; - /* This is a bit tricky. First we drop dupes from the quote-include - list. Then we drop dupes from the bracket-include list. - Finally, if qtail and brack are the same directory, we cut out - brack and move brack up to point to qtail. + /* This is a bit tricky. First we drop non-system dupes of system + directories from the merged bracket-include list. Next we drop + dupes from the bracket and quote include lists. Then we drop + non-system dupes from the merged quote-include list. Finally, + if qtail and brack are the same directory, we cut out brack and + move brack up to point to qtail. We can't just merge the lists and then uniquify them because then we may lose directories from the <> search path that should - be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however + be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo -Iquux. */ - remove_dup_dirs (pfile, brack); - qtail = remove_dup_dirs (pfile, quote); + remove_dup_nonsys_dirs (pfile, &brack, systm); + remove_dup_dirs (pfile, &brack); if (quote) { + qtail = remove_dup_dirs (pfile, "e); qtail->next = brack; + qtail = remove_dup_nonsys_dirs (pfile, "e, brack); + /* If brack == qtail, remove brack as it's simpler. */ - if (brack && INO_T_EQ (qtail->ino, brack->ino) + if (qtail && brack && INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev) - brack = remove_dup_dir (pfile, qtail); + brack = remove_dup_dir (pfile, qtail, "e); } else quote = brack; @@ -395,7 +448,7 @@ struct lang_flags char objc; char cplusplus; char extended_numbers; - char trigraphs; + char std; char dollars_in_ident; char cplusplus_comments; char digraphs; @@ -403,7 +456,7 @@ struct lang_flags /* ??? Enable $ in identifiers in assembly? */ static const struct lang_flags lang_defaults[] = -{ /* c99 objc c++ xnum trig dollar c++comm digr */ +{ /* c99 objc c++ xnum std dollar c++comm digr */ /* GNUC89 */ { 0, 0, 0, 1, 0, 1, 1, 1 }, /* GNUC99 */ { 1, 0, 0, 1, 0, 1, 1, 1 }, /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 }, @@ -423,14 +476,15 @@ set_lang (pfile, lang) enum c_lang lang; { const struct lang_flags *l = &lang_defaults[(int) lang]; - + CPP_OPTION (pfile, lang) = lang; CPP_OPTION (pfile, c99) = l->c99; CPP_OPTION (pfile, objc) = l->objc; CPP_OPTION (pfile, cplusplus) = l->cplusplus; CPP_OPTION (pfile, extended_numbers) = l->extended_numbers; - CPP_OPTION (pfile, trigraphs) = l->trigraphs; + CPP_OPTION (pfile, std) = l->std; + CPP_OPTION (pfile, trigraphs) = l->std; CPP_OPTION (pfile, dollars_in_ident) = l->dollars_in_ident; CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; CPP_OPTION (pfile, digraphs) = l->digraphs; @@ -614,28 +668,22 @@ cpp_destroy (pfile) Two values are not compile time constants, so we tag them in the FLAGS field instead: VERS value is the global version_string, quoted - ULP value is the global user_label_prefix - - Also, macros with CPLUS set in the flags field are entered only for C++. */ + ULP value is the global user_label_prefix */ struct builtin { const U_CHAR *name; const char *value; unsigned char builtin; - unsigned char operator; unsigned short flags; unsigned short len; }; #define VERS 0x01 #define ULP 0x02 -#define CPLUS 0x04 #define BUILTIN 0x08 -#define OPERATOR 0x10 -#define B(n, t) { U n, 0, t, 0, BUILTIN, sizeof n - 1 } -#define C(n, v) { U n, v, 0, 0, 0, sizeof n - 1 } -#define X(n, f) { U n, 0, 0, 0, f, sizeof n - 1 } -#define O(n, c, f) { U n, 0, 0, c, OPERATOR | f, sizeof n - 1 } +#define B(n, t) { U n, 0, t, BUILTIN, sizeof n - 1 } +#define C(n, v) { U n, v, 0, 0, sizeof n - 1 } +#define X(n, f) { U n, 0, 0, f, sizeof n - 1 } static const struct builtin builtin_array[] = { B("__TIME__", BT_TIME), @@ -671,30 +719,55 @@ static const struct builtin builtin_array[] = #else C("__STDC__", "1"), #endif - - /* Named operators known to the preprocessor. These cannot be #defined - and always have their stated meaning. They are treated like normal - identifiers except for the type code and the meaning. Most of them - are only for C++ (but see iso646.h). */ - O("and", CPP_AND_AND, CPLUS), - O("and_eq", CPP_AND_EQ, CPLUS), - O("bitand", CPP_AND, CPLUS), - O("bitor", CPP_OR, CPLUS), - O("compl", CPP_COMPL, CPLUS), - O("not", CPP_NOT, CPLUS), - O("not_eq", CPP_NOT_EQ, CPLUS), - O("or", CPP_OR_OR, CPLUS), - O("or_eq", CPP_OR_EQ, CPLUS), - O("xor", CPP_XOR, CPLUS), - O("xor_eq", CPP_XOR_EQ, CPLUS) }; #undef B #undef C #undef X -#undef O #define builtin_array_end \ builtin_array + sizeof(builtin_array)/sizeof(struct builtin) +/* Named operators known to the preprocessor. These cannot be + #defined and always have their stated meaning. They are treated + like normal identifiers except for the type code and the meaning. + Most of them are only for C++ (but see iso646.h). */ +#define B(n, t) { DSC(n), t } +static const struct named_op +{ + const U_CHAR *name; + unsigned int len; + enum cpp_ttype value; +} operator_array[] = { + B("and", CPP_AND_AND), + B("and_eq", CPP_AND_EQ), + B("bitand", CPP_AND), + B("bitor", CPP_OR), + B("compl", CPP_COMPL), + B("not", CPP_NOT), + B("not_eq", CPP_NOT_EQ), + B("or", CPP_OR_OR), + B("or_eq", CPP_OR_EQ), + B("xor", CPP_XOR), + B("xor_eq", CPP_XOR_EQ) +}; +#undef B + +/* Mark the C++ named operators in the hash table. */ +static void +mark_named_operators (pfile) + cpp_reader *pfile; +{ + const struct named_op *b; + + for (b = operator_array; + b < (operator_array + ARRAY_SIZE (operator_array)); + b++) + { + cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); + hp->flags |= NODE_OPERATOR; + hp->value.operator = b->value; + } +} + /* Subroutine of cpp_read_main_file; reads the builtins table above and enters them, and language-specific macros, into the hash table. */ static void @@ -705,26 +778,12 @@ init_builtins (pfile) for(b = builtin_array; b < builtin_array_end; b++) { - if ((b->flags & CPLUS) && ! CPP_OPTION (pfile, cplusplus)) - continue; - - if ((b->flags & OPERATOR) && ! CPP_OPTION (pfile, operator_names)) - continue; - - if (b->flags & (OPERATOR | BUILTIN)) + if (b->flags & BUILTIN) { cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); - if (b->flags & OPERATOR) - { - hp->flags |= NODE_OPERATOR; - hp->value.operator = b->operator; - } - else - { - hp->type = NT_MACRO; - hp->flags |= NODE_BUILTIN | NODE_WARN; - hp->value.builtin = b->builtin; - } + hp->type = NT_MACRO; + hp->flags |= NODE_BUILTIN | NODE_WARN; + hp->value.builtin = b->builtin; } else /* A standard macro of some kind. */ { @@ -783,7 +842,6 @@ init_builtins (pfile) #undef OPERATOR #undef VERS #undef ULP -#undef CPLUS #undef builtin_array_end /* And another subroutine. This one sets up the standard include path. */ @@ -844,7 +902,7 @@ init_standard_includes (pfile) && !CPP_OPTION (pfile, no_standard_cplusplus_includes))) { /* Does this dir start with the prefix? */ - if (!memcmp (p->fname, default_prefix, default_len)) + if (!strncmp (p->fname, default_prefix, default_len)) { /* Yes; change prefix and add to search list. */ int flen = strlen (p->fname); @@ -1003,6 +1061,10 @@ void cpp_finish_options (pfile) cpp_reader *pfile; { + /* Mark named operators before handling command line macros. */ + if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names)) + mark_named_operators (pfile); + /* Install builtins and process command line macros etc. in the order they appeared, but only if not already preprocessed. */ if (! CPP_OPTION (pfile, preprocessed)) @@ -1290,7 +1352,7 @@ parse_option (input) md = (mn + mx) / 2; opt_len = cl_options[md].opt_len; - comp = memcmp (input, cl_options[md].opt_text, opt_len); + comp = strncmp (input, cl_options[md].opt_text, opt_len); if (comp > 0) mn = md + 1; @@ -1315,7 +1377,7 @@ parse_option (input) for (; mn < (unsigned int) N_OPTS; mn++) { opt_len = cl_options[mn].opt_len; - if (memcmp (input, cl_options[mn].opt_text, opt_len)) + if (strncmp (input, cl_options[mn].opt_text, opt_len)) break; if (input[opt_len] == '\0') return mn; @@ -1762,7 +1824,7 @@ cpp_handle_option (pfile, argc, argv, ignore) case OPT_obj_ext: CPP_OPTION (pfile, obj_ext) = arg; break; - } + } } return i + 1; } @@ -1879,7 +1941,10 @@ init_dependency_output (pfile) { spec = getenv ("SUNPRO_DEPENDENCIES"); if (spec) - CPP_OPTION (pfile, print_deps) = 2; + { + CPP_OPTION (pfile, print_deps) = 2; + CPP_OPTION (pfile, deps_ignore_main_file) = 1; + } else return; } @@ -1981,7 +2046,7 @@ Switches:\n\ -MG Treat missing header file as generated files\n\ "), stdout); fputs (_("\ - -MP Generate phony targets for all headers\n\ + -MP Generate phony targets for all headers\n\ -MQ Add a MAKE-quoted target\n\ -MT Add an unquoted target\n\ "), stdout); diff --git a/support/cpp2/cpplib.c b/support/cpp2/cpplib.c index a741b1ef..2b43de05 100644 --- a/support/cpp2/cpplib.c +++ b/support/cpp2/cpplib.c @@ -215,7 +215,7 @@ skip_rest_of_line (pfile) cpp_reader *pfile; { /* Discard all stacked contexts. */ - while (pfile->context != &pfile->base_context) + while (pfile->context->prev) _cpp_pop_context (pfile); /* Sweep up all tokens remaining on the line. */ @@ -411,12 +411,17 @@ run_directive (pfile, dir_no, buf, count) { cpp_push_buffer (pfile, (const U_CHAR *) buf, count, /* from_stage3 */ true, 1); + /* Disgusting hack. */ + if (dir_no == T_PRAGMA) + pfile->buffer->inc = pfile->buffer->prev->inc; start_directive (pfile); /* We don't want a leading # to be interpreted as a directive. */ pfile->buffer->saved_flags = 0; pfile->directive = &dtable[dir_no]; (void) (*pfile->directive->handler) (pfile); end_directive (pfile, 1); + if (dir_no == T_PRAGMA) + pfile->buffer->inc = NULL; _cpp_pop_buffer (pfile); } @@ -1305,7 +1310,44 @@ destringize_and_run (pfile, in) } *dest = '\0'; - run_directive (pfile, T_PRAGMA, result, dest - result); + /* Ugh; an awful kludge. We are really not set up to be lexing + tokens when in the middle of a macro expansion. Use a new + context to force cpp_get_token to lex, and so skip_rest_of_line + doesn't go beyond the end of the text. Also, remember the + current lexing position so we can return to it later. + + 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); + free (pfile->context); + pfile->context = saved_context; + pfile->cur_token = saved_cur_token; + pfile->cur_run = saved_cur_run; + } + + /* See above comment. For the moment, we'd like + + token1 _Pragma ("foo") token2 + + to be output as + + token1 + # 7 "file.c" + #pragma foo + # 7 "file.c" + token2 + + Getting the line markers is a little tricky. */ + if (pfile->cb.line_change) + (*pfile->cb.line_change) (pfile, pfile->cur_token, false); } /* Handle the _Pragma operator. */ @@ -1317,25 +1359,19 @@ _cpp_do__Pragma (pfile) unsigned int len; const cpp_token *string = get__Pragma_string (pfile); - if (!string) - cpp_error (pfile, "_Pragma takes a parenthesized string literal"); - else + if (string) { - /* Ideally, we'd like - token1 _Pragma ("foo") token2 - to be output as - token1 - # 7 "file.c" - #pragma foo - # 7 "file.c" - token2 - Getting these correct line markers is a little tricky. */ - - buffer = destringize (&string->val.str, &len); + unsigned int len; + + unsigned char *buffer = destringize (&string->val.str, &len); buffer[len] = 0; - cpp_output_string ("\n#pragma "); cpp_output_string (buffer); cpp_output_string ("\n"); + cpp_output_string ("\n#pragma "); + cpp_output_string (buffer); + cpp_output_string ("\n"); free ((PTR) buffer); } + else + cpp_error (pfile, "_Pragma takes a parenthesized string literal"); } /* Just ignore #sccs, on systems where we define it at all. */ diff --git a/support/cpp2/cpplib.h b/support/cpp2/cpplib.h index 8261fea1..807f00f2 100644 --- a/support/cpp2/cpplib.h +++ b/support/cpp2/cpplib.h @@ -282,6 +282,9 @@ struct cpp_options /* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */ unsigned char print_deps_append; + /* If true, no dependency is generated on the main file. */ + unsigned char deps_ignore_main_file; + /* Nonzero means print names of header files (-H). */ unsigned char print_include_names; @@ -338,6 +341,9 @@ struct cpp_options /* Nonzero for the 1999 C Standard, including corrigenda and amendments. */ unsigned char c99; + /* Nonzero if conforming to some particular standard. */ + unsigned char std; + /* Nonzero means give all the error messages the ANSI standard requires. */ unsigned char pedantic; diff --git a/support/cpp2/cppmacro.c b/support/cpp2/cppmacro.c index 68d860d2..38103aa4 100644 --- a/support/cpp2/cppmacro.c +++ b/support/cpp2/cppmacro.c @@ -348,6 +348,12 @@ stringify_arg (pfile, arg) } /* Commit the memory, including NUL, and return the token. */ + if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < 1) + { + size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); + _cpp_extend_buff (pfile, &pfile->u_buff, 1); + dest = BUFF_FRONT (pfile->u_buff) + len_so_far; + } len = dest - BUFF_FRONT (pfile->u_buff); BUFF_FRONT (pfile->u_buff) = dest + 1; return new_string_token (pfile, dest - len, len); @@ -613,7 +619,20 @@ collect_args (pfile, node) } if (!error) - return base_buff; + { + /* GCC has special semantics for , ## b where b is a varargs + parameter: we remove the comma if b was omitted entirely. + If b was merely an empty argument, the comma is retained. + If the macro takes just one (varargs) parameter, then we + retain the comma only if we are standards conforming. + + If FIRST is NULL replace_args () swallows the comma. */ + if (macro->variadic && (argc < macro->paramc + || (argc == 1 && args[0].count == 0 + && !CPP_OPTION (pfile, std)))) + args[macro->paramc - 1].first = NULL; + return base_buff; + } _cpp_release_buff (pfile, base_buff); return NULL; @@ -673,6 +692,8 @@ enter_macro_context (pfile, node) /* The presence of a macro invalidates a file's controlling macro. */ pfile->mi_valid = false; + pfile->state.angled_headers = false; + /* Handle standard macros. */ if (! (node->flags & NODE_BUILTIN)) { @@ -797,15 +818,13 @@ replace_args (pfile, node, args) count = arg->count, from = arg->first; if (dest != first) { - /* GCC has special semantics for , ## b where b is a - varargs parameter: the comma disappears if b was - given no actual arguments (not merely if b is an - empty argument); otherwise the paste flag is removed. */ if (dest[-1]->type == CPP_COMMA && macro->variadic && src->val.arg_no == macro->paramc) { - if (count == 0) + /* Swallow a pasted comma if from == NULL, otherwise + drop the paste flag. */ + if (from == NULL) dest--; else paste_flag = dest - 1; @@ -1530,7 +1549,7 @@ cpp_macro_definition (pfile, node) } /* Calculate length. */ - len = NODE_LEN (node) + 1; /* ' ' */ + len = NODE_LEN (node) + 2; /* ' ' and NUL. */ if (macro->fun_like) { len += 4; /* "()" plus possible final ".." of named diff --git a/support/cpp2/hashtable.c b/support/cpp2/hashtable.c index d39fb8a8..665b3bcf 100644 --- a/support/cpp2/hashtable.c +++ b/support/cpp2/hashtable.c @@ -39,7 +39,7 @@ static void ht_expand PARAMS ((hash_table *)); #endif /* Let them override the alloc and free routines too. */ #ifndef OBSTACK_CHUNK_ALLOC -#define OBSTACK_CHUNK_ALLOC malloc +#define OBSTACK_CHUNK_ALLOC xmalloc #endif #ifndef OBSTACK_CHUNK_FREE #define OBSTACK_CHUNK_FREE free diff --git a/support/cpp2/system.h b/support/cpp2/system.h index 3f3a7b9f..e9cefaf8 100644 --- a/support/cpp2/system.h +++ b/support/cpp2/system.h @@ -26,7 +26,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* This is the location of the online document giving information how to report bugs. If you change this string, also check for strings not under control of the preprocessor. */ -#define GCCBUGURL "" +#define GCCBUGURL "" #include "ansidecl.h" @@ -224,6 +224,12 @@ extern int errno; #ifndef WSTOPSIG #define WSTOPSIG WEXITSTATUS #endif +#ifndef WCOREDUMP +#define WCOREDUMP(S) ((S) & WCOREFLG) +#endif +#ifndef WCOREFLG +#define WCOREFLG 0200 +#endif /* The HAVE_DECL_* macros are three-state, undefined, 0 or 1. If they are defined to 0 then we must provide the relevant declaration @@ -513,7 +519,10 @@ typedef char _Bool; OMIT_EH_TABLE EASY_DIV_EXPR IMPLICIT_FIX_EXPR \ LONGJMP_RESTORE_FROM_STACK MAX_INT_TYPE_SIZE ASM_IDENTIFY_GCC \ STDC_VALUE TRAMPOLINE_ALIGN ASM_IDENTIFY_GCC_AFTER_SOURCE \ - SLOW_ZERO_EXTEND SUBREG_REGNO_OFFSET DWARF_LINE_MIN_INSTR_LENGTH + SLOW_ZERO_EXTEND SUBREG_REGNO_OFFSET DWARF_LINE_MIN_INSTR_LENGTH \ + BLOCK_PROFILER BLOCK_PROFILER_CODE FUNCTION_BLOCK_PROFILER \ + FUNCTION_BLOCK_PROFILER_EXIT MACHINE_STATE_SAVE \ + MACHINE_STATE_RESTORE #endif /* IN_GCC */ diff --git a/support/cpp2/version.c b/support/cpp2/version.c index be4a09b6..18a2df8a 100644 --- a/support/cpp2/version.c +++ b/support/cpp2/version.c @@ -1,4 +1,4 @@ #include "ansidecl.h" #include "version.h" -const char *const version_string = "3.1 + SDCC"; +const char *const version_string = "3.2.3 + SDCC";