+2006-11-25 Borut Razem <borut.razem AT siol.net>
+
+ * 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 <borut.razem AT siol.net>
+
+ * 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 <epetrich AT ivorytower.norman.ok.us>
* src/hc08/gen.c (genPcall): fix for bug #1601032
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 *));
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)
}
/* 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;
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;
char objc;
char cplusplus;
char extended_numbers;
- char trigraphs;
+ char std;
char dollars_in_ident;
char cplusplus_comments;
char digraphs;
/* ??? 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 },
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;
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),
#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
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. */
{
#undef OPERATOR
#undef VERS
#undef ULP
-#undef CPLUS
#undef builtin_array_end
/* And another subroutine. This one sets up the standard include path. */
&& !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);
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))
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;
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;
case OPT_obj_ext:
CPP_OPTION (pfile, obj_ext) = arg;
break;
- }
+ }
}
return i + 1;
}
{
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;
}
-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 <target> Add a MAKE-quoted target\n\
-MT <target> Add an unquoted target\n\
"), stdout);
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. */
{
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);
}
}
*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. */
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. */