c.opt: Introduce -fworking-directory.

* 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.

From-SVN: r70189
This commit is contained in:
Alexandre Oliva 2003-08-05 21:15:57 +00:00 committed by Alexandre Oliva
parent 1260d70fb6
commit b20d9f0c07
17 changed files with 215 additions and 9 deletions

View File

@ -1,3 +1,28 @@
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.
2003-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
* pretty-print.h (pp_set_line_maximum_length): Make macro.

View File

@ -559,6 +559,13 @@ int flag_new_for_scope = 1;
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. */

View File

@ -716,6 +716,13 @@ extern int flag_new_for_scope;
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. */

View File

@ -72,6 +72,7 @@ static tree lex_charconst (const cpp_token *);
static void update_header_times (const char *);
static int dump_one_header (splay_tree_node, void *);
static void cb_line_change (cpp_reader *, const cpp_token *, int);
static void cb_dir_change (cpp_reader *, const char *);
static void cb_ident (cpp_reader *, unsigned int, const cpp_string *);
static void cb_def_pragma (cpp_reader *, unsigned int);
static void cb_define (cpp_reader *, unsigned int, cpp_hashnode *);
@ -98,6 +99,7 @@ init_c_lex (void)
cb = cpp_get_callbacks (parse_in);
cb->line_change = cb_line_change;
cb->dir_change = cb_dir_change;
cb->ident = cb_ident;
cb->def_pragma = cb_def_pragma;
cb->valid_pch = c_common_valid_pch;
@ -200,6 +202,13 @@ cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
src_lineno = SOURCE_LINE (map, token->line);
}
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
fe_file_change (const struct line_map *new_map)
{

View File

@ -235,7 +235,7 @@ c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
return result;
}
/* Handle switch SCODE with argument ARG. ON is true, unless no-
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
form of an -f or -W option was given. Returns 0 if the switch was
invalid, a negative number to prevent language-independent
processing in toplev.c (a hack necessary for the short-term). */
@ -335,6 +335,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
flag_no_line_commands = 1;
break;
case OPT_fworking_directory:
flag_working_directory = value;
break;
case OPT_U:
defer_opt (code, arg);
break;
@ -1329,6 +1333,15 @@ sanitize_cpp_opts (void)
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;
}
/* Add include path with a prefix at the front of its name. */

View File

@ -650,6 +650,10 @@ fwide-exec-charset=
C ObjC C++ ObjC++ Joined RejectNegative
-fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset>
fworking-directory
C ObjC C++ ObjC++
Generate a #line directive pointing at the current working directory
fxref
C++ ObjC++
Emit cross referencing information

View File

@ -28,6 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static void init_library (void);
static void mark_named_operators (cpp_reader *);
static void read_original_filename (cpp_reader *);
static void read_original_directory (cpp_reader *);
static void post_options (cpp_reader *);
/* If we have designated initializers (GCC >2.7) these tables can be
@ -470,6 +471,24 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname)
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;
}
@ -494,6 +513,7 @@ read_original_filename (cpp_reader *pfile)
if (token1->type == CPP_NUMBER)
{
_cpp_handle_directive (pfile, token->flags & PREV_WHITE);
read_original_directory (pfile);
return;
}
}
@ -502,6 +522,60 @@ read_original_filename (cpp_reader *pfile)
_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 (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;
}
/* This is called at the end of preprocessing. It pops the last
buffer and writes dependency output, and returns the number of
errors.

View File

@ -370,6 +370,11 @@ struct cpp_options
/* 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 to cpplib client. */
@ -378,6 +383,7 @@ struct cpp_callbacks
/* Called when a new line of preprocessed output is started. */
void (*line_change) (cpp_reader *, const cpp_token *, int);
void (*file_change) (cpp_reader *, const struct line_map *);
void (*dir_change) (cpp_reader *, const char *);
void (*include) (cpp_reader *, unsigned int, const unsigned char *,
const char *, int);
void (*define) (cpp_reader *, unsigned int, cpp_hashnode *);

View File

@ -469,7 +469,8 @@ dbxout_init (const char *input_file_name)
/* Put the current working directory in an N_SO symbol. */
if (use_gnu_debug_info_extensions)
{
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)
{

View File

@ -4133,7 +4133,9 @@ without notice.
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}

View File

@ -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.
@ -513,6 +513,22 @@ corresponds to the width of @code{wchar_t}. As with
by the system's @code{iconv} library routine; however, you will have
problems with encodings that do not fit exactly in @code{wchar_t}.
@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

View File

@ -301,7 +301,8 @@ in the following sections.
-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} @gol
-Xpreprocessor @var{option}}

View File

@ -9506,7 +9506,7 @@ add_name_attribute (dw_die_ref die, const char *name_string)
static void
add_comp_dir_attribute (dw_die_ref die)
{
const char *wd = getpwd ();
const char *wd = get_src_pwd ();
if (wd != NULL)
add_AT_string (die, DW_AT_comp_dir, wd);
}

View File

@ -4043,7 +4043,7 @@ output_compile_unit_die (void *arg)
stmt_list_attribute (LINE_BEGIN_LABEL);
{
const char *wd = getpwd ();
const char *wd = get_src_pwd ();
if (wd)
comp_dir_attribute (wd);
}
@ -6114,7 +6114,7 @@ dwarfout_init (const char *main_input_filename)
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)

View File

@ -755,7 +755,7 @@ static const char *cpp_unique_options =
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. */

View File

@ -1219,6 +1219,41 @@ FILE *aux_info_file;
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)
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;
}
/* Set up a default flag_random_seed and local_tick, unless the user
already specified one. */

View File

@ -155,4 +155,10 @@ extern bool fast_math_flags_set_p (void);
extern int exact_log2_wide (unsigned HOST_WIDE_INT);
extern int floor_log2_wide (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 */