This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: compile server design document
- From: Per Bothner <per at bothner dot com>
- To: Per Bothner <pbothner at apple dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 26 Feb 2003 23:05:13 -0800
- Subject: Re: compile server design document
- References: <3E5D6970.6080108@apple.com>
Attached is a recent snapshot of the compile server.
This predates the C++ work which I've just started,
and is C-only. I.e. you should configure with
--enable-languages=c if you want to try it.
But mainly this is for illustration. It is certainly
not being proposed for checking into cvs as is!
--
--Per Bothner
per at bothner dot com http://www.bothner.com/per/
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.167
diff -c -r1.167 c-common.h
*** c-common.h 18 Jan 2003 02:26:40 -0000 1.167
--- c-common.h 8 Feb 2003 20:05:02 -0000
***************
*** 180,185 ****
--- 180,236 ----
struct cpp_hashnode node;
};
+ #define DECL_FRAGMENT(DECL) \
+ ((struct c_include_fragment *) DECL_CHECK (DECL)->decl.defining_fragment)
+ #define SET_DECL_FRAGMENT(DECL, FRAGMENT) \
+ (DECL_CHECK (DECL)->decl.defining_fragment = (tree) (FRAGMENT))
+ #define C_FRAGMENT(FRAG) ((struct c_include_fragment *) (FRAG)->start_marker)
+
+ struct c_include_fragment GTY(())
+ {
+ struct tree_common common;
+ const char *name;
+ /* Value of c_timestamp when this fragment was last read (parsed). */
+ int read_timestamp;
+ /* Value of c_timestamp when this fragment was last logically included. */
+ int include_timestamp;
+ /* True if a declaration in this fragmemt was used in current_c_fragment. */
+ unsigned used_in_current : 1;
+ unsigned valid : 1;
+ /* A TREE_VEC whose members are other c_include_fragments. An element is in
+ uses_fragments iff the current fragments uses (references) a declartion
+ in that element. */
+ tree uses_fragments;
+ tree bindings;
+ };
+
+ extern int main_timestamp;
+ extern int c_timestamp;
+ extern GTY(()) struct c_include_fragment *current_c_fragment;
+ extern int currently_nested;
+
+ extern void register_decl_dependency PARAMS ((tree));
+ extern struct c_include_fragment * alloc_include_fragment PARAMS ((void));
+ extern void remember_fragment_start PARAMS ((struct c_include_fragment *));
+ extern void remember_fragment_end PARAMS ((struct c_include_fragment *));
+ extern void restore_from_fragment PARAMS ((struct c_include_fragment *));
+ extern void note_fragment_binding_1 PARAMS ((tree));
+ extern void note_fragment_binding_2 PARAMS ((tree, tree));
+ extern void note_fragment_binding_3 PARAMS ((tree, tree, tree));
+ extern void setup_globals PARAMS ((void));
+
+ extern void* cb_push_fragment PARAMS ((cpp_reader*, cpp_fragment*, const char*, int));
+ extern void cb_pop_fragment PARAMS ((cpp_reader*, cpp_fragment*));
+
+ #if 0
+ #define FRAGMENT_OLDEST_DECL(NODE) \
+ (((struct c_include_fragment *) (NODE))->oldest_decl)
+ #define FRAGMENT_NEWEST_DECL(NODE) \
+ (((struct c_include_fragment *) (NODE))->newest_decl)
+ #define FRAGMENT_PREVIOUS_FRAGMENT_DECL(NODE) \
+ (((struct c_include_fragment *) (NODE))->previous_fragment_decl)
+ #endif
+
#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]
#define signed_wchar_type_node c_global_trees[CTI_SIGNED_WCHAR_TYPE]
#define unsigned_wchar_type_node c_global_trees[CTI_UNSIGNED_WCHAR_TYPE]
***************
*** 916,921 ****
--- 967,974 ----
extern tree convert_and_check PARAMS ((tree, tree));
extern void overflow_warning PARAMS ((tree));
extern void unsigned_conversion_warning PARAMS ((tree, tree));
+
+ extern void c_initially_decl_processing PARAMS ((void));
/* Read the rest of the current #-directive line. */
extern char *get_directive_line PARAMS ((void));
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.175
diff -c -r1.175 cpphash.h
*** cpphash.h 21 Jan 2003 00:12:52 -0000 1.175
--- cpphash.h 8 Feb 2003 20:05:03 -0000
***************
*** 267,272 ****
--- 267,297 ----
unsigned char printed; /* Nonzero if something output at line. */
};
+ struct cpp_fragment
+ {
+ const char *name; /* actual path name of file REDUNDANT */
+ cpp_fragment *next;
+ const unsigned char *start;
+ const unsigned char *end;
+ unsigned was_reused : 1;
+ /*unsigned int valid : 1;*/
+ void *start_marker; /* Returned from front-end - kludge. */
+ unsigned int start_line;
+ unsigned int end_line;
+ const unsigned char *end_line_base;
+ };
+
+ /* Used by compile server to restore previous macro state. */
+ struct cpp_macro_note
+ {
+ cpp_hashnode *node;
+ struct cpp_macro *macro; /* null for an #undef */
+ };
+ extern void _cpp_note_macro PARAMS ((cpp_reader *,
+ cpp_hashnode *, cpp_macro *));
+ extern void _cpp_restore_macros PARAMS ((cpp_reader *,
+ struct cpp_macro_note *, int));
+
/* Represents the contents of a file cpplib has read in. */
struct cpp_buffer
{
***************
*** 323,328 ****
--- 348,355 ----
/* Used for buffer overlays by cpptrad.c. */
const uchar *saved_cur, *saved_rlimit;
+
+ cpp_fragment *saved_current_fragment;
};
/* A cpp_reader encapsulates the "state" of a pre-processor run.
***************
*** 343,348 ****
--- 370,376 ----
struct line_maps line_maps;
const struct line_map *map;
unsigned int line;
+ const char *main_input_filename;
/* The line of the '#' of the current directive. */
unsigned int directive_line;
***************
*** 386,391 ****
--- 414,426 ----
/* Tree of other included files. See cppfiles.c. */
struct splay_tree_s *all_include_files;
+
+ cpp_fragment *current_fragment;
+
+ int do_note_macros;
+ struct cpp_macro_note *macro_notes;
+ int macro_notes_alloc_length;
+ int macro_notes_count;
/* Current maximum length of directory names in the search path
for include files. (Altered as we get more of them.) */
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.242
diff -c -r1.242 cpplib.h
*** cpplib.h 28 Jan 2003 19:30:00 -0000 1.242
--- cpplib.h 8 Feb 2003 20:05:04 -0000
***************
*** 39,44 ****
--- 39,45 ----
typedef struct cpp_hashnode cpp_hashnode;
typedef struct cpp_macro cpp_macro;
typedef struct cpp_callbacks cpp_callbacks;
+ typedef struct cpp_fragment cpp_fragment;
struct answer;
struct file_name_map_list;
***************
*** 419,424 ****
--- 420,428 ----
void (*file_change) PARAMS ((cpp_reader *, const struct line_map *));
void (*include) PARAMS ((cpp_reader *, unsigned int,
const unsigned char *, const cpp_token *));
+ void* (*push_fragment) PARAMS ((cpp_reader *, cpp_fragment *,
+ const char*, int));
+ void (*pop_fragment) PARAMS ((cpp_reader *, cpp_fragment *));
void (*define) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
void (*undef) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
void (*ident) PARAMS ((cpp_reader *, unsigned int, const cpp_string *));
***************
*** 540,545 ****
--- 544,551 ----
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
+ /* FIXME this comment needs fixing, but leave it until later,
+ due to gcc-3.3 and gcc-3.4 type fix causing patch hassles. */
/* This function reads the file, but does not start preprocessing. It
returns the name of the original file; this is the same as the
input file, except for preprocessed input. This will generate at
***************
*** 550,557 ****
pointer. Otherwise you should pass in an initialized hash table
that cpplib will share; this technique is used by the C front
ends. */
! extern const char *cpp_read_main_file PARAMS ((cpp_reader *, const char *,
! struct ht *));
/* Deferred handling of command line options that can generate debug
callbacks, such as -D and -imacros. Call this after
--- 556,563 ----
pointer. Otherwise you should pass in an initialized hash table
that cpplib will share; this technique is used by the C front
ends. */
! extern const char *cpp_read_main_file PARAMS ((cpp_reader *, const char *));
! extern void cpp_init_tables PARAMS ((cpp_reader *, struct ht *));
/* Deferred handling of command line options that can generate debug
callbacks, such as -D and -imacros. Call this after
***************
*** 590,595 ****
--- 596,604 ----
extern const unsigned char *cpp_macro_definition PARAMS ((cpp_reader *,
const cpp_hashnode *));
extern void _cpp_backup_tokens PARAMS ((cpp_reader *, unsigned int));
+ extern void _cpp_start_fragment PARAMS ((cpp_reader *));
+ extern void _cpp_push_fragment PARAMS ((cpp_reader *, cpp_fragment*));
+ extern void _cpp_pop_fragment PARAMS ((cpp_reader *, cpp_fragment*));
/* Evaluate a CPP_CHAR or CPP_WCHAR token. */
extern cppchar_t
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.109
diff -c -r1.109 c-tree.h
*** c-tree.h 16 Sep 2002 18:33:18 -0000 1.109
--- c-tree.h 8 Feb 2003 20:05:04 -0000
***************
*** 244,249 ****
--- 244,250 ----
/* in c-objc-common.c */
extern int c_disregard_inline_limits PARAMS ((tree));
extern int c_cannot_inline_tree_fn PARAMS ((tree *));
+ extern void c_objc_common_initially PARAMS ((void));
extern const char *c_objc_common_init PARAMS ((const char *));
extern int c_missing_noreturn_ok_p PARAMS ((tree));
extern void c_objc_common_finish_file PARAMS ((void));
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.96
diff -c -r1.96 flags.h
*** flags.h 24 Jan 2003 15:17:24 -0000 1.96
--- flags.h 8 Feb 2003 20:05:04 -0000
***************
*** 664,669 ****
--- 664,671 ----
/* Nonzero means disable transformations observable by signaling NaNs. */
extern int flag_signaling_nans;
+ extern int is_server;
+
/* True if the given mode has a NaN representation and the treatment of
NaN operands is important. Certain optimizations, such as folding
x * 0 into x, are not correct for NaN operands, and are normally
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.40
diff -c -r1.40 langhooks-def.h
*** langhooks-def.h 16 Dec 2002 18:19:40 -0000 1.40
--- langhooks-def.h 8 Feb 2003 20:05:05 -0000
***************
*** 85,90 ****
--- 85,91 ----
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
#define LANG_HOOKS_INIT lhd_do_nothing
+ #define LANG_HOOKS_INITIALLY lhd_do_nothing
#define LANG_HOOKS_FINISH lhd_do_nothing
#define LANG_HOOKS_PARSE_FILE lhd_do_nothing_i
#define LANG_HOOKS_CLEAR_BINDING_STACK lhd_clear_binding_stack
***************
*** 228,233 ****
--- 229,235 ----
LANG_HOOKS_INIT_OPTIONS, \
LANG_HOOKS_DECODE_OPTION, \
LANG_HOOKS_POST_OPTIONS, \
+ LANG_HOOKS_INITIALLY, \
LANG_HOOKS_INIT, \
LANG_HOOKS_FINISH, \
LANG_HOOKS_PARSE_FILE, \
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.h,v
retrieving revision 1.49
diff -c -r1.49 langhooks.h
*** langhooks.h 16 Dec 2002 18:19:41 -0000 1.49
--- langhooks.h 8 Feb 2003 20:05:05 -0000
***************
*** 206,217 ****
immediately and the finish hook is not called. */
bool (*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. */
--- 206,221 ----
immediately and the finish hook is not called. */
bool (*post_options) PARAMS ((void));
! /* Called after post_options, to initialize the front end.
! This only gets call once, even if we're invoked as a server. */
! void (*initially) PARAMS ((void));
!
! /* Called (after initially) to initially the front-end for a main file.
! If we're invoked as a server, this is called once for each request.
! The 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. */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.379
diff -c -r1.379 tree.h
*** tree.h 31 Jan 2003 14:46:47 -0000 1.379
--- tree.h 8 Feb 2003 20:05:07 -0000
***************
*** 1792,1797 ****
--- 1792,1799 ----
{
struct tree_common common;
location_t locus;
+ /* FIXME make part of locus - or of context! */
+ tree defining_fragment;
unsigned int uid;
tree size;
ENUM_BITFIELD(machine_mode) mode : 8;
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.399
diff -c -r1.399 c-common.c
*** c-common.c 30 Jan 2003 07:23:57 -0000 1.399
--- c-common.c 8 Feb 2003 20:05:11 -0000
***************
*** 38,43 ****
--- 38,44 ----
#include "tm_p.h"
#include "obstack.h"
#include "cpplib.h"
+ #include "cpphash.h"
#include "target.h"
#include "langhooks.h"
#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
***************
*** 3185,3190 ****
--- 3186,3195 ----
static void c_init_attributes PARAMS ((void));
+ static void reserve_fragment_binding PARAMS ((int));
+
+ static int common_nodes_and_builtins_done;
+
/* Build tree nodes and builtin functions common to both C and C++ language
frontends. */
***************
*** 3225,3230 ****
--- 3230,3239 ----
tree va_list_ref_type_node;
tree va_list_arg_type_node;
+ setup_globals ();
+ if (common_nodes_and_builtins_done++ > 0)
+ return; /* FIXME - never happens? */
+
/* Define `int' and `char' first so that dbx will output them first. */
record_builtin_type (RID_INT, NULL, integer_type_node);
record_builtin_type (RID_CHAR, "char", char_type_node);
***************
*** 4725,4730 ****
--- 4734,4973 ----
return val;
}
+ /* A stack of include fragments that are used by current_c_fragment
+ or other not-yet popped headers. The ones in current_c_fragment
+ are whose at index from 0 to current_fragment_deps_end (exclusive). */
+ static GTY (()) tree current_fragment_deps_stack;
+ /* The number of elements in current_include_deps_stack that are in use. */
+ static int current_fragment_deps_end;
+
+ struct c_include_fragment *current_c_fragment;
+
+ extern void register_fragment_dependency PARAMS ((struct c_include_fragment*));
+
+ void
+ register_decl_dependency (used)
+ tree used;
+ {
+ struct c_include_fragment *fragment;
+ const char *file = DECL_SOURCE_FILE (used);
+ if (file == NULL)
+ return;
+ if (strcmp (file, "<built-in>") == 0)
+ return;
+
+ fragment = DECL_FRAGMENT (used);
+ if (fragment == NULL)
+ return;
+ register_fragment_dependency (fragment);
+ }
+
+ tree fragment_bindings_stack;
+ int fragment_bindings_end;
+
+ static void
+ reserve_fragment_binding (space_needed)
+ int space_needed;
+ {
+ if (fragment_bindings_stack == NULL_TREE)
+ fragment_bindings_stack = make_tree_vec (50);
+ else if (TREE_VEC_LENGTH (fragment_bindings_stack)
+ < fragment_bindings_end + space_needed)
+ {
+ /* Re-size fragment_bindings_stack. */
+ int i = fragment_bindings_end;
+ tree new_vec = make_tree_vec (2 * i);
+ while (--i >= 0)
+ TREE_VEC_ELT (new_vec, i)
+ = TREE_VEC_ELT (fragment_bindings_stack, i);
+ fragment_bindings_stack = new_vec;
+ }
+ fragment_bindings_end += space_needed;
+ }
+
+ void
+ note_fragment_binding_1 (tree1)
+ tree tree1;
+ {
+ reserve_fragment_binding (1);
+ TREE_VEC_ELT (fragment_bindings_stack, fragment_bindings_end - 1) = tree1;
+ }
+
+ void
+ note_fragment_binding_2 (tree1, tree2)
+ tree tree1, tree2;
+ {
+ reserve_fragment_binding (2);
+ TREE_VEC_ELT (fragment_bindings_stack, fragment_bindings_end - 2) = tree1;
+ TREE_VEC_ELT (fragment_bindings_stack, fragment_bindings_end - 1) = tree2;
+ }
+
+ void
+ note_fragment_binding_3 (tree1, tree2, tree3)
+ tree tree1, tree2, tree3;
+ {
+ reserve_fragment_binding (3);
+ TREE_VEC_ELT (fragment_bindings_stack, fragment_bindings_end - 3) = tree1;
+ TREE_VEC_ELT (fragment_bindings_stack, fragment_bindings_end - 2) = tree2;
+ TREE_VEC_ELT (fragment_bindings_stack, fragment_bindings_end - 1) = tree3;
+ }
+
+ void
+ register_fragment_dependency (used)
+ struct c_include_fragment* used;
+ {
+ if (! used->used_in_current && used != current_c_fragment
+ && current_c_fragment != NULL)
+ {
+ if (current_fragment_deps_stack == NULL_TREE)
+ current_fragment_deps_stack = make_tree_vec (50);
+ else if (TREE_VEC_LENGTH (current_fragment_deps_stack)
+ == current_fragment_deps_end)
+ {
+ /* Re-size current_fragment_deps_stack. */
+ int i = current_fragment_deps_end;
+ tree new_vec = make_tree_vec (2 * i);
+ while (--i >= 0)
+ TREE_VEC_ELT (new_vec, i)
+ = TREE_VEC_ELT (current_fragment_deps_stack, i);
+ current_fragment_deps_stack = new_vec;
+ }
+ TREE_VEC_ELT (current_fragment_deps_stack, current_fragment_deps_end)
+ = (tree) used;
+ current_fragment_deps_end++;
+ used->used_in_current = 1;
+ }
+ }
+
+ int main_timestamp;
+ int c_timestamp;
+ /* Inside an incomple enum, for example. */
+ int currently_nested;
+
+ void*
+ cb_push_fragment (reader, fragment, name, line)
+ cpp_reader* reader ATTRIBUTE_UNUSED;
+ cpp_fragment *fragment;
+ const char* name;
+ int line;
+ {
+ struct c_include_fragment* st = C_FRAGMENT (fragment);
+ void *ret;
+ bool valid = 0;
+ if (st != NULL)
+ {
+ int i;
+ valid = st->valid && st->include_timestamp < main_timestamp && ! currently_nested;
+
+ if (valid)
+ {
+ /* Check dependencies. */
+ tree d = st->uses_fragments;
+ for (i = d == NULL_TREE ? 0 : TREE_VEC_LENGTH (d); --i >= 0; )
+ {
+ struct c_include_fragment *uses
+ = (struct c_include_fragment *) TREE_VEC_ELT (d, i);
+ if (uses->include_timestamp < main_timestamp
+ || uses->read_timestamp == 0
+ || uses->read_timestamp > st->read_timestamp)
+ {
+ valid = 0;
+ break;
+ }
+ }
+ }
+
+ if (! valid)
+ {
+ st->valid = 0;
+ if (! quiet_flag)
+ fprintf (stderr, "(invalidating cached fragment %s:%d)\n", name, line);
+ }
+ else
+ {
+ if (! quiet_flag)
+ fprintf (stderr, "(reusing cached fragment %s:%d)\n", name, line);
+ restore_from_fragment (st);
+ ret = NULL;
+ }
+ }
+ else
+ {
+ st = alloc_include_fragment ();
+ st->name = name;
+ st->valid = 0;
+ }
+ st->include_timestamp = ++c_timestamp;
+ if (! valid)
+ {
+ st->read_timestamp = 0;
+ st->uses_fragments = NULL_TREE;
+ st->bindings = NULL_TREE;
+ /*st->used_in_current = 0;*/
+
+ ret = st;
+ current_fragment_deps_end = 0;
+ fragment_bindings_end = 0;
+ st->read_timestamp = st->include_timestamp;
+ }
+ current_c_fragment = st;
+ /* Note fragment->was_resued is redundant - it's same as
+ st->include_timestamp > st->read_timestamp */
+ fragment->was_reused = ret == NULL;
+ return ret;
+ }
+
+ void
+ cb_pop_fragment (reader, fragment)
+ cpp_reader *reader ATTRIBUTE_UNUSED;
+ cpp_fragment *fragment;
+ {
+ struct c_include_fragment* st = C_FRAGMENT (fragment);
+ if (st != NULL)
+ {
+ int i;
+
+ int uses_fragments_count = current_fragment_deps_end;
+ tree uses_fragments = (uses_fragments_count == 0 ? NULL_TREE
+ : make_tree_vec (uses_fragments_count));
+
+ tree bindings = (fragment_bindings_end == 0 ? NULL_TREE
+ : make_tree_vec (fragment_bindings_end));
+ for (i = 0; i < fragment_bindings_end; i++)
+ {
+ TREE_VEC_ELT (bindings, i)
+ = TREE_VEC_ELT (fragment_bindings_stack, i);
+ /* Clean up for the sake of garbage collection. ??? */
+ TREE_VEC_ELT (fragment_bindings_stack, i) = NULL;
+ }
+ st->bindings = bindings;
+ fragment_bindings_end = 0;
+
+ for (i = 0; i < current_fragment_deps_end; i++)
+ {
+ tree uses = TREE_VEC_ELT (current_fragment_deps_stack, i);
+ TREE_VEC_ELT (uses_fragments, i) = uses;
+ ((struct c_include_fragment*) uses)->used_in_current = 0;
+ /* Clean up for the sake of garbage collection. ??? */
+ TREE_VEC_ELT (current_fragment_deps_stack, i) = NULL;
+ }
+ st->uses_fragments = uses_fragments;
+ current_fragment_deps_end = 0;
+ for (i = 0; i < current_fragment_deps_end; i++)
+ {
+ ((struct c_include_fragment*) TREE_VEC_ELT (current_fragment_deps_stack, i))->used_in_current = 1;
+ }
+
+ current_c_fragment = NULL;
+ st->valid = ! currently_nested;
+ }
+ #if 0
+ fprintf(stderr, "(pop deps start:%d end:%d for %s ret:%s)\n",
+ current_fragment_deps_start, current_fragment_deps_end, st->name,
+ (st ? "non-null":"null"));
+ #endif
+ }
+
/* Define NAME with value TYPE precision. */
static void
builtin_define_type_precision (name, type)
***************
*** 4918,4923 ****
--- 5161,5169 ----
/* -undef turns off target-specific built-ins. */
if (flag_undef)
return;
+
+ if (is_server)
+ pfile->do_note_macros = 1;
if (c_language == clk_cplusplus)
{
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.361
diff -c -r1.361 c-decl.c
*** c-decl.c 24 Jan 2003 15:17:24 -0000 1.361
--- c-decl.c 8 Feb 2003 20:05:16 -0000
***************
*** 43,48 ****
--- 43,49 ----
#include "ggc.h"
#include "tm_p.h"
#include "cpplib.h"
+ #include "cpphash.h"
#include "target.h"
#include "debug.h"
#include "timevar.h"
***************
*** 344,349 ****
--- 345,474 ----
}
}
+ static int c_init_decl_done;
+ static GTY(()) tree builtins_end;
+
+ static void restore_fragment_bindings PARAMS ((struct c_include_fragment *));
+
+ static void
+ restore_fragment_bindings (fragment)
+ struct c_include_fragment *fragment;
+ {
+ int i;
+ tree bindings = fragment->bindings;
+ int len;
+ struct binding_level *b = current_binding_level;
+ if (bindings == NULL_TREE)
+ return;
+ len = TREE_VEC_LENGTH (bindings);
+ for (i = 0; i < len; )
+ {
+ tree x = TREE_VEC_ELT (bindings, i);
+
+ if (TREE_CODE_CLASS (TREE_CODE (x)) == 'd')
+ {
+ tree n = DECL_NAME (x);
+ if (n != NULL_TREE)
+ IDENTIFIER_GLOBAL_VALUE (n) = x;
+ TREE_CHAIN (x) = b->names;
+ b->names = x;
+ i++;
+ }
+ else if (TREE_CODE (x) == TREE_LIST) /* pushtag */
+ {
+ tree type = TREE_VALUE (x);
+ TREE_CHAIN (x) = b->tags;
+ TYPE_SIZE (type) = NULL_TREE;
+ TYPE_FIELDS (type) = NULL_TREE;
+ b->tags = x;
+ i++;
+ }
+ else if (TREE_CODE_CLASS (TREE_CODE (x)) == 't')
+ { /* finish_struct */
+ tree type = x;
+ TYPE_FIELDS (type) = TREE_VEC_ELT (bindings, i + 1);
+ TYPE_SIZE (type) = TREE_VEC_ELT (bindings, i + 2);
+ i += 3;
+ }
+ else
+ abort ();
+ }
+ }
+
+ void
+ restore_from_fragment (fragment)
+ struct c_include_fragment *fragment;
+ {
+ restore_fragment_bindings (fragment);
+ }
+
+ extern int clear_identifiers PARAMS ((cpp_reader*, cpp_hashnode*, void*));
+ int
+ clear_identifiers (pfile, node, v)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ cpp_hashnode *node;
+ void *v ATTRIBUTE_UNUSED;
+ {
+ tree tnode = HT_IDENT_TO_GCC_IDENT (node);
+ struct lang_identifier * lang_id = (struct lang_identifier *) tnode;
+ node->flags &= ~ NODE_POISONED; /* ??? also clear NODE_DIAGNOSTIC? */
+ if (TREE_CODE (tnode) != IDENTIFIER_NODE)
+ abort();
+ if (lang_id != NULL)
+ lang_id->global_value = NULL_TREE;
+ if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
+ {
+ cpp_macro *macro = node->value.macro;
+ macro->used = 0;
+
+ _cpp_free_definition (node);
+ }
+
+ return 1;
+ }
+
+ void setup_globals ()
+ {
+ current_function_decl = NULL;
+ named_labels = NULL;
+ current_binding_level = NULL_BINDING_LEVEL;
+
+ /* Make the binding_level structure for global names. */
+ pushlevel (0);
+ global_binding_level = current_binding_level;
+ }
+
+ void
+ c_init_decl_processing ()
+ {
+
+ main_timestamp = ++c_timestamp;
+ if (c_init_decl_done++ == 0)
+ {
+ setup_globals ();
+ parse_in->do_note_macros = 0;
+ }
+ else
+ {
+ tree d;
+ struct c_include_fragment *fragment;
+
+ cpp_forall_identifiers (parse_in, clear_identifiers, NULL);
+ _cpp_restore_macros (parse_in,
+ parse_in->macro_notes, parse_in->macro_notes_count);
+
+ global_binding_level->names = builtins_end;
+ global_binding_level->tags = NULL_TREE;
+
+ for (d = builtins_end; d != NULL_TREE; d = TREE_CHAIN (d))
+ {
+ tree n = DECL_NAME (d);
+ if (n != NULL_TREE)
+ IDENTIFIER_GLOBAL_VALUE (n) = d;
+ }
+ }
+ }
+
/* Reuse or create a struct for this binding level. */
static struct binding_level *
***************
*** 831,836 ****
--- 956,966 ----
b->tags = tree_cons (name, type, b->tags);
+ if (b == global_binding_level && is_server)
+ {
+ note_fragment_binding_1 (b->tags);
+ }
+
/* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
tagged type we just added to the current binding level. This fake
NULL-named TYPE_DECL node helps dwarfout.c to know when it needs
***************
*** 1839,1844 ****
--- 1969,1979 ----
TREE_PUBLIC (name) = 1;
IDENTIFIER_GLOBAL_VALUE (name) = x;
+ if (is_server)
+ {
+ SET_DECL_FRAGMENT (x, current_c_fragment);
+ note_fragment_binding_1 (x);
+ }
/* We no longer care about any previous block level declarations. */
IDENTIFIER_LIMBO_VALUE (name) = 0;
***************
*** 2432,2437 ****
--- 2567,2574 ----
val = IDENTIFIER_LOCAL_VALUE (name);
else
val = IDENTIFIER_GLOBAL_VALUE (name);
+ if (val != NULL_TREE && is_server)
+ register_decl_dependency (val);
return val;
}
***************
*** 2462,2468 ****
Make definitions for built-in primitive functions. */
void
! c_init_decl_processing ()
{
tree endlink;
tree ptr_ftype_void, ptr_ftype_ptr;
--- 2599,2605 ----
Make definitions for built-in primitive functions. */
void
! c_initially_decl_processing ()
{
tree endlink;
tree ptr_ftype_void, ptr_ftype_ptr;
***************
*** 2470,2484 ****
/* Adds some ggc roots, and reserved words for c-parse.in. */
c_parse_init ();
- current_function_decl = NULL;
- named_labels = NULL;
- current_binding_level = NULL_BINDING_LEVEL;
free_binding_level = NULL_BINDING_LEVEL;
- /* Make the binding_level structure for global names. */
- pushlevel (0);
- global_binding_level = current_binding_level;
-
build_common_tree_nodes (flag_signed_char);
c_common_nodes_and_builtins ();
--- 2607,2614 ----
***************
*** 2509,2514 ****
--- 2639,2645 ----
make_fname_decl = c_make_fname_decl;
start_fname_decls ();
+ builtins_end = global_binding_level->names;
}
/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
***************
*** 5302,5307 ****
--- 5433,5443 ----
layout_type (t);
+ if (is_server)
+ {
+ note_fragment_binding_3 (t, fieldlist, TYPE_SIZE (t));
+ }
+
/* Delete all zero-width bit-fields from the fieldlist */
{
tree *fieldlistp = &fieldlist;
***************
*** 5450,5455 ****
--- 5586,5593 ----
if (flag_short_enums)
TYPE_PACKED (enumtype) = 1;
+ currently_nested++;
+
return enumtype;
}
***************
*** 5470,5475 ****
--- 5608,5615 ----
int precision, unsign;
int toplevel = (global_binding_level == current_binding_level);
+ currently_nested--;
+
if (in_parm_level_p ())
warning ("enum defined inside parms");
***************
*** 5562,5567 ****
--- 5702,5712 ----
}
TYPE_VALUES (enumtype) = values;
+ }
+
+ if (is_server)
+ {
+ note_fragment_binding_3 (enumtype, values, TYPE_SIZE (enumtype));
}
/* Fix up all variant types of this enum type. */
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lang.c,v
retrieving revision 1.101
diff -c -r1.101 c-lang.c
*** c-lang.c 16 Dec 2002 18:19:02 -0000 1.101
--- c-lang.c 8 Feb 2003 20:05:16 -0000
***************
*** 37,42 ****
--- 37,44 ----
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C"
+ #undef LANG_HOOKS_INITIALLY
+ #define LANG_HOOKS_INITIALLY c_objc_common_initially
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT c_objc_common_init
#undef LANG_HOOKS_FINISH
Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.193
diff -c -r1.193 c-lex.c
*** c-lex.c 13 Jan 2003 00:14:58 -0000 1.193
--- c-lex.c 8 Feb 2003 20:05:17 -0000
***************
*** 139,146 ****
/* Start it at 0. */
lineno = 0;
! return cpp_read_main_file (parse_in, filename, ident_hash);
}
/* A thin wrapper around the real parser that initializes the
integrated preprocessor after debug output has been initialized.
--- 139,149 ----
/* Start it at 0. */
lineno = 0;
! return cpp_read_main_file (parse_in, filename);
}
+
+ /* kludge to reduce patch conflicts with Apple PFE */
+ #define cpp_finish_options(parse_in) ((void)0)
/* A thin wrapper around the real parser that initializes the
integrated preprocessor after debug output has been initialized.
Index: c-objc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-objc-common.c,v
retrieving revision 1.20
diff -c -r1.20 c-objc-common.c
*** c-objc-common.c 10 Jan 2003 02:21:58 -0000 1.20
--- c-objc-common.c 8 Feb 2003 20:05:17 -0000
***************
*** 28,33 ****
--- 28,34 ----
#include "integrate.h"
#include "expr.h"
#include "c-tree.h"
+ #include "c-pragma.h"
#include "function.h"
#include "flags.h"
#include "toplev.h"
***************
*** 237,242 ****
--- 238,279 ----
return false;
return true;
+ }
+
+ /* APPLE local hack - remove for FSF */
+ void print_INCLUDE_FRAGMENT () { abort(); }
+
+ struct c_include_fragment *
+ alloc_include_fragment ()
+ {
+ int length = sizeof (struct c_include_fragment);
+ tree t = ggc_alloc_tree (length);
+ memset ((PTR) t, 0, length);
+ TREE_SET_CODE (t, INCLUDE_FRAGMENT);
+ return (struct c_include_fragment *) t;
+ }
+
+ /* Initialization common to C and Objective-C front ends. */
+ void
+ c_objc_common_initially ()
+ {
+ cpp_init_tables (parse_in, ident_hash);
+
+ /*
+ if (! CPP_OPTION (pfile, preprocessed))
+ {
+ struct pending_option *p;
+
+ _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0);
+ }
+ */
+ init_pragma ();
+
+ c_initially_decl_processing ();
+
+ c_common_initially ();
+
+ cpp_finish_options (parse_in);
}
/* Initialization common to C and Objective-C front ends. */
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.28
diff -c -r1.28 c-opts.c
*** c-opts.c 28 Jan 2003 19:29:57 -0000 1.28
--- c-opts.c 8 Feb 2003 20:05:18 -0000
***************
*** 1430,1439 ****
cpp_preprocess_file (parse_in, in_fname, out_stream);
}
! /* Front end initialization common to C, ObjC and C++. */
! const char *
! c_common_init (filename)
! const char *filename;
{
/* Set up preprocessor arithmetic. Must be done after call to
c_common_nodes_and_builtins for type nodes to be good. */
--- 1430,1437 ----
cpp_preprocess_file (parse_in, in_fname, out_stream);
}
! void
! c_common_initially ()
{
/* Set up preprocessor arithmetic. Must be done after call to
c_common_nodes_and_builtins for type nodes to be good. */
***************
*** 1446,1452 ****
--- 1444,1461 ----
/* Register preprocessor built-ins before calls to
cpp_main_file. */
cpp_get_callbacks (parse_in)->register_builtins = cb_register_builtins;
+ if (is_server)
+ {
+ cpp_get_callbacks (parse_in)->push_fragment = cb_push_fragment;
+ cpp_get_callbacks (parse_in)->pop_fragment = cb_pop_fragment;
+ }
+ }
+ /* Front end initialization common to C, ObjC and C++. */
+ const char *
+ c_common_init (filename)
+ const char *filename;
+ {
/* NULL is passed up to toplev.c and we exit quickly. */
if (flag_preprocess_only)
{
***************
*** 1457,1465 ****
/* Do this before initializing pragmas, as then cpplib's hash table
has been set up. NOTE: we are using our own file name here, not
the one supplied. */
filename = init_c_lex (in_fname);
-
- init_pragma ();
return filename;
}
--- 1466,1473 ----
/* Do this before initializing pragmas, as then cpplib's hash table
has been set up. NOTE: we are using our own file name here, not
the one supplied. */
+ in_fname = filename;
filename = init_c_lex (in_fname);
return filename;
}
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.160
diff -c -r1.160 cppfiles.c
*** cppfiles.c 10 Jan 2003 02:21:58 -0000 1.160
--- cppfiles.c 8 Feb 2003 20:05:22 -0000
***************
*** 94,99 ****
--- 94,100 ----
/* location in search path where file was
found, for #include_next and sysp. */
const unsigned char *buffer; /* pointer to cached file contents */
+ cpp_fragment *fragments; /* head of fragment chain */
struct stat st; /* copy of stat(2) data for file */
int fd; /* fd open on file (short term storage only) */
int err_no; /* errno obtained if opening a file failed */
***************
*** 121,127 ****
/* The cmacro works like this: If it's NULL, the file is to be
included again. If it's NEVER_REREAD, the file is never to be
included again. Otherwise it is a macro hashnode, and the file is
! to be included again if the macro is defined. */
#define NEVER_REREAD ((const cpp_hashnode *) -1)
#define DO_NOT_REREAD(inc) \
((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
--- 122,128 ----
/* The cmacro works like this: If it's NULL, the file is to be
included again. If it's NEVER_REREAD, the file is never to be
included again. Otherwise it is a macro hashnode, and the file is
! to be included again if the macro is undefined. */
#define NEVER_REREAD ((const cpp_hashnode *) -1)
#define DO_NOT_REREAD(inc) \
((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
***************
*** 148,153 ****
--- 149,155 ----
static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
static bool stack_include_file PARAMS ((cpp_reader *, struct include_file *));
static void purge_cache PARAMS ((struct include_file *));
+ static void purge_fragments PARAMS ((struct include_file *));
static void destroy_node PARAMS ((splay_tree_value));
static int report_missing_guard PARAMS ((splay_tree_node, void *));
static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
***************
*** 467,472 ****
--- 469,479 ----
/* from_stage3 */ CPP_OPTION (pfile, preprocessed), 0);
fp->inc = inc;
fp->inc->refcnt++;
+ pfile->current_fragment = inc->fragments;
+ #if 0
+ if (inc->fragments)
+ _cpp_push_fragment (pfile, inc->fragments);
+ #endif
/* Initialize controlling macro state. */
pfile->mi_valid = true;
***************
*** 481,486 ****
--- 488,531 ----
return true;
}
+ void
+ _cpp_push_fragment (pfile, fragment)
+ cpp_reader *pfile;
+ cpp_fragment *fragment;
+ {
+ if (pfile->cb.push_fragment != NULL)
+ {
+ void *start
+ = pfile->cb.push_fragment (pfile, fragment,
+ fragment->name,
+ SOURCE_LINE (lookup_line (&pfile->line_maps, pfile->line), pfile->line));
+ if (start == NULL)
+ {
+ pfile->buffer->cur = fragment->end;
+ pfile->buffer->line_base = fragment->end_line_base;
+ pfile->line += fragment->end_line - fragment->start_line;
+ return;
+ }
+ fragment->start_marker = start;
+ fragment->start_line = pfile->line;
+ }
+ }
+
+ void
+ _cpp_pop_fragment (pfile, fragment)
+ cpp_reader *pfile;
+ cpp_fragment *fragment;
+ {
+ if (pfile->cb.pop_fragment != NULL
+ && ! pfile->state.skipping
+ && ! fragment->was_reused)
+ {
+ pfile->cb.pop_fragment (pfile, fragment);
+ fragment->end_line = pfile->line;
+ fragment->end_line_base = pfile->buffer->line_base;
+ }
+ }
+
/* Read the file referenced by INC into the file cache.
If fd points to a plain file, we might be able to mmap it; we can
***************
*** 500,505 ****
--- 545,551 ----
cpp_reader *pfile;
struct include_file *inc;
{
+ cpp_fragment *fragment;
ssize_t size, offset, count;
uchar *buf;
#if MMAP_THRESHOLD
***************
*** 601,606 ****
--- 647,668 ----
}
inc->buffer = buf;
+
+ if (pfile->cb.pop_fragment != NULL)
+ {
+ size = strlen (inc->name);
+ if (size > 2 && inc->name[size-1] != 'c') /* FIXME */
+ {
+ purge_fragments (inc);
+ fragment = xcnew (cpp_fragment);
+ fragment->name = inc->name;
+ fragment->next = NULL;
+ fragment->start = buf;
+ fragment->end = 0;
+ inc->fragments = fragment;
+ }
+ }
+
return 0;
perror_fail:
***************
*** 631,636 ****
--- 693,713 ----
free ((PTR) inc->buffer);
inc->buffer = NULL;
}
+ purge_fragments (inc);
+ }
+
+ static void
+ purge_fragments (inc)
+ struct include_file *inc;
+ {
+ cpp_fragment *fragment = inc->fragments;;
+ while (fragment != NULL)
+ {
+ cpp_fragment *next = fragment->next;
+ free ((PTR) fragment);
+ fragment = next;
+ }
+ inc->fragments = NULL;
}
/* Return 1 if the file named by FNAME has been included before in
***************
*** 895,902 ****
--- 972,981 ----
pfile->mi_valid = false;
inc->refcnt--;
+ #if 0
if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
purge_cache (inc);
+ #endif
}
/* Returns the first place in the include chain to start searching for
Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppinit.c,v
retrieving revision 1.266
diff -c -r1.266 cppinit.c
*** cppinit.c 28 Jan 2003 19:29:57 -0000 1.266
--- cppinit.c 8 Feb 2003 20:05:23 -0000
***************
*** 911,924 ****
deps_add_target (pfile->deps, target, quote);
}
! /* This is called after options have been parsed, and partially
! processed. Setup for processing input from the file named FNAME,
! or stdin if it is the empty string. Return the original filename
! on success (e.g. foo.i->foo.c), or NULL on failure. */
! const char *
! cpp_read_main_file (pfile, fname, table)
cpp_reader *pfile;
- const char *fname;
hash_table *table;
{
static const char *const lang_env_vars[] =
--- 911,919 ----
deps_add_target (pfile->deps, target, quote);
}
! void
! cpp_init_tables (pfile, table)
cpp_reader *pfile;
hash_table *table;
{
static const char *const lang_env_vars[] =
***************
*** 963,969 ****
--- 958,975 ----
}
fprintf (stderr, _("End of search list.\n"));
}
+ }
+ /* This is called after options have been parsed, and partially
+ processed. Setup for processing input from the file named FNAME,
+ or stdin if it is the empty string. Return the original filename
+ on success (e.g. foo.i->foo.c), or NULL on failure. */
+ const char *
+ cpp_read_main_file (pfile, fname)
+ cpp_reader *pfile;
+ const char *fname;
+ {
+ pfile->main_input_filename = fname;
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE)
{
if (!pfile->deps)
***************
*** 1078,1084 ****
{
/* All done; restore the line map from <command line>. */
_cpp_do_file_change (pfile, LC_RENAME,
! pfile->line_maps.maps[0].to_file, 1, 0);
/* Don't come back here again. */
pfile->next_include_file = NULL;
}
--- 1084,1091 ----
{
/* All done; restore the line map from <command line>. */
_cpp_do_file_change (pfile, LC_RENAME,
! pfile->main_input_filename, 1, 0);
! /* pfile->line_maps.maps[0].to_file, 1, 0);*/
/* Don't come back here again. */
pfile->next_include_file = NULL;
}
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.329
diff -c -r1.329 cpplib.c
*** cpplib.c 28 Jan 2003 19:30:00 -0000 1.329
--- cpplib.c 8 Feb 2003 20:05:25 -0000
***************
*** 238,249 ****
--- 238,261 ----
start_directive (pfile)
cpp_reader *pfile;
{
+ cpp_fragment *fragment;
+ const unsigned char *cur;
+
/* Setup in-directive state. */
pfile->state.in_directive = 1;
pfile->state.save_comments = 0;
/* Some handlers need the position of the # for diagnostics. */
pfile->directive_line = pfile->line;
+
+ cur = pfile->buffer->cur - 1;
+ if ((fragment = pfile->current_fragment) != NULL
+ && (fragment->end == NULL
+ || fragment->end == cur))
+ {
+ fragment->end = cur;
+ _cpp_pop_fragment (pfile, fragment);
+ }
}
/* Called when leaving a directive, _Pragma or command-line directive. */
***************
*** 277,282 ****
--- 289,335 ----
pfile->state.in_expression = 0;
pfile->state.angled_headers = 0;
pfile->directive = 0;
+ _cpp_start_fragment (pfile);
+ }
+
+ void
+ _cpp_start_fragment (pfile)
+ cpp_reader *pfile;
+ {
+ cpp_fragment *fragment;
+ if ((fragment = pfile->current_fragment) != NULL
+ && ! pfile->state.skipping)
+ {
+ const unsigned char *cur = pfile->buffer->cur;
+ for (;;)
+ {
+ cpp_fragment *next_fragment = fragment->next;
+ if (next_fragment == NULL || next_fragment->start > cur)
+ break;
+ fragment = next_fragment;
+ }
+ if (fragment->start < cur)
+ {
+ cpp_fragment *next_fragment;
+ if (1 /*fragment->start != fragment->end*/
+ /* && contains more than whitespace ... FIXME */)
+ {
+ #if 0
+ if (fragment->start != fragment->end)
+ fragment->start_marker = NULL; /* FIXME */
+ #endif
+ next_fragment = xcnew (cpp_fragment);
+ next_fragment->name = fragment->name;
+ next_fragment->next = fragment->next;
+ fragment->next = next_fragment;
+ fragment = next_fragment;
+ }
+ fragment->start = cur;
+ fragment->end = 0;
+ }
+ pfile->current_fragment = fragment;
+ _cpp_push_fragment (pfile, fragment);
+ }
}
/* Prepare to handle the directive in pfile->directive. */
***************
*** 520,525 ****
--- 573,634 ----
return NULL;
}
+ void
+ _cpp_restore_macros (pfile, notes, count)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ struct cpp_macro_note *notes;
+ int count;
+ {
+ for (; --count >= 0; notes++)
+ {
+ cpp_hashnode *node = notes->node;
+ struct cpp_macro *macro = notes->macro;
+ if (macro != NULL)
+ {
+ /* #define */
+ node->type = NT_MACRO;
+ node->value.macro = macro;
+ }
+ else
+ {
+ /* #undef */
+ _cpp_free_definition (node);
+ }
+ }
+ }
+
+ void
+ _cpp_note_macro (pfile, node, macro)
+ cpp_reader *pfile;
+ cpp_hashnode *node;
+ struct cpp_macro *macro;
+ {
+ int count, alloc;
+ if (! pfile->do_note_macros)
+ return;
+
+ count = pfile->macro_notes_count;
+ if (pfile->macro_notes == NULL)
+ {
+ alloc = 64;
+ pfile->macro_notes = xmalloc (alloc * sizeof (struct cpp_macro_note));
+ pfile->macro_notes_alloc_length = alloc;
+ }
+ else if (count >= (alloc = pfile->macro_notes_alloc_length))
+ {
+ struct cpp_macro_note *new_notes
+ = xmalloc (2 * alloc * sizeof (struct cpp_macro_note));
+ memcpy (new_notes, pfile->macro_notes,
+ count * sizeof (struct cpp_macro_note));
+ free (pfile->macro_notes);
+ pfile->macro_notes = new_notes;
+ pfile->macro_notes_alloc_length = 2 * alloc;
+ }
+ pfile->macro_notes[count].node = node;
+ pfile->macro_notes[count].macro = macro;
+ pfile->macro_notes_count = count + 1;
+ }
+
/* Process a #define directive. Most work is done in cppmacro.c. */
static void
do_define (pfile)
***************
*** 534,542 ****
pfile->state.save_comments =
! CPP_OPTION (pfile, discard_comments_in_macro_exp);
if (_cpp_create_definition (pfile, node))
! if (pfile->cb.define)
! (*pfile->cb.define) (pfile, pfile->directive_line, node);
}
}
--- 643,655 ----
pfile->state.save_comments =
! CPP_OPTION (pfile, discard_comments_in_macro_exp);
+
if (_cpp_create_definition (pfile, node))
! {
! _cpp_note_macro (pfile, node, node->value.macro);
! if (pfile->cb.define)
! (*pfile->cb.define) (pfile, pfile->directive_line, node);
! }
}
}
***************
*** 554,559 ****
--- 667,674 ----
if (pfile->cb.undef)
(*pfile->cb.undef) (pfile, pfile->directive_line, node);
+ _cpp_note_macro (pfile, node, NULL);
+
if (node->flags & NODE_WARN)
cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
***************
*** 2030,2036 ****
--- 2145,2153 ----
new->return_at_eof = return_at_eof;
new->saved_flags = BOL;
+ new->saved_current_fragment = pfile->current_fragment;
pfile->buffer = new;
+ pfile->current_fragment = NULL;
return new;
}
***************
*** 2054,2060 ****
--- 2171,2184 ----
/* In case of a missing #endif. */
pfile->state.skipping = 0;
+ if (pfile->current_fragment != 0)
+ {
+ cpp_fragment *fragment = pfile->current_fragment;
+ fragment->end = buffer->cur;
+ _cpp_pop_fragment (pfile, fragment);
+ }
/* _cpp_do_file_change expects pfile->buffer to be the new one. */
+ pfile->current_fragment = buffer->saved_current_fragment;
pfile->buffer = buffer->prev;
/* Free the buffer object now; we may want to push a new buffer
***************
*** 2074,2079 ****
--- 2198,2204 ----
files left to push. */
if (!pfile->buffer->prev)
_cpp_maybe_push_include_file (pfile);
+ _cpp_start_fragment (pfile);
}
}
}
Index: cppmain.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmain.c,v
retrieving revision 1.106
diff -c -r1.106 cppmain.c
*** cppmain.c 16 Dec 2002 18:19:18 -0000 1.106
--- cppmain.c 8 Feb 2003 20:05:25 -0000
***************
*** 72,81 ****
setup_callbacks (pfile);
! if (cpp_read_main_file (pfile, in_fname, NULL))
{
cpp_options *options = &pfile->opts;
! cpp_finish_options (pfile);
/* A successful cpp_read_main_file guarantees that we can call
cpp_scan_nooutput or cpp_get_token next. */
--- 72,81 ----
setup_callbacks (pfile);
! if (cpp_read_main_file (pfile, in_fname))
{
cpp_options *options = &pfile->opts;
! /*cpp_finish_options (pfile);*/
/* A successful cpp_read_main_file guarantees that we can call
cpp_scan_nooutput or cpp_get_token next. */
Index: fix-header.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fix-header.c,v
retrieving revision 1.85
diff -c -r1.85 fix-header.c
*** fix-header.c 16 Dec 2002 18:19:26 -0000 1.85
--- fix-header.c 8 Feb 2003 20:05:26 -0000
***************
*** 637,643 ****
if (cpp_errors (scan_in))
exit (FATAL_EXIT_CODE);
! if (! cpp_read_main_file (scan_in, in_fname, NULL))
exit (FATAL_EXIT_CODE);
cpp_finish_options (scan_in);
--- 637,644 ----
if (cpp_errors (scan_in))
exit (FATAL_EXIT_CODE);
! cpp_init_tables (scan_in, NULL);
! if (! cpp_read_main_file (scan_in, in_fname))
exit (FATAL_EXIT_CODE);
cpp_finish_options (scan_in);
Index: ggc-page.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-page.c,v
retrieving revision 1.61
diff -c -r1.61 ggc-page.c
*** ggc-page.c 30 Jan 2003 18:14:06 -0000 1.61
--- ggc-page.c 8 Feb 2003 20:05:29 -0000
***************
*** 1523,1528 ****
--- 1523,1529 ----
void
ggc_collect ()
{
+ #if 0
/* Avoid frequent unnecessary work by skipping collection if the
total allocations haven't expanded much since the last
collection. */
***************
*** 1564,1569 ****
--- 1565,1571 ----
if (!quiet_flag)
fprintf (stderr, "%luk}", (unsigned long) G.allocated / 1024);
+ #endif
}
/* Print allocation statistics. */
Index: regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.168
diff -c -r1.168 regclass.c
*** regclass.c 31 Jan 2003 23:34:13 -0000 1.168
--- regclass.c 8 Feb 2003 20:05:31 -0000
***************
*** 49,55 ****
#endif
static void init_reg_sets_1 PARAMS ((void));
- static void init_reg_modes PARAMS ((void));
static void init_reg_autoinc PARAMS ((void));
/* If we have auto-increment or auto-decrement and we can have secondary
--- 49,54 ----
***************
*** 549,555 ****
These values are used to record death information for individual registers
(as opposed to a multi-register mode). */
! static void
init_reg_modes ()
{
int i;
--- 548,554 ----
These values are used to record death information for individual registers
(as opposed to a multi-register mode). */
! void
init_reg_modes ()
{
int i;
***************
*** 577,584 ****
/* This finishes what was started by init_reg_sets, but couldn't be done
until after register usage was specified. */
init_reg_sets_1 ();
-
- init_reg_modes ();
init_reg_autoinc ();
}
--- 576,581 ----
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.703
diff -c -r1.703 toplev.c
*** toplev.c 26 Jan 2003 14:40:15 -0000 1.703
--- toplev.c 8 Feb 2003 20:05:34 -0000
***************
*** 142,147 ****
--- 142,150 ----
/* Copy of arguments to toplev_main. */
int save_argc;
char **save_argv;
+
+ int is_server;
+ static bool no_backend;
/* Name of current original source file (what was input to cpp).
This comes from each #-command in the actual input. */
***************
*** 982,987 ****
--- 985,991 ----
static const lang_independent_options f_options[] =
{
+ {"server", &is_server, 1, N_("run compiler in server mode") },
{"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
N_("Perform DWARF2 duplicate elimination") },
{"float-store", &flag_float_store, 1,
***************
*** 5214,5230 ****
static void
backend_init ()
{
- /* init_emit_once uses reg_raw_mode and therefore must be called
- after init_regs which initialized reg_raw_mode. */
init_regs ();
- init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
- || debug_info_level == DINFO_LEVEL_VERBOSE
- #ifdef VMS_DEBUGGING_INFO
- /* Enable line number info for traceback */
- || debug_info_level > DINFO_LEVEL_NONE
- #endif
- || flag_test_coverage
- || warn_notreached);
init_fake_stack_mems ();
init_alias_once ();
init_loop ();
--- 5218,5224 ----
***************
*** 5352,5359 ****
}
/* Initialize the compiler, and compile the input file. */
! static void
! do_compile ()
{
/* All command line options have been parsed; allow the front end to
perform consistency checks, etc. */
--- 5346,5353 ----
}
/* Initialize the compiler, and compile the input file. */
! static bool
! init_compile ()
{
/* All command line options have been parsed; allow the front end to
perform consistency checks, etc. */
***************
*** 5362,5370 ****
/* The bulk of command line switch processing. */
process_options ();
! /* If an error has already occurred, give up. */
! if (errorcount)
! return;
if (aux_base_name)
/*NOP*/;
--- 5356,5380 ----
/* The bulk of command line switch processing. */
process_options ();
! /* init_emit_once uses reg_raw_mode and therefore must be called
! after init_reg_modes which initialized reg_raw_mode. */
! init_reg_modes ();
! init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
! || debug_info_level == DINFO_LEVEL_VERBOSE
! #ifdef VMS_DEBUGGING_INFO
! /* Enable line number info for traceback */
! || debug_info_level > DINFO_LEVEL_NONE
! #endif
! || flag_test_coverage
! || warn_notreached);
!
! (*lang_hooks.initially) ();
! return no_backend;
! }
!
! static void
! do_compile ()
! {
if (aux_base_name)
/*NOP*/;
***************
*** 5398,5403 ****
--- 5408,5446 ----
timevar_print (stderr);
}
+ extern int
+ server_get_filename (void);
+ int
+ server_get_filename ()
+ {
+ char buffer[1024];
+ int len;
+
+ if (fgets (buffer, 1024, stdin) == NULL)
+ return 0;
+ len = strlen (buffer);
+ if (len == 0)
+ return 0;
+ if (buffer[len-1] == '\n')
+ buffer[--len] = '\0';
+ filename = xmalloc (len+1);
+ strcpy (filename, buffer);
+
+ if (fgets (buffer, 1024, stdin) == NULL)
+ return 0;
+ len = strlen (buffer);
+ if (len == 0)
+ return 0;
+ if (buffer[len-1] == '\n')
+ buffer[--len] = '\0';
+ asm_file_name = xmalloc (len+1);
+ strcpy (asm_file_name, buffer);
+
+ if (! quiet_flag)
+ fprintf (stderr, "serve '%s' -o '%s'\n", filename, asm_file_name);
+ return 1;
+ }
+
/* 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
***************
*** 5419,5425 ****
/* Exit early if we can (e.g. -help). */
if (!exit_after_options)
! do_compile ();
if (errorcount || sorrycount)
return (FATAL_EXIT_CODE);
--- 5462,5482 ----
/* Exit early if we can (e.g. -help). */
if (!exit_after_options)
! {
! no_backend = init_compile ();
!
! /* If an error has already occurred, give up. */
! if (! errorcount)
! {
! if (is_server)
! {
! while (server_get_filename ())
! do_compile ();
! }
! else
! do_compile ();
! }
! }
if (errorcount || sorrycount)
return (FATAL_EXIT_CODE);
Index: c-common.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.def,v
retrieving revision 1.13
diff -c -r1.13 c-common.def
*** c-common.def 29 Sep 2002 13:16:42 -0000 1.13
--- c-common.def 8 Feb 2003 20:05:35 -0000
***************
*** 28,33 ****
--- 28,35 ----
/* A node to remember a source position. */
DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
+ DEFTREECODE (INCLUDE_FRAGMENT, "include_fragment", 'x', 2)
+
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)