aboutsummaryrefslogtreecommitdiff
path: root/gcc/cppinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cppinit.c')
-rw-r--r--gcc/cppinit.c224
1 files changed, 191 insertions, 33 deletions
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 74ddd5b..c66f045 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -36,6 +36,17 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
#endif
+/* Windows does not natively support inodes, and neither does MSDOS.
+ Cygwin's emulation can generate non-unique inodes, so don't use it.
+ VMS has non-numeric inodes. */
+#ifdef VMS
+#define INO_T_EQ(a, b) (!memcmp (&(a), &(b), sizeof (a)))
+#elif (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
+#define INO_T_EQ(a, b) 0
+#else
+#define INO_T_EQ(a, b) ((a) == (b))
+#endif
+
#ifndef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR "/usr/include"
#endif
@@ -97,47 +108,51 @@ struct default_include
C++. */
};
+#ifndef STANDARD_INCLUDE_COMPONENT
+#define STANDARD_INCLUDE_COMPONENT 0
+#endif
+
+#ifdef CROSS_COMPILE
+#undef LOCAL_INCLUDE_DIR
+#undef SYSTEM_INCLUDE_DIR
+#undef STANDARD_INCLUDE_DIR
+#else
+#undef CROSS_INCLUDE_DIR
+#endif
+
static const struct default_include include_defaults_array[]
#ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS;
#else
= {
+#ifdef GPLUSPLUS_INCLUDE_DIR
/* Pick up GNU C++ specific include files. */
{ GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
-#ifdef CROSS_COMPILE
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
- /* For cross-compilation, this dir name is generated
- automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
-#ifdef TOOL_INCLUDE_DIR
- /* This is another place that the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
#endif
-#else /* not CROSS_COMPILE */
#ifdef LOCAL_INCLUDE_DIR
- /* This should be /usr/local/include and should come before
- the fixincludes-fixed header files. */
+ /* /usr/local/include comes before the fixincluded header files. */
{ LOCAL_INCLUDE_DIR, 0, 0, 1 },
#endif
+#ifdef GCC_INCLUDE_DIR
+ /* This is the dir for fixincludes and for gcc's private headers. */
+ { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+#endif
+#ifdef CROSS_INCLUDE_DIR
+ /* One place the target system's headers might be. */
+ { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
+#endif
#ifdef TOOL_INCLUDE_DIR
- /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
- Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
+ /* Another place the target system's headers might be. */
{ TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
#endif
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
- /* Some systems have an extra dir of include files. */
#ifdef SYSTEM_INCLUDE_DIR
+ /* Some systems have an extra dir of include files. */
{ SYSTEM_INCLUDE_DIR, 0, 0, 0 },
#endif
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
+#ifdef STANDARD_INCLUDE_DIR
+ /* /usr/include comes dead last. */
{ STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
-#endif /* not CROSS_COMPILE */
+#endif
{ 0, 0, 0, 0 }
};
#endif /* no INCLUDE_DEFAULTS */
@@ -156,6 +171,24 @@ struct pending_option
int undef;
};
+/* The `pending' structure accumulates all the options that are not
+ actually processed until we hit cpp_start_read. It consists of
+ several lists, one for each type of option. We keep both head and
+ tail pointers for quick insertion. */
+struct cpp_pending
+{
+ struct pending_option *define_head, *define_tail;
+ struct pending_option *assert_head, *assert_tail;
+
+ struct file_name_list *quote_head, *quote_tail;
+ struct file_name_list *brack_head, *brack_tail;
+ struct file_name_list *systm_head, *systm_tail;
+ struct file_name_list *after_head, *after_tail;
+
+ struct pending_option *imacros_head, *imacros_tail;
+ struct pending_option *include_head, *include_tail;
+};
+
#ifdef __STDC__
#define APPEND(pend, list, elt) \
do { if (!(pend)->list##_head) (pend)->list##_head = (elt); \
@@ -178,6 +211,8 @@ static void initialize_builtins PARAMS ((cpp_reader *));
static void append_include_chain PARAMS ((cpp_reader *,
struct cpp_pending *,
char *, int, int));
+static void merge_include_chains PARAMS ((struct cpp_options *));
+
static void dump_special_to_buffer PARAMS ((cpp_reader *, const char *));
static void initialize_dependency_output PARAMS ((cpp_reader *));
static void initialize_standard_includes PARAMS ((cpp_reader *));
@@ -341,6 +376,135 @@ append_include_chain (pfile, pend, dir, path, cxx_aware)
}
}
+/* Merge the four include chains together in the order quote, bracket,
+ system, after. Remove duplicate dirs (as determined by
+ INO_T_EQ()). The system_include and after_include chains are never
+ referred to again after this function; all access is through the
+ bracket_include path.
+
+ For the future: Check if the directory is empty (but
+ how?) and possibly preload the include hash. */
+
+static void
+merge_include_chains (opts)
+ struct cpp_options *opts;
+{
+ struct file_name_list *prev, *cur, *other;
+ struct file_name_list *quote, *brack, *systm, *after;
+ struct file_name_list *qtail, *btail, *stail, *atail;
+
+ qtail = opts->pending->quote_tail;
+ btail = opts->pending->brack_tail;
+ stail = opts->pending->systm_tail;
+ atail = opts->pending->after_tail;
+
+ quote = opts->pending->quote_head;
+ brack = opts->pending->brack_head;
+ systm = opts->pending->systm_head;
+ after = opts->pending->after_head;
+
+ /* Paste together bracket, system, and after include chains. */
+ if (stail)
+ stail->next = after;
+ else
+ systm = after;
+ if (btail)
+ btail->next = systm;
+ 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 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
+ safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
+ -Ibar -I- -Ifoo -Iquux.
+
+ Note that this algorithm is quadratic in the number of -I switches,
+ which is acceptable since there aren't usually that many of them. */
+
+ for (cur = quote, prev = NULL; cur; cur = cur->next)
+ {
+ for (other = quote; other != cur; other = other->next)
+ if (INO_T_EQ (cur->ino, other->ino)
+ && cur->dev == other->dev)
+ {
+ if (opts->verbose)
+ fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+ cur->name);
+
+ prev->next = cur->next;
+ free (cur->name);
+ free (cur);
+ cur = prev;
+ break;
+ }
+ prev = cur;
+ }
+ qtail = prev;
+
+ for (cur = brack; cur; cur = cur->next)
+ {
+ for (other = brack; other != cur; other = other->next)
+ if (INO_T_EQ (cur->ino, other->ino)
+ && cur->dev == other->dev)
+ {
+ if (opts->verbose)
+ fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+ cur->name);
+
+ prev->next = cur->next;
+ free (cur->name);
+ free (cur);
+ cur = prev;
+ break;
+ }
+ prev = cur;
+ }
+
+ if (quote)
+ {
+ if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
+ {
+ if (quote == qtail)
+ {
+ if (opts->verbose)
+ fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+ quote->name);
+
+ free (quote->name);
+ free (quote);
+ quote = brack;
+ }
+ else
+ {
+ cur = quote;
+ while (cur->next != qtail)
+ cur = cur->next;
+ cur->next = brack;
+ if (opts->verbose)
+ fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
+ qtail->name);
+
+ free (qtail->name);
+ free (qtail);
+ }
+ }
+ else
+ qtail->next = brack;
+ }
+ else
+ quote = brack;
+
+ opts->quote_include = quote;
+ opts->bracket_include = brack;
+}
+
/* Write out a #define command for the special named MACRO_NAME
to PFILE's token_buffer. */
@@ -418,13 +582,6 @@ cpp_cleanup (pfile)
if (pfile->deps)
deps_free (pfile->deps);
- while (pfile->if_stack)
- {
- IF_STACK *temp = pfile->if_stack;
- pfile->if_stack = temp->next;
- free (temp);
- }
-
for (i = ALL_INCLUDE_HASHSIZE; --i >= 0; )
{
IHASH *imp, *next;
@@ -723,7 +880,7 @@ cpp_start_read (pfile, fname)
if (! opts->no_standard_includes)
initialize_standard_includes (pfile);
- _cpp_merge_include_chains (opts);
+ merge_include_chains (opts);
/* With -v, print the list of dirs to search. */
if (opts->verbose)
@@ -844,9 +1001,10 @@ cpp_finish (pfile)
{
struct cpp_options *opts = CPP_OPTIONS (pfile);
- if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) != NULL)
+ if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)))
cpp_ice (pfile, "buffers still stacked in cpp_finish");
- cpp_pop_buffer (pfile);
+ while (CPP_BUFFER (pfile))
+ cpp_pop_buffer (pfile);
/* Don't write the deps file if preprocessing has failed. */
if (opts->print_deps && pfile->errors == 0)