447 lines
15 KiB
Diff
447 lines
15 KiB
Diff
2003-08-05 Alexandre Oliva <aoliva@redhat.com>
|
|
|
|
* c.opt: Introduce -fworking-directory.
|
|
* doc/cpp.texi, doc/invoke.texi, doc/cppopts.texi: Document it.
|
|
* c-common.h (flag_working_directory): Declare.
|
|
* c-common.c (flag_working_directory): Define.
|
|
* c-opts.c (c_common_handle_options): Set it.
|
|
(sanitize_cpp_opts): Set...
|
|
* cpplib.h (struct cpp_options): ... working_directory option.
|
|
(struct cpp_callbacks): Add dir_change.
|
|
* cppinit.c (read_original_filename): Call...
|
|
(read_original_directory): New. Look for # 1 "directory//"
|
|
and process it.
|
|
(cpp_read_main_file): Call dir_change callback if working_directory
|
|
option is set.
|
|
* gcc.c (cpp_unique_options): Pass -g*.
|
|
* c-lex.c (cb_dir_change): New.
|
|
(init_c_lex): Set dir_change callback.
|
|
* toplev.c (src_pwd): New static variable.
|
|
(set_src_pwd, get_src_pwd): New functions.
|
|
* toplev.h (get_src_pwd, set_src_pwd): Declare.
|
|
* dbxout.c (dbxout_init): Call get_src_pwd() instead of getpwd().
|
|
* dwarf2out.c (gen_compile_unit_die): Likewise.
|
|
* dwarfout.c (output_compile_unit_die, dwarfout_init): Likewise.
|
|
|
|
================================================================================
|
|
--- gcc-3.3.4/gcc/c-common.c
|
|
+++ gcc-3.3.4/gcc/c-common.c
|
|
@@ -548,6 +548,13 @@
|
|
|
|
int flag_weak = 1;
|
|
|
|
+/* 0 means we want the preprocessor to not emit line directives for
|
|
+ the current working directory. 1 means we want it to do it. -1
|
|
+ means we should decide depending on whether debugging information
|
|
+ is being emitted or not. */
|
|
+
|
|
+int flag_working_directory = -1;
|
|
+
|
|
/* Nonzero to use __cxa_atexit, rather than atexit, to register
|
|
destructors for local statics and global objects. */
|
|
|
|
--- gcc-3.3.4/gcc/c-common.h
|
|
+++ gcc-3.3.4/gcc/c-common.h
|
|
@@ -711,6 +711,13 @@
|
|
|
|
extern int flag_weak;
|
|
|
|
+/* 0 means we want the preprocessor to not emit line directives for
|
|
+ the current working directory. 1 means we want it to do it. -1
|
|
+ means we should decide depending on whether debugging information
|
|
+ is being emitted or not. */
|
|
+
|
|
+extern int flag_working_directory;
|
|
+
|
|
/* Nonzero to use __cxa_atexit, rather than atexit, to register
|
|
destructors for local statics and global objects. */
|
|
|
|
--- gcc-3.3.4/gcc/c-lex.c
|
|
+++ gcc-3.3.4/gcc/c-lex.c
|
|
@@ -82,6 +82,7 @@
|
|
static void update_header_times PARAMS ((const char *));
|
|
static int dump_one_header PARAMS ((splay_tree_node, void *));
|
|
static void cb_line_change PARAMS ((cpp_reader *, const cpp_token *, int));
|
|
+static void cb_dir_change PARAMS ((cpp_reader *, const char *));
|
|
static void cb_ident PARAMS ((cpp_reader *, unsigned int,
|
|
const cpp_string *));
|
|
static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
|
|
@@ -119,6 +120,7 @@
|
|
cb = cpp_get_callbacks (parse_in);
|
|
|
|
cb->line_change = cb_line_change;
|
|
+ cb->dir_change = cb_dir_change;
|
|
cb->ident = cb_ident;
|
|
cb->file_change = cb_file_change;
|
|
cb->def_pragma = cb_def_pragma;
|
|
@@ -206,6 +208,13 @@
|
|
return 0;
|
|
}
|
|
|
|
+static void
|
|
+cb_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
|
|
+{
|
|
+ if (! set_src_pwd (dir))
|
|
+ warning ("too late for # directive to set debug directory");
|
|
+}
|
|
+
|
|
void
|
|
dump_time_statistics ()
|
|
{
|
|
--- gcc-3.3.4/gcc/c-opts.c
|
|
+++ gcc-3.3.4/gcc/c-opts.c
|
|
@@ -124,6 +124,7 @@
|
|
OPT("MQ", CL_ALL | CL_ARG, OPT_MQ) \
|
|
OPT("MT", CL_ALL | CL_ARG, OPT_MT) \
|
|
OPT("P", CL_ALL, OPT_P) \
|
|
+ OPT("fworking-directory", CL_ALL, OPT_fworking_directory) \
|
|
OPT("Wabi", CL_CXX, OPT_Wabi) \
|
|
OPT("Wall", CL_ALL, OPT_Wall) \
|
|
OPT("Wbad-function-cast", CL_C, OPT_Wbad_function_cast) \
|
|
@@ -686,6 +687,10 @@
|
|
cpp_opts->no_line_commands = 1;
|
|
break;
|
|
|
|
+ case OPT_fworking_directory:
|
|
+ flag_working_directory = on;
|
|
+ break;
|
|
+
|
|
case OPT_Wabi:
|
|
warn_abi = on;
|
|
break;
|
|
@@ -1587,6 +1592,15 @@
|
|
and/or -Wtraditional, whatever the ordering. */
|
|
cpp_opts->warn_long_long
|
|
= warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
|
|
+
|
|
+ /* If we're generating preprocessor output, emit current directory
|
|
+ if explicitly requested or if debugging information is enabled.
|
|
+ ??? Maybe we should only do it for debugging formats that
|
|
+ actually output the current directory? */
|
|
+ if (flag_working_directory == -1)
|
|
+ flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
|
|
+ cpp_opts->working_directory
|
|
+ = flag_preprocess_only && flag_working_directory;
|
|
}
|
|
|
|
/* Set the C 89 standard (with 1994 amendments if C94, without GNU
|
|
@@ -1790,6 +1804,10 @@
|
|
-dI Include #include directives in the output\n\
|
|
"), stdout);
|
|
fputs (_("\
|
|
+ -fworking-directory Generate a #line directive pointing at the\n\
|
|
+ current working directory\n\
|
|
+"), stdout);
|
|
+ fputs (_("\
|
|
-f[no-]preprocessed Treat the input file as already preprocessed\n\
|
|
-ftabstop=<number> Distance between tab stops for column reporting\n\
|
|
-P Do not generate #line directives\n\
|
|
--- gcc-3.3.4/gcc/cppinit.c
|
|
+++ gcc-3.3.4/gcc/cppinit.c
|
|
@@ -107,6 +107,7 @@
|
|
static void free_chain PARAMS ((struct pending_option *));
|
|
static void init_standard_includes PARAMS ((cpp_reader *));
|
|
static void read_original_filename PARAMS ((cpp_reader *));
|
|
+static void read_original_directory PARAMS ((cpp_reader *));
|
|
static void new_pending_directive PARAMS ((struct cpp_pending *,
|
|
const char *,
|
|
cl_directive_handler));
|
|
@@ -1026,6 +1027,24 @@
|
|
if (CPP_OPTION (pfile, preprocessed))
|
|
read_original_filename (pfile);
|
|
|
|
+ if (CPP_OPTION (pfile, working_directory))
|
|
+ {
|
|
+ const char *name = pfile->map->to_file;
|
|
+ const char *dir = getpwd ();
|
|
+ char *dir_with_slashes = alloca (strlen (dir) + 3);
|
|
+
|
|
+ memcpy (dir_with_slashes, dir, strlen (dir));
|
|
+ memcpy (dir_with_slashes + strlen (dir), "//", 3);
|
|
+
|
|
+ if (pfile->cb.dir_change)
|
|
+ pfile->cb.dir_change (pfile, dir);
|
|
+ /* Emit file renames that will be recognized by
|
|
+ read_directory_filename, since dir_change doesn't output
|
|
+ anything. */
|
|
+ _cpp_do_file_change (pfile, LC_RENAME, dir_with_slashes, 1, 0);
|
|
+ _cpp_do_file_change (pfile, LC_RENAME, name, 1, 0);
|
|
+ }
|
|
+
|
|
return pfile->map->to_file;
|
|
}
|
|
|
|
@@ -1051,6 +1070,7 @@
|
|
if (token1->type == CPP_NUMBER)
|
|
{
|
|
_cpp_handle_directive (pfile, token->flags & PREV_WHITE);
|
|
+ read_original_directory (pfile);
|
|
return;
|
|
}
|
|
}
|
|
@@ -1059,6 +1079,61 @@
|
|
_cpp_backup_tokens (pfile, 1);
|
|
}
|
|
|
|
+/* For preprocessed files, if the tokens following the first filename
|
|
+ line is of the form # <line> "/path/name//", handle the
|
|
+ directive so we know the original current directory. */
|
|
+static void
|
|
+read_original_directory (pfile)
|
|
+ cpp_reader *pfile;
|
|
+{
|
|
+ const cpp_token *hash, *token;
|
|
+
|
|
+ /* Lex ahead; if the first tokens are of the form # NUM, then
|
|
+ process the directive, otherwise back up. */
|
|
+ hash = _cpp_lex_direct (pfile);
|
|
+ if (hash->type != CPP_HASH)
|
|
+ {
|
|
+ _cpp_backup_tokens (pfile, 1);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ token = _cpp_lex_direct (pfile);
|
|
+
|
|
+ if (token->type != CPP_NUMBER)
|
|
+ {
|
|
+ _cpp_backup_tokens (pfile, 2);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ token = _cpp_lex_direct (pfile);
|
|
+
|
|
+ if (token->type != CPP_STRING
|
|
+ || ! (token->val.str.len >= 5
|
|
+ && token->val.str.text[token->val.str.len-2] == '/'
|
|
+ && token->val.str.text[token->val.str.len-3] == '/'))
|
|
+ {
|
|
+ _cpp_backup_tokens (pfile, 3);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (pfile->cb.dir_change)
|
|
+ {
|
|
+ char *debugdir = alloca (token->val.str.len - 3);
|
|
+
|
|
+ memcpy (debugdir, (const char *) token->val.str.text + 1,
|
|
+ token->val.str.len - 4);
|
|
+ debugdir[token->val.str.len - 4] = '\0';
|
|
+
|
|
+ pfile->cb.dir_change (pfile, debugdir);
|
|
+ }
|
|
+
|
|
+ /* We want to process the fake line changes as regular changes, to
|
|
+ get them output. */
|
|
+ _cpp_backup_tokens (pfile, 3);
|
|
+
|
|
+ CPP_OPTION (pfile, working_directory) = false;
|
|
+}
|
|
+
|
|
/* Handle pending command line options: -D, -U, -A, -imacros and
|
|
-include. This should be called after debugging has been properly
|
|
set up in the front ends. */
|
|
--- gcc-3.3.4/gcc/cpplib.h
|
|
+++ gcc-3.3.4/gcc/cpplib.h
|
|
@@ -407,6 +407,11 @@
|
|
|
|
/* Nonzero means __STDC__ should have the value 0 in system headers. */
|
|
unsigned char stdc_0_in_system_headers;
|
|
+
|
|
+ /* Nonzero means output a directory line marker right after the
|
|
+ initial file name line marker, and before a duplicate initial
|
|
+ line marker. */
|
|
+ bool working_directory;
|
|
};
|
|
|
|
/* Call backs. */
|
|
@@ -415,6 +420,7 @@
|
|
/* Called when a new line of preprocessed output is started. */
|
|
void (*line_change) PARAMS ((cpp_reader *, const cpp_token *, int));
|
|
void (*file_change) PARAMS ((cpp_reader *, const struct line_map *));
|
|
+ void (*dir_change) PARAMS ((cpp_reader *, const char *));
|
|
void (*include) PARAMS ((cpp_reader *, unsigned int,
|
|
const unsigned char *, const cpp_token *));
|
|
void (*define) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
|
|
--- gcc-3.3.4/gcc/dbxout.c
|
|
+++ gcc-3.3.4/gcc/dbxout.c
|
|
@@ -438,7 +438,8 @@
|
|
if (use_gnu_debug_info_extensions)
|
|
#endif
|
|
{
|
|
- if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
|
|
+ if (!cwd && (cwd = get_src_pwd ())
|
|
+ && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
|
|
cwd = concat (cwd, FILE_NAME_JOINER, NULL);
|
|
if (cwd)
|
|
{
|
|
--- gcc-3.3.4/gcc/doc/cpp.texi
|
|
+++ gcc-3.3.4/gcc/doc/cpp.texi
|
|
@@ -4066,7 +4066,9 @@
|
|
cpp [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}]
|
|
[@option{-I}@var{dir}@dots{}] [@option{-W}@var{warn}@dots{}]
|
|
[@option{-M}|@option{-MM}] [@option{-MG}] [@option{-MF} @var{filename}]
|
|
- [@option{-MP}] [@option{-MQ} @var{target}@dots{}] [@option{-MT} @var{target}@dots{}]
|
|
+ [@option{-MP}] [@option{-MQ} @var{target}@dots{}]
|
|
+ [@option{-MT} @var{target}@dots{}]
|
|
+ [@option{-P}] [@option{-fno-working-directory}]
|
|
[@option{-x} @var{language}] [@option{-std=}@var{standard}]
|
|
@var{infile} @var{outfile}
|
|
|
|
--- gcc-3.3.4/gcc/doc/cppopts.texi
|
|
+++ gcc-3.3.4/gcc/doc/cppopts.texi
|
|
@@ -1,4 +1,4 @@
|
|
-@c Copyright (c) 1999, 2000, 2001, 2002
|
|
+@c Copyright (c) 1999, 2000, 2001, 2002, 2003
|
|
@c Free Software Foundation, Inc.
|
|
@c This is part of the CPP and GCC manuals.
|
|
@c For copying conditions, see the file gcc.texi.
|
|
@@ -470,6 +470,22 @@
|
|
line. If the value is less than 1 or greater than 100, the option is
|
|
ignored. The default is 8.
|
|
|
|
+@item -fworking-directory
|
|
+@opindex fworking-directory
|
|
+@opindex fno-working-directory
|
|
+Enable generation of linemarkers in the preprocessor output that will
|
|
+let the compiler know the current working directory at the time of
|
|
+preprocessing. When this option is enabled, the preprocessor will
|
|
+emit, after the initial linemarker, a second linemarker with the
|
|
+current working directory followed by two slashes. GCC will use this
|
|
+directory, when it's present in the preprocessed input, as the
|
|
+directory emitted as the current working directory in some debugging
|
|
+information formats. This option is implicitly enabled if debugging
|
|
+information is enabled, but this can be inhibited with the negated
|
|
+form @option{-fno-working-directory}. If the @option{-P} flag is
|
|
+present in the command line, this option has no effect, since no
|
|
+@code{#line} directives are emitted whatsoever.
|
|
+
|
|
@item -fno-show-column
|
|
@opindex fno-show-column
|
|
Do not print column numbers in diagnostics. This may be necessary if
|
|
--- gcc-3.3.4/gcc/doc/invoke.texi
|
|
+++ gcc-3.3.4/gcc/doc/invoke.texi
|
|
@@ -294,7 +294,8 @@
|
|
-include @var{file} -imacros @var{file} @gol
|
|
-iprefix @var{file} -iwithprefix @var{dir} @gol
|
|
-iwithprefixbefore @var{dir} -isystem @var{dir} @gol
|
|
--M -MM -MF -MG -MP -MQ -MT -nostdinc -P -remap @gol
|
|
+-M -MM -MF -MG -MP -MQ -MT -nostdinc @gol
|
|
+-P -fworking-directory -remap @gol
|
|
-trigraphs -undef -U@var{macro} -Wp,@var{option}}
|
|
|
|
@item Assembler Option
|
|
--- gcc-3.3.4/gcc/dwarf2out.c
|
|
+++ gcc-3.3.4/gcc/dwarf2out.c
|
|
@@ -11764,7 +11764,7 @@
|
|
{
|
|
dw_die_ref die;
|
|
char producer[250];
|
|
- const char *wd = getpwd ();
|
|
+ const char *wd = get_src_pwd ();
|
|
const char *language_string = lang_hooks.name;
|
|
int language;
|
|
|
|
@@ -13222,7 +13222,7 @@
|
|
|
|
if (get_AT (comp_unit_die, DW_AT_comp_dir) == NULL)
|
|
{
|
|
- char *wd = getpwd ();
|
|
+ char *wd = get_src_pwd ();
|
|
unsigned i;
|
|
|
|
if (wd != NULL)
|
|
--- gcc-3.3.4/gcc/dwarfout.c
|
|
+++ gcc-3.3.4/gcc/dwarfout.c
|
|
@@ -4147,7 +4147,7 @@
|
|
stmt_list_attribute (LINE_BEGIN_LABEL);
|
|
|
|
{
|
|
- const char *wd = getpwd ();
|
|
+ const char *wd = get_src_pwd ();
|
|
if (wd)
|
|
comp_dir_attribute (wd);
|
|
}
|
|
@@ -6272,7 +6272,7 @@
|
|
ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SFNAMES_SECTION);
|
|
ASM_OUTPUT_LABEL (asm_out_file, SFNAMES_BEGIN_LABEL);
|
|
{
|
|
- const char *pwd = getpwd ();
|
|
+ const char *pwd = get_src_pwd ();
|
|
char *dirname;
|
|
|
|
if (!pwd)
|
|
--- gcc-3.3.4/gcc/gcc.c
|
|
+++ gcc-3.3.4/gcc/gcc.c
|
|
@@ -725,7 +725,7 @@
|
|
in turn cause preprocessor symbols to be defined specially. */
|
|
static const char *cpp_options =
|
|
"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
|
|
- %{O*} %{undef}";
|
|
+ %{g*} %{O*} %{undef}";
|
|
|
|
/* This contains cpp options which are not passed when the preprocessor
|
|
output will be used by another program. */
|
|
--- gcc-3.3.4/gcc/toplev.c
|
|
+++ gcc-3.3.4/gcc/toplev.c
|
|
@@ -1711,6 +1711,46 @@
|
|
FILE *rtl_dump_file = NULL;
|
|
FILE *cgraph_dump_file = NULL;
|
|
|
|
+/* The current working directory of a translation. It's generally the
|
|
+ directory from which compilation was initiated, but a preprocessed
|
|
+ file may specify the original directory in which it was
|
|
+ created. */
|
|
+
|
|
+static const char *src_pwd;
|
|
+
|
|
+/* Initialize src_pwd with the given string, and return true. If it
|
|
+ was already initialized, return false. As a special case, it may
|
|
+ be called with a NULL argument to test whether src_pwd has NOT been
|
|
+ initialized yet. */
|
|
+
|
|
+bool
|
|
+set_src_pwd (const char *pwd)
|
|
+{
|
|
+ if (src_pwd)
|
|
+ {
|
|
+ if (strcmp (src_pwd, pwd) == 0)
|
|
+ return true;
|
|
+ else
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ src_pwd = xstrdup (pwd);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/* Return the directory from which the translation unit was initiated,
|
|
+ in case set_src_pwd() was not called before to assign it a
|
|
+ different value. */
|
|
+
|
|
+const char *
|
|
+get_src_pwd (void)
|
|
+{
|
|
+ if (! src_pwd)
|
|
+ src_pwd = getpwd ();
|
|
+
|
|
+ return src_pwd;
|
|
+}
|
|
+
|
|
/* Decode the string P as an integral parameter.
|
|
If the string is indeed an integer return its numeric value else
|
|
issue an Invalid Option error for the option PNAME and return DEFVAL.
|
|
--- gcc-3.3.4/gcc/toplev.h
|
|
+++ gcc-3.3.4/gcc/toplev.h
|
|
@@ -133,4 +133,10 @@
|
|
extern int exact_log2_wide PARAMS ((unsigned HOST_WIDE_INT));
|
|
extern int floor_log2_wide PARAMS ((unsigned HOST_WIDE_INT));
|
|
|
|
+/* Functions used to get and set GCC's notion of in what directory
|
|
+ compilation was started. */
|
|
+
|
|
+extern const char *get_src_pwd (void);
|
|
+extern bool set_src_pwd (const char *);
|
|
+
|
|
#endif /* ! GCC_TOPLEV_H */
|