X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-incpath.c;h=f8b524d6e1176a5a0e7ded5d83050bc377375f23;hb=7e3b64b4fe86e3bdceb004b797f6da883402a2ef;hp=efcd19b5ea5b9a8402a6a9968b22908e67050087;hpb=917bbcab602907861c40cfad1cc5337aaf9d0f1d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-incpath.c b/gcc/c-incpath.c index efcd19b5ea5..f8b524d6e11 100644 --- a/gcc/c-incpath.c +++ b/gcc/c-incpath.c @@ -1,26 +1,29 @@ /* Set up combined include path chain for the preprocessor. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003. -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + . */ #include "config.h" #include "system.h" #include "coretypes.h" +#include "machmode.h" +#include "target.h" #include "tm.h" #include "cpplib.h" #include "prefix.h" @@ -35,7 +38,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A))) # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC)) #else -# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__ +# if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__ # define INO_T_EQ(A, B) 0 # else # define INO_T_EQ(A, B) ((A) == (B)) @@ -43,23 +46,26 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ # define INO_T_COPY(DEST, SRC) (DEST) = (SRC) #endif +static const char dir_separator_str[] = { DIR_SEPARATOR, 0 }; + static void add_env_var_paths (const char *, int); -static void add_standard_paths (const char *, const char *, int); -static void free_path (struct cpp_path *, int); -static void merge_include_chains (cpp_reader *, int); -static struct cpp_path *remove_duplicates (cpp_reader *, struct cpp_path *, - struct cpp_path *, - struct cpp_path *, int); +static void add_standard_paths (const char *, const char *, const char *, int); +static void free_path (struct cpp_dir *, int); +static void merge_include_chains (const char *, cpp_reader *, int); +static void add_sysroot_to_chain (const char *, int); +static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *, + struct cpp_dir *, + struct cpp_dir *, int); /* Include chains heads and tails. */ -static struct cpp_path *heads[4]; -static struct cpp_path *tails[4]; +static struct cpp_dir *heads[4]; +static struct cpp_dir *tails[4]; static bool quote_ignores_source_dir; enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS }; /* Free an element of the include chain, possibly giving a reason. */ static void -free_path (struct cpp_path *path, int reason) +free_path (struct cpp_dir *path, int reason) { switch (reason) { @@ -107,26 +113,28 @@ add_env_var_paths (const char *env_var, int chain) path = xstrdup ("."); else { - path = xmalloc (q - p + 1); + path = XNEWVEC (char, q - p + 1); memcpy (path, p, q - p); path[q - p] = '\0'; } - add_path (path, chain, chain == SYSTEM); + add_path (path, chain, chain == SYSTEM, false); } } /* Append the standard include chain defined in cppdefault.c. */ static void -add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) +add_standard_paths (const char *sysroot, const char *iprefix, + const char *imultilib, int cxx_stdinc) { const struct default_include *p; + int relocated = cpp_relocated(); size_t len; if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0) { /* Look for directories that start with the standard prefix. - "Translate" them, ie. replace /usr/local/lib/gcc... with + "Translate" them, i.e. replace /usr/local/lib/gcc... with IPREFIX and search them first. */ for (p = cpp_include_defaults; p->fname; p++) { @@ -140,7 +148,9 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len)) { char *str = concat (iprefix, p->fname + len, NULL); - add_path (str, SYSTEM, p->cxx_aware); + if (p->multilib && imultilib) + str = concat (str, dir_separator_str, imultilib, NULL); + add_path (str, SYSTEM, p->cxx_aware, false); } } } @@ -155,10 +165,38 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) /* Should this directory start with the sysroot? */ if (sysroot && p->add_sysroot) str = concat (sysroot, p->fname, NULL); + else if (!p->add_sysroot && relocated + && strncmp (p->fname, cpp_PREFIX, cpp_PREFIX_len) == 0) + { + static const char *relocated_prefix; + /* If this path starts with the configure-time prefix, + but the compiler has been relocated, replace it + with the run-time prefix. The run-time exec prefix + is GCC_EXEC_PREFIX. Compute the path from there back + to the toplevel prefix. */ + if (!relocated_prefix) + { + char *dummy; + /* Make relative prefix expects the first argument + to be a program, not a directory. */ + dummy = concat (gcc_exec_prefix, "dummy", NULL); + relocated_prefix + = make_relative_prefix (dummy, + cpp_EXEC_PREFIX, + cpp_PREFIX); + } + str = concat (relocated_prefix, + p->fname + cpp_PREFIX_len, + NULL); + str = update_path (str, p->component); + } else str = update_path (p->fname, p->component); - add_path (str, SYSTEM, p->cxx_aware); + if (p->multilib && imultilib) + str = concat (str, dir_separator_str, imultilib, NULL); + + add_path (str, SYSTEM, p->cxx_aware, false); } } } @@ -169,12 +207,13 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) JOIN, unless it duplicates JOIN in which case the last path is removed. Return the head of the resulting chain. Any of HEAD, JOIN and SYSTEM can be NULL. */ -static struct cpp_path * -remove_duplicates (cpp_reader *pfile, struct cpp_path *head, - struct cpp_path *system, struct cpp_path *join, + +static struct cpp_dir * +remove_duplicates (cpp_reader *pfile, struct cpp_dir *head, + struct cpp_dir *system, struct cpp_dir *join, int verbose) { - struct cpp_path **pcur, *tmp, *cur; + struct cpp_dir **pcur, *tmp, *cur; struct stat st; for (pcur = &head; *pcur; ) @@ -182,18 +221,23 @@ remove_duplicates (cpp_reader *pfile, struct cpp_path *head, int reason = REASON_QUIET; cur = *pcur; - cpp_simplify_path (cur->name); if (stat (cur->name, &st)) { /* Dirs that don't exist are silently ignored, unless verbose. */ if (errno != ENOENT) - cpp_errno (pfile, DL_ERROR, cur->name); + cpp_errno (pfile, CPP_DL_ERROR, cur->name); else - reason = REASON_NOENT; + { + /* If -Wmissing-include-dirs is given, warn. */ + cpp_options *opts = cpp_get_options (pfile); + if (opts->warn_missing_include_dirs && cur->user_supplied_p) + cpp_errno (pfile, CPP_DL_WARNING, cur->name); + reason = REASON_NOENT; + } } else if (!S_ISDIR (st.st_mode)) - cpp_error_with_line (pfile, DL_ERROR, 0, 0, + cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0, "%s: not a directory", cur->name); else { @@ -203,7 +247,8 @@ remove_duplicates (cpp_reader *pfile, struct cpp_path *head, /* Remove this one if it is in the system chain. */ reason = REASON_DUP_SYS; for (tmp = system; tmp; tmp = tmp->next) - if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev) + if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev + && cur->construct == tmp->construct) break; if (!tmp) @@ -211,14 +256,16 @@ remove_duplicates (cpp_reader *pfile, struct cpp_path *head, /* Duplicate of something earlier in the same chain? */ reason = REASON_DUP; for (tmp = head; tmp != cur; tmp = tmp->next) - if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev) + if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev + && cur->construct == tmp->construct) break; if (tmp == cur /* Last in the chain and duplicate of JOIN? */ && !(cur->next == NULL && join && INO_T_EQ (cur->ino, join->ino) - && cur->dev == join->dev)) + && cur->dev == join->dev + && cur->construct == join->construct)) { /* Unique, so keep this directory. */ pcur = &cur->next; @@ -236,18 +283,41 @@ remove_duplicates (cpp_reader *pfile, struct cpp_path *head, return head; } +/* Add SYSROOT to any user-supplied paths in CHAIN starting with + "=". */ + +static void +add_sysroot_to_chain (const char *sysroot, int chain) +{ + struct cpp_dir *p; + + for (p = heads[chain]; p != NULL; p = p->next) + if (p->name[0] == '=' && p->user_supplied_p) + p->name = concat (sysroot, p->name + 1, NULL); +} + /* Merge the four include chains together in the order quote, bracket, system, after. Remove duplicate dirs (as determined by INO_T_EQ()). 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. */ + there; consider -iquote foo -iquote bar -Ifoo -Iquux. It is + however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if + written -iquote bar -Ifoo -Iquux. */ + static void -merge_include_chains (cpp_reader *pfile, int verbose) +merge_include_chains (const char *sysroot, cpp_reader *pfile, int verbose) { + /* Add the sysroot to user-supplied paths starting with "=". */ + if (sysroot) + { + add_sysroot_to_chain (sysroot, QUOTE); + add_sysroot_to_chain (sysroot, BRACKET); + add_sysroot_to_chain (sysroot, SYSTEM); + add_sysroot_to_chain (sysroot, AFTER); + } + /* Join the SYSTEM and AFTER chains. Remove duplicates in the resulting SYSTEM chain. */ if (heads[SYSTEM]) @@ -269,7 +339,7 @@ merge_include_chains (cpp_reader *pfile, int verbose) /* If verbose, print the list of dirs to search. */ if (verbose) { - struct cpp_path *p; + struct cpp_dir *p; fprintf (stderr, _("#include \"...\" search starts here:\n")); for (p = heads[QUOTE];; p = p->next) @@ -299,34 +369,59 @@ split_quote_chain (void) quote_ignores_source_dir = true; } +/* Add P to the chain specified by CHAIN. */ + +void +add_cpp_dir_path (cpp_dir *p, int chain) +{ + if (tails[chain]) + tails[chain]->next = p; + else + heads[chain] = p; + tails[chain] = p; +} + /* Add PATH to the include chain CHAIN. PATH must be malloc-ed and NUL-terminated. */ void -add_path (char *path, int chain, int cxx_aware) +add_path (char *path, int chain, int cxx_aware, bool user_supplied_p) { - struct cpp_path *p; + cpp_dir *p; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Remove unnecessary trailing slashes. On some versions of MS + Windows, trailing _forward_ slashes cause no problems for stat(). + On newer versions, stat() does not recognize a directory that ends + in a '\\' or '/', unless it is a drive root dir, such as "c:/", + where it is obligatory. */ + int pathlen = strlen (path); + char* end = path + pathlen - 1; + /* Preserve the lead '/' or lead "c:/". */ + char* start = path + (pathlen > 2 && path[1] == ':' ? 3 : 1); + + for (; end > start && IS_DIR_SEPARATOR (*end); end--) + *end = 0; +#endif - p = (struct cpp_path *) xmalloc (sizeof (struct cpp_path)); + p = XNEW (cpp_dir); p->next = NULL; p->name = path; if (chain == SYSTEM || chain == AFTER) p->sysp = 1 + !cxx_aware; else p->sysp = 0; + p->construct = 0; + p->user_supplied_p = user_supplied_p; - if (tails[chain]) - tails[chain]->next = p; - else - heads[chain] = p; - tails[chain] = p; + add_cpp_dir_path (p, chain); } /* Exported function to handle include chain merging, duplicate removal, and registration with cpplib. */ void register_include_chains (cpp_reader *pfile, const char *sysroot, - const char *iprefix, int stdinc, int cxx_stdinc, - int verbose) + const char *iprefix, const char *imultilib, + int stdinc, int cxx_stdinc, int verbose) { static const char *const lang_env_vars[] = { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH", @@ -344,12 +439,33 @@ register_include_chains (cpp_reader *pfile, const char *sysroot, add_env_var_paths ("CPATH", BRACKET); add_env_var_paths (lang_env_vars[idx], SYSTEM); + target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc); + /* Finally chain on the standard directories. */ if (stdinc) - add_standard_paths (sysroot, iprefix, cxx_stdinc); + add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc); + + target_c_incpath.extra_includes (sysroot, iprefix, stdinc); - merge_include_chains (pfile, verbose); + merge_include_chains (sysroot, pfile, verbose); cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET], quote_ignores_source_dir); } +#if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES) +static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED, + const char *iprefix ATTRIBUTE_UNUSED, + int stdinc ATTRIBUTE_UNUSED) +{ +} +#endif + +#ifndef TARGET_EXTRA_INCLUDES +#define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int +#endif +#ifndef TARGET_EXTRA_PRE_INCLUDES +#define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int +#endif + +struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES }; +