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:
parent
1260d70fb6
commit
b20d9f0c07
17 changed files with 215 additions and 9 deletions
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
15
gcc/c-opts.c
15
gcc/c-opts.c
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
35
gcc/toplev.c
35
gcc/toplev.c
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue