]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c.opt: Introduce -fworking-directory.
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 5 Aug 2003 21:15:57 +0000 (21:15 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 5 Aug 2003 21:15:57 +0000 (21:15 +0000)
* 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

17 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-lex.c
gcc/c-opts.c
gcc/c.opt
gcc/cppinit.c
gcc/cpplib.h
gcc/dbxout.c
gcc/doc/cpp.texi
gcc/doc/cppopts.texi
gcc/doc/invoke.texi
gcc/dwarf2out.c
gcc/dwarfout.c
gcc/gcc.c
gcc/toplev.c
gcc/toplev.h

index d7342a85c57daab20a095cf9ce087c98c5355457..8aa7b430d1937a3f3d4c2e68f9ea9cdf775785c3 100644 (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.
index 60e980f62ecfcd07baf47d29f7448527db46d5e2..267ede38197ab3dcdcd055ed5ad46de4ab5fc172 100644 (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.  */
 
index bda560313e7de344163e9e92fb03e31ffd8899a7..6230ac937ef3469d7fe5e86b111aa98309355123 100644 (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.  */
 
index 28f2e8d5c271b88e633fe685aa8910fb7cdf1d03..47515e7b7032020e8963ce4962b339bf126cf708 100644 (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)
 {
index 012f24ba53a8a9bfeedd74d82489e325c9427d4f..e2a30430997eeb05b5eccdfb48ccfcf42ca8c2e6 100644 (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.  */
index 221fb678b3ddbc4fa44009dd49646dffa215639a..229414f6c1a7c2815158c41189ad5eeeee8f67ca 100644 (file)
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -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
index b719a85bb8cc4930d92890962ef9b35e719fdb3f..4ef7e24998cd308e68a1cde1e6f1fc0bf07e5924 100644 (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.
index ca3f81422ad8beebb215358613ea4a9fb918361b..57fc0b1308678a43ddc83a334f141ac8eb82dcc7 100644 (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 *);
index 2501c947ef1a5e54052cb1308ed4dbf3b71c357c..d257729d8f8ed2e9505e0c1e7aa5efd901797365 100644 (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)
        {
index a6ff40c53ef513f22caf0e90940b8cd4bee7ef99..2db1ee1ff116d969b2898ed8b604a890e5a01c58 100644 (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}
 
index 8096763e6edded34d695f7301d18b9f9d585db7d..4988227213d35419c912a59fecf97a88082a6a0d 100644 (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
index 518b527a9bc2bb06b4f2d79c5d7c796a31e09920..40cba57d005bf27095af1b4884b25bde8562f14a 100644 (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}}
 
index 48f0f92c08c5cc10a53362a7adfa75d83afc09e2..81cb7ecf5c99c2a44287334a0cefc66baaa606e4 100644 (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);
 }
index 769c0eacb80f61057ead671f9b97737ea8ec761c..cd4dc050661c425a3983348c1f69d2fe77c90261 100644 (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)
index 9f685252e24cc18beb39623769d328f8d1c16509..f18b1684876a93541cce1ad05ce7c991adcd6d41 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -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.  */
index 1e5787783584b465957f7ff2a35f91a39addf462..73d459ac5bf4d4c5efaf9753e33036e2d75d3b9a 100644 (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.  */
 
index c45105c760e7260054c8a366135908213f504ec1..71a9fd5bfadf50aa216a738fda90e4e49b526826 100644 (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 */