summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/c-common.c59
-rw-r--r--gcc/c-common.h4
-rw-r--r--gcc/c-lang.c25
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/lex.c14
-rw-r--r--gcc/cppfiles.c33
-rw-r--r--gcc/cpplex.c103
-rw-r--r--gcc/cpplib.c10
-rw-r--r--gcc/cppmacro.c8
-rw-r--r--gcc/langhooks-def.h6
-rw-r--r--gcc/langhooks.h36
-rw-r--r--gcc/objc/objc-act.c7
-rw-r--r--gcc/toplev.c65
16 files changed, 241 insertions, 178 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1db9694fc80..496fd5aa723 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,39 @@
+2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cppfiles.c (stack_include_file): Don't optimize zero-length
+ files.
+ (read_include_file): NUL-terminate read files.
+ * cpplex.c (handle_newline, skip_escaped_newlines,
+ get_effective_char, skip_whitespace, parse_identifier,
+ parse_identifier_slow, parse_number, parse_string,
+ _cpp_lex_direct): Optimize for the fact that buffers are guaranteed
+ NUL-terminated.
+ * cpplib.c (destringize_and_run, cpp_define, handle_assertion):
+ Be sure buffers are NUL terminated.
+ * cppmacro.c (warn_of_redefinition): Kill compile warning.
+
+2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * c-common.c: Include tree-inline.h.
+ (c_language): Move separate definitions here.
+ (c_common_init_options, c_common_post_options): New.
+ (c_common_lang_init): Rename c_common_init.
+ * c-common.h (c_common_lang_init): Similarly.
+ (c_common_init_options, c_common_post_options): New.
+ * c-lang.c (c_post_options): Move body to c_common_post_options.
+ (c_init_options): Use c_common_init_options.
+ (c_init): Update.
+ * langhooks.def: Rearrange.
+ * langhooks.h: Rearrange, and improve comments.
+ * toplev.c (do_compile): New function.
+ (toplev_main): Use it.
+ (lang_independent_f_options, parse_options_and_default_flags,
+ process_options): Remove trailing periods.
+ * Makefile.in: Update.
+objc: * objc-act.c (objc_post_options, objc_init_options): Use c-common.c
+ functions.
+ (ojbc_init): Update.
+
2001-11-26 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.md (unop): Add 0 offset for some gas versions.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f88b0b4bf1e..1cb15998f73 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1250,7 +1250,7 @@ s-under: $(GCC_PASSES)
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
$(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
$(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
- diagnostic.h
+ diagnostic.h tree-inline.h
# A file used by all variants of C and some other languages.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index dde1af3b892..a7d005b04ed 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "expr.h"
#include "c-common.h"
+#include "tree-inline.h"
#include "diagnostic.h"
#include "tm_p.h"
#include "obstack.h"
@@ -79,6 +80,10 @@ cpp_reader *parse_in; /* Declared in c-lex.h. */
: "long long unsigned int"))
#endif
+/* The variant of the C language being processed. */
+
+enum c_language_kind c_language;
+
/* The following symbols are subsumed in the c_global_trees array, and
listed here individually for documentation purposes.
@@ -2371,7 +2376,7 @@ c_common_nodes_and_builtins ()
tree va_list_arg_type_node;
/* We must initialize this before any builtin functions (which might have
- attributes) are declared. (c_common_lang_init is too late.) */
+ attributes) are declared. (c_common_init is too late.) */
format_attribute_table = c_format_attribute_table;
/* Define `int' and `char' first so that dbx will output them first. */
@@ -3858,17 +3863,43 @@ static bool c_attrs_initialized = false;
static void c_init_attributes PARAMS ((void));
-/* Do the parts of lang_init common to C and C++. */
-const char *
-c_common_lang_init (filename)
- const char *filename;
+/* Common initialization before parsing options. */
+void
+c_common_init_options (lang)
+ enum c_language_kind lang;
{
- filename = init_c_lex (filename);
+ c_language = lang;
+ parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89:
+ lang == clk_cplusplus ? CLK_GNUCXX: CLK_OBJC);
- init_pragma ();
+ /* Mark as "unspecified" (see c_common_post_options). */
+ flag_bounds_check = -1;
+}
+
+/* Post-switch processing. */
+void
+c_common_post_options ()
+{
+ cpp_post_options (parse_in);
+
+ /* Use tree inlining if possible. Function instrumentation is only
+ done in the RTL level, so we disable tree inlining. */
+ if (! flag_instrument_function_entry_exit)
+ {
+ if (!flag_no_inline)
+ {
+ flag_inline_trees = 1;
+ flag_no_inline = 1;
+ }
+ if (flag_inline_functions)
+ {
+ flag_inline_trees = 2;
+ flag_inline_functions = 0;
+ }
+ }
/* If still "unspecified", make it match -fbounded-pointers. */
- if (flag_bounds_check < 0)
+ if (flag_bounds_check == -1)
flag_bounds_check = flag_bounded_pointers;
/* Special format checking options don't work without -Wformat; warn if
@@ -3883,6 +3914,18 @@ c_common_lang_init (filename)
warning ("-Wformat-security ignored without -Wformat");
if (warn_missing_format_attribute && !warn_format)
warning ("-Wmissing-format-attribute ignored without -Wformat");
+}
+
+/* Front end initialization common to C, ObjC and C++. */
+const char *
+c_common_init (filename)
+ const char *filename;
+{
+ /* Do this before initializing pragmas, as then cpplib's hash table
+ has been set up. */
+ filename = init_c_lex (filename);
+
+ init_pragma ();
if (!c_attrs_initialized)
c_init_attributes ();
diff --git a/gcc/c-common.h b/gcc/c-common.h
index b289cb8b24f..84e4bb95824 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -534,7 +534,9 @@ extern void disable_builtin_function PARAMS ((const char *));
extern tree build_va_arg PARAMS ((tree, tree));
-extern const char *c_common_lang_init PARAMS ((const char *));
+extern void c_common_init_options PARAMS ((enum c_language_kind));
+extern void c_common_post_options PARAMS ((void));
+extern const char *c_common_init PARAMS ((const char *));
extern void c_common_finish PARAMS ((void));
extern HOST_WIDE_INT c_common_get_alias_set PARAMS ((tree));
extern bool c_promoting_integer_type_p PARAMS ((tree));
diff --git a/gcc/c-lang.c b/gcc/c-lang.c
index 9f0fb286a88..a5c86625b30 100644
--- a/gcc/c-lang.c
+++ b/gcc/c-lang.c
@@ -88,32 +88,13 @@ static varray_type deferred_fns;
static void
c_post_options ()
{
- cpp_post_options (parse_in);
-
- /* Use tree inlining if possible. Function instrumentation is only
- done in the RTL level, so we disable tree inlining. */
- if (! flag_instrument_function_entry_exit)
- {
- if (!flag_no_inline)
- {
- flag_inline_trees = 1;
- flag_no_inline = 1;
- }
- if (flag_inline_functions)
- {
- flag_inline_trees = 2;
- flag_inline_functions = 0;
- }
- }
+ c_common_post_options ();
}
static void
c_init_options ()
{
- parse_in = cpp_create_reader (CLK_GNUC89);
-
- /* Mark as "unspecified". */
- flag_bounds_check = -1;
+ c_common_init_options (clk_c);
}
static const char *
@@ -122,7 +103,7 @@ c_init (filename)
{
c_init_decl_processing ();
- filename = c_common_lang_init (filename);
+ filename = c_common_init (filename);
add_c_tree_codes ();
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 68ae9e1cfc6..110f7c40e8e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (c_language): Move to c-common.c.
+ * lex.c (cxx_post_options, cxx_init_options): Use c-common.c
+ functions.
+ (cxx_init): Update.
+
2001-11-26 Jason Merrill <jason@redhat.com>
* call.c (joust): Remove COND_EXPR hack.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f2bbba09f2c..c316da034fa 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -400,10 +400,6 @@ int flag_permissive;
int flag_enforce_eh_specs = 1;
-/* The variant of the C language being processed. */
-
-c_language_kind c_language = clk_cplusplus;
-
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index c093fc1f0f7..ba93ca5f5fa 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -241,18 +241,17 @@ static const char *const cplus_tree_code_name[] = {
void
cxx_post_options ()
{
- cpp_post_options (parse_in);
+ c_common_post_options ();
}
+/* Initialization before switch parsing. */
void
cxx_init_options ()
{
- parse_in = cpp_create_reader (CLK_GNUCXX);
+ c_common_init_options (clk_cplusplus);
/* Default exceptions on. */
flag_exceptions = 1;
- /* Mark as "unspecified". */
- flag_bounds_check = -1;
/* By default wrap lines at 80 characters. Is getenv ("COLUMNS")
preferable? */
diagnostic_line_cutoff (global_dc) = 80;
@@ -720,10 +719,7 @@ cxx_init (filename)
cxx_init_decl_processing ();
- /* Create the built-in __null node. Note that we can't yet call for
- type_for_size here because integer_type_node and so forth are not
- set up. Therefore, we don't set the type of these nodes until
- cxx_init_decl_processing. */
+ /* Create the built-in __null node. */
null_node = build_int_2 (0, 0);
TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0);
ridpointers[RID_NULL] = null_node;
@@ -731,7 +727,7 @@ cxx_init (filename)
token_count = init_cpp_parse ();
interface_unknown = 1;
- filename = c_common_lang_init (filename);
+ filename = c_common_init (filename);
init_cp_pragma ();
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 1fb357d642a..f0d85d9bf37 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -296,17 +296,17 @@ stack_include_file (pfile, inc)
/* Not in cache? */
if (! inc->buffer)
{
- /* Mark a regular, zero-length file never-reread. Zero-length
- files are stacked the first time, so preprocessing a main
- file of zero length does not raise an error. */
- if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
- _cpp_never_reread (inc);
- else if (read_include_file (pfile, inc))
+ if (read_include_file (pfile, inc))
{
/* If an error occurs, do not try to read this file again. */
_cpp_never_reread (inc);
return false;
}
+ /* Mark a regular, zero-length file never-reread. We read it,
+ NUL-terminate it, and stack it once, so preprocessing a main
+ file of zero length does not raise an error. */
+ if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
+ _cpp_never_reread (inc);
close (inc->fd);
inc->fd = -1;
}
@@ -382,7 +382,8 @@ read_include_file (pfile, inc)
if (pagesize == -1)
pagesize = getpagesize ();
- if (size / pagesize >= MMAP_THRESHOLD)
+ if (size / pagesize >= MMAP_THRESHOLD
+ && (size % pagesize) != 0)
{
buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
if (buf == (U_CHAR *)-1)
@@ -392,7 +393,7 @@ read_include_file (pfile, inc)
else
#endif
{
- buf = (U_CHAR *) xmalloc (size);
+ buf = (U_CHAR *) xmalloc (size + 1);
offset = 0;
while (offset < size)
{
@@ -410,6 +411,8 @@ read_include_file (pfile, inc)
}
offset += count;
}
+ /* The lexer requires that the buffer be NUL-terminated. */
+ buf[size] = '\0';
}
}
else if (S_ISBLK (inc->st.st_mode))
@@ -424,19 +427,25 @@ read_include_file (pfile, inc)
bigger than the majority of C source files. */
size = 8 * 1024;
- buf = (U_CHAR *) xmalloc (size);
+ buf = (U_CHAR *) xmalloc (size + 1);
offset = 0;
while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
{
offset += count;
if (offset == size)
- buf = xrealloc (buf, (size *= 2));
+ {
+ size *= 2;
+ buf = xrealloc (buf, size + 1);
+ }
}
if (count < 0)
goto perror_fail;
- if (offset < size)
- buf = xrealloc (buf, offset);
+ if (offset + 1 < size)
+ buf = xrealloc (buf, offset + 1);
+
+ /* The lexer requires that the buffer be NUL-terminated. */
+ buf[offset] = '\0';
inc->st.st_size = offset;
}
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 35411e615c1..08223bd49b7 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -75,7 +75,7 @@ static cppchar_t get_effective_char PARAMS ((cpp_reader *));
static int skip_block_comment PARAMS ((cpp_reader *));
static int skip_line_comment PARAMS ((cpp_reader *));
static void adjust_column PARAMS ((cpp_reader *));
-static void skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
+static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
static cpp_hashnode *parse_identifier_slow PARAMS ((cpp_reader *,
const U_CHAR *));
@@ -119,12 +119,8 @@ handle_newline (pfile)
cpp_buffer *buffer = pfile->buffer;
/* Handle CR-LF and LF-CR. Most other implementations (e.g. java)
- only accept CR-LF; maybe we should fall back to that behaviour?
-
- NOTE: the EOF case in _cpp_lex_direct currently requires the
- buffer->cur != buffer->rlimit test here for 0-length files. */
- if (buffer->cur != buffer->rlimit
- && buffer->cur[-1] + buffer->cur[0] == '\r' + '\n')
+ only accept CR-LF; maybe we should fall back to that behaviour? */
+ if (buffer->cur[-1] + buffer->cur[0] == '\r' + '\n')
buffer->cur++;
buffer->line_base = buffer->cur;
@@ -190,24 +186,21 @@ skip_escaped_newlines (pfile)
do
{
- if (buffer->cur == buffer->rlimit)
- break;
-
if (next == '?')
{
- if (buffer->cur[0] != '?' || buffer->cur + 1 == buffer->rlimit)
- break;
-
- if (!trigraph_p (pfile))
+ if (buffer->cur[0] != '?' || !trigraph_p (pfile))
break;
/* Translate the trigraph. */
next = _cpp_trigraph_map[buffer->cur[1]];
buffer->cur += 2;
- if (next != '\\' || buffer->cur == buffer->rlimit)
+ if (next != '\\')
break;
}
+ if (buffer->cur == buffer->rlimit)
+ break;
+
/* We have a backslash, and room for at least one more
character. Skip horizontal whitespace. */
saved_cur = buffer->cur;
@@ -250,16 +243,13 @@ static cppchar_t
get_effective_char (pfile)
cpp_reader *pfile;
{
- cppchar_t next = EOF;
+ cppchar_t next;
cpp_buffer *buffer = pfile->buffer;
buffer->backup_to = buffer->cur;
- if (buffer->cur < buffer->rlimit)
- {
- next = *buffer->cur++;
- if (__builtin_expect (next == '?' || next == '\\', 0))
- next = skip_escaped_newlines (pfile);
- }
+ next = *buffer->cur++;
+ if (__builtin_expect (next == '?' || next == '\\', 0))
+ next = skip_escaped_newlines (pfile);
return next;
}
@@ -295,7 +285,6 @@ skip_block_comment (pfile)
comes immediately before the true comment delimiter.
Don't bother to get it right across escaped newlines. */
if (CPP_OPTION (pfile, warn_comments)
- && buffer->cur + 1 < buffer->rlimit
&& buffer->cur[0] == '*' && buffer->cur[1] != '/')
cpp_warning_with_line (pfile,
pfile->line, CPP_BUF_COL (buffer),
@@ -360,7 +349,7 @@ adjust_column (pfile)
/* Skips whitespace, saving the next non-whitespace character.
Adjusts pfile->col_adjust to account for tabs. Without this,
tokens might be assigned an incorrect column. */
-static void
+static int
skip_whitespace (pfile, c)
cpp_reader *pfile;
cppchar_t c;
@@ -378,6 +367,8 @@ skip_whitespace (pfile, c)
/* Just \f \v or \0 left. */
else if (c == '\0')
{
+ if (buffer->cur - 1 == buffer->rlimit)
+ return 0;
if (!warned)
{
cpp_warning (pfile, "null character(s) ignored");
@@ -390,14 +381,13 @@ skip_whitespace (pfile, c)
"%s in preprocessing directive",
c == '\f' ? "form feed" : "vertical tab");
- if (buffer->cur == buffer->rlimit)
- return;
c = *buffer->cur++;
}
/* We only want non-vertical space, i.e. ' ' \t \f \v \0. */
while (is_nvspace (c));
buffer->cur--;
+ return 1;
}
/* See if the characters of a number token are valid in a name (no
@@ -430,18 +420,16 @@ parse_identifier (pfile)
cpp_reader *pfile;
{
cpp_hashnode *result;
- const U_CHAR *cur, *rlimit;
+ const U_CHAR *cur;
/* Fast-path loop. Skim over a normal identifier.
N.B. ISIDNUM does not include $. */
- cur = pfile->buffer->cur - 1;
- rlimit = pfile->buffer->rlimit;
- do
+ cur = pfile->buffer->cur;
+ while (ISIDNUM (*cur))
cur++;
- while (cur < rlimit && ISIDNUM (*cur));
/* Check for slow-path cases. */
- if (cur < rlimit && (*cur == '?' || *cur == '\\' || *cur == '$'))
+ if (*cur == '?' || *cur == '\\' || *cur == '$')
result = parse_identifier_slow (pfile, cur);
else
{
@@ -501,9 +489,6 @@ parse_identifier_slow (pfile, cur)
if (c == '$')
saw_dollar++;
- if (buffer->cur == buffer->rlimit)
- goto at_eof;
-
c = *buffer->cur++;
}
@@ -515,9 +500,8 @@ parse_identifier_slow (pfile, cur)
}
while (is_idchar (c));
- /* Step back over the unwanted char, except at EOF. */
+ /* Step back over the unwanted char. */
BACKUP ();
- at_eof:
/* $ is not an identifier character in the standard, but is commonly
accepted as an extension. Don't warn about it in skipped
@@ -573,9 +557,6 @@ parse_number (pfile, number, c, leading_period)
}
*dest++ = c;
- if (buffer->cur == buffer->rlimit)
- goto at_eof;
-
c = *buffer->cur++;
}
while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
@@ -588,9 +569,8 @@ parse_number (pfile, number, c, leading_period)
}
while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
- /* Step back over the unwanted char, except at EOF. */
+ /* Step back over the unwanted char. */
BACKUP ();
- at_eof:
/* Null-terminate the number. */
*dest = '\0';
@@ -671,12 +651,6 @@ parse_string (pfile, token, terminator)
limit = BUFF_LIMIT (pfile->u_buff);
}
- if (buffer->cur == buffer->rlimit)
- {
- unterminated (pfile, terminator);
- break;
- }
-
/* Handle trigraphs, escaped newlines etc. */
c = *buffer->cur++;
if (c == '?' || c == '\\')
@@ -724,10 +698,19 @@ parse_string (pfile, token, terminator)
handle_newline (pfile);
c = '\n';
}
- else if (c == '\0' && !warned_nulls)
+ else if (c == '\0')
{
- warned_nulls = true;
- cpp_warning (pfile, "null character(s) preserved in literal");
+ if (buffer->cur - 1 == buffer->rlimit)
+ {
+ unterminated (pfile, terminator);
+ buffer->cur--;
+ break;
+ }
+ if (!warned_nulls)
+ {
+ warned_nulls = true;
+ cpp_warning (pfile, "null character(s) preserved in literal");
+ }
}
*dest++ = c;
@@ -907,15 +890,19 @@ _cpp_lex_direct (pfile)
result->line = pfile->line;
skipped_white:
- if (buffer->cur == buffer->rlimit)
- goto at_eof;
c = *buffer->cur++;
result->col = CPP_BUF_COLUMN (buffer, buffer->cur);
trigraph:
switch (c)
{
- at_eof:
+ case ' ': case '\t': case '\f': case '\v': case '\0':
+ result->flags |= PREV_WHITE;
+ if (skip_whitespace (pfile, c))
+ goto skipped_white;
+
+ /* EOF. */
+ buffer->cur--;
buffer->saved_flags = BOL;
if (!pfile->state.parsing_args && !pfile->state.in_directive)
{
@@ -941,11 +928,6 @@ _cpp_lex_direct (pfile)
result->type = CPP_EOF;
break;
- case ' ': case '\t': case '\f': case '\v': case '\0':
- skip_whitespace (pfile, c);
- result->flags |= PREV_WHITE;
- goto skipped_white;
-
case '\n': case '\r':
handle_newline (pfile);
buffer->saved_flags = BOL;
@@ -1016,8 +998,7 @@ _cpp_lex_direct (pfile)
result->val.node = parse_identifier (pfile);
/* 'L' may introduce wide characters or strings. */
- if (result->val.node == pfile->spec_nodes.n_L
- && buffer->cur < buffer->rlimit)
+ if (result->val.node == pfile->spec_nodes.n_L)
{
c = *buffer->cur;
if (c == '\'' || c == '"')
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 324c7b21c4d..ea1d9f86860 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -1158,7 +1158,7 @@ destringize_and_run (pfile, in)
const unsigned char *src, *limit;
char *dest, *result;
- dest = result = alloca (in->len);
+ dest = result = alloca (in->len + 1);
for (src = in->text, limit = src + in->len; src < limit;)
{
/* We know there is a character following the backslash. */
@@ -1166,6 +1166,7 @@ destringize_and_run (pfile, in)
src++;
*dest++ = *src++;
}
+ *dest = '\0';
run_directive (pfile, T_PRAGMA, result, dest - result);
}
@@ -1647,9 +1648,8 @@ cpp_define (pfile, str)
Change the first "=" in the string to a space. If there is none,
tack " 1" on the end. */
- /* Length including the null. */
count = strlen (str);
- buf = (char *) alloca (count + 2);
+ buf = (char *) alloca (count + 3);
memcpy (buf, str, count);
p = strchr (str, '=');
@@ -1660,6 +1660,7 @@ cpp_define (pfile, str)
buf[count++] = ' ';
buf[count++] = '1';
}
+ buf[count] = '\0';
run_directive (pfile, T_DEFINE, buf, count);
}
@@ -1714,11 +1715,12 @@ handle_assertion (pfile, str, type)
{
/* Copy the entire option so we can modify it. Change the first
"=" in the string to a '(', and tack a ')' on the end. */
- char *buf = (char *) alloca (count + 1);
+ char *buf = (char *) alloca (count + 2);
memcpy (buf, str, count);
buf[p - str] = '(';
buf[count++] = ')';
+ buf[count] = '\0';
str = buf;
}
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index 403920c03a3..21d3cb1296b 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -82,7 +82,7 @@ static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
-static int warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *,
+static int warn_of_redefinition PARAMS ((const cpp_hashnode *,
const cpp_macro *));
static int save_parameter PARAMS ((cpp_reader *, cpp_macro *, cpp_hashnode *));
static int parse_params PARAMS ((cpp_reader *, cpp_macro *));
@@ -380,6 +380,7 @@ paste_tokens (pfile, plhs, rhs)
&& (rhs->type == CPP_MULT || rhs->type == CPP_DIV))
*end++ = ' ';
end = cpp_spell_token (pfile, rhs, end);
+ *end = '\0';
cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true, 1);
@@ -1112,8 +1113,7 @@ _cpp_backup_tokens (pfile, count)
/* Returns non-zero if a macro redefinition warning is required. */
static int
-warn_of_redefinition (pfile, node, macro2)
- cpp_reader *pfile;
+warn_of_redefinition (node, macro2)
const cpp_hashnode *node;
const cpp_macro *macro2;
{
@@ -1408,7 +1408,7 @@ _cpp_create_definition (pfile, node)
if (node->type != NT_VOID)
{
- if (warn_of_redefinition (pfile, node, macro))
+ if (warn_of_redefinition (node, macro))
{
cpp_pedwarn_with_line (pfile, pfile->directive_line, 0,
"\"%s\" redefined", NODE_NAME (node));
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 7c8480f4f84..bb38e01cc71 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -119,12 +119,12 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
#define LANG_HOOKS_INITIALIZER { \
LANG_HOOKS_NAME, \
LANG_HOOKS_IDENTIFIER_SIZE, \
- LANG_HOOKS_INIT, \
- LANG_HOOKS_FINISH, \
- LANG_HOOKS_CLEAR_BINDING_STACK, \
LANG_HOOKS_INIT_OPTIONS, \
LANG_HOOKS_DECODE_OPTION, \
LANG_HOOKS_POST_OPTIONS, \
+ LANG_HOOKS_INIT, \
+ LANG_HOOKS_FINISH, \
+ LANG_HOOKS_CLEAR_BINDING_STACK, \
LANG_HOOKS_GET_ALIAS_SET, \
LANG_HOOKS_HONOR_READONLY, \
LANG_HOOKS_PRINT_STATISTICS, \
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 4ec01e70d01..befdb0f6838 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -71,21 +71,8 @@ struct lang_hooks
identifier nodes long enough for the language-specific slots. */
size_t identifier_size;
- /* Called after options parsing, to initialize the front end. The
- main input filename is passed, which may be NULL; the front end
- should return the original filename (e.g. foo.i -> foo.c).
- Return NULL to indicate a serious error of some sort; in that
- case no compilation is performed, and the finish hook is called
- immediately. */
- const char * (*init) PARAMS ((const char *));
-
- /* Called last, as a finalizer. */
- void (*finish) PARAMS ((void));
-
- /* Called immediately after parsing to clear the binding stack. */
- void (*clear_binding_stack) PARAMS ((void));
-
- /* Called to initialize options, before any calls to decode_option. */
+ /* The first callback made to the front end, for simple
+ initialization needed before any calls to decode_option. */
void (*init_options) PARAMS ((void));
/* Function called with an option vector as argument, to decode a
@@ -98,9 +85,26 @@ struct lang_hooks
done for this option. */
int (*decode_option) PARAMS ((int, char **));
- /* Called when all command line options have been parsed. */
+ /* Called when all command line options have been parsed. Should do
+ any required consistency checks, modifications etc. Complex
+ initialization should be left to the "init" callback, since GC
+ and the identifier hashes are set up between now and then. */
void (*post_options) PARAMS ((void));
+ /* Called after post_options, to initialize the front end. The main
+ input filename is passed, which may be NULL; the front end should
+ return the original filename (e.g. foo.i -> foo.c). Return NULL
+ to indicate a serious error of some sort; in that case no
+ compilation is performed, and the finish hook is called
+ immediately. */
+ const char * (*init) PARAMS ((const char *));
+
+ /* Called at the end of compilation, as a finalizer. */
+ void (*finish) PARAMS ((void));
+
+ /* Called immediately after parsing to clear the binding stack. */
+ void (*clear_binding_stack) PARAMS ((void));
+
/* Called to obtain the alias set to be used for an expression or type.
Returns -1 if the language does nothing special for it. */
HOST_WIDE_INT (*get_alias_set) PARAMS ((tree));
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index c98b61f02ab..474df1afdba 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -478,7 +478,7 @@ static varray_type deferred_fns;
static void
objc_post_options ()
{
- cpp_post_options (parse_in);
+ c_common_post_options ();
}
/* Some platforms pass small structures through registers versus through
@@ -547,8 +547,7 @@ generate_struct_by_value_array ()
static void
objc_init_options ()
{
- parse_in = cpp_create_reader (CLK_OBJC);
- c_language = clk_objective_c;
+ c_common_init_options (clk_objective_c);
}
static const char *
@@ -557,7 +556,7 @@ objc_init (filename)
{
c_init_decl_processing ();
- filename = c_common_lang_init (filename);
+ filename = c_common_init (filename);
add_c_tree_codes ();
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 7ee39cba43c..72c93a799b2 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -126,6 +126,7 @@ extern tree last_assemble_variable_decl;
static void general_init PARAMS ((char *));
static void parse_options_and_default_flags PARAMS ((int, char **));
+static void do_compile PARAMS ((void));
static void process_options PARAMS ((void));
static void lang_independent_init PARAMS ((void));
static int lang_dependent_init PARAMS ((const char *));
@@ -1177,7 +1178,7 @@ lang_independent_options f_options[] =
{"mem-report", &mem_report, 1,
N_("Report on permanent memory allocation at end of run") },
{ "trapv", &flag_trapv, 1,
- N_("Trap for signed overflow in addition / subtraction / multiplication.") },
+ N_("Trap for signed overflow in addition / subtraction / multiplication") },
};
/* Table of language-specific options. */
@@ -4787,7 +4788,8 @@ parse_options_and_default_flags (argc, argv)
}
}
- /* All command line options have been processed. */
+ /* All command line options have been parsed; allow the front end to
+ perform consistency checks, etc. */
(*lang_hooks.post_options) ();
}
@@ -4837,7 +4839,7 @@ process_options ()
if (profile_block_flag == 3)
{
- warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
+ warning ("`-ax' and `-a' are conflicting options. `-a' ignored");
profile_block_flag = 2;
}
@@ -4951,12 +4953,12 @@ process_options ()
{
if (flag_function_sections)
{
- warning ("-ffunction-sections not supported for this target.");
+ warning ("-ffunction-sections not supported for this target");
flag_function_sections = 0;
}
if (flag_data_sections)
{
- warning ("-fdata-sections not supported for this target.");
+ warning ("-fdata-sections not supported for this target");
flag_data_sections = 0;
}
}
@@ -4964,13 +4966,13 @@ process_options ()
if (flag_function_sections
&& (profile_flag || profile_block_flag))
{
- warning ("-ffunction-sections disabled; it makes profiling impossible.");
+ warning ("-ffunction-sections disabled; it makes profiling impossible");
flag_function_sections = 0;
}
#ifndef OBJECT_FORMAT_ELF
if (flag_function_sections && write_symbols != NO_DEBUG)
- warning ("-ffunction-sections may affect debugging on some targets.");
+ warning ("-ffunction-sections may affect debugging on some targets");
#endif
}
@@ -5127,29 +5129,10 @@ finalize ()
(*lang_hooks.finish) ();
}
-/* Entry point of cc1, cc1plus, jc1, f771, etc.
- Decode command args, then call compile_file.
- Exit code is FATAL_EXIT_CODE if can't open files or if there were
- any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
-
- It is not safe to call this function more than once. */
-
-int
-toplev_main (argc, argv)
- int argc;
- char **argv;
+/* Initialize the compiler, and compile the input file. */
+static void
+do_compile ()
{
- /* Initialization of GCC's environment, and diagnostics. */
- general_init (argv [0]);
-
- /* Parse the options and do minimal processing; basically just
- enough to default flags appropriately. */
- parse_options_and_default_flags (argc, argv);
-
- /* Exit early if we can (e.g. -help). */
- if (exit_after_options)
- return (SUCCESS_EXIT_CODE);
-
/* The bulk of command line switch processing. */
process_options ();
@@ -5171,6 +5154,30 @@ toplev_main (argc, argv)
/* Stop timing and print the times. */
timevar_stop (TV_TOTAL);
timevar_print (stderr);
+}
+
+/* Entry point of cc1, cc1plus, jc1, f771, etc.
+ Decode command args, then call compile_file.
+ Exit code is FATAL_EXIT_CODE if can't open files or if there were
+ any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
+
+ It is not safe to call this function more than once. */
+
+int
+toplev_main (argc, argv)
+ int argc;
+ char **argv;
+{
+ /* Initialization of GCC's environment, and diagnostics. */
+ general_init (argv [0]);
+
+ /* Parse the options and do minimal processing; basically just
+ enough to default flags appropriately. */
+ parse_options_and_default_flags (argc, argv);
+
+ /* Exit early if we can (e.g. -help). */
+ if (!exit_after_options)
+ do_compile ();
if (errorcount || sorrycount)
return (FATAL_EXIT_CODE);