+2013-02-03 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * dwarf2read.c (file_file_name): New function with code from
+ file_full_name.
+ (file_full_name): Move most of the code to file_file_name.
+ (macro_start_file): Rename variable full_name to file_name and use
+ file_file_name for it. Add comp_dir parameter to new_macro_table.
+ * macrocmd.c (show_pp_source_pos): New variable fullname. Replace any
+ macro_source_file->filename access by macro_source_fullname call.
+ * macroscope.c (_initialize_macroscope): Update the new_macro_table
+ caller.
+ * macrotab.c (struct macro_table): New field comp_dir.
+ (macro_include): New variables link_fullname and source_fullname.
+ Replace any macro_source_file->filename access by macro_source_fullname
+ call.
+ (macro_lookup_inclusion): Remove the partial filenames checking code.
+ (check_for_redefinition): New variables source_fullname and
+ found_key_fullname. Replace any macro_source_file->filename access by
+ macro_source_fullname call.
+ (macro_undef): New variables source_fullname and key_fullname. Replace
+ any macro_source_file->filename access by macro_source_fullname call.
+ (macro_lookup_definition): New variables retval and source_fullname.
+ Replace any macro_source_file->filename access by macro_source_fullname
+ call.
+ (foreach_macro): New variable key_fullname. Replace any
+ macro_source_file->filename access by macro_source_fullname call.
+ (foreach_macro_in_scope): New variable datum_fullname. Replace any
+ macro_source_file->filename access by macro_source_fullname call.
+ (new_macro_table): Add parameter comp_dir. Initialize T with it.
+ (macro_source_fullname): New function.
+ * macrotab.h (struct macro_source_file): Extent the filename field
+ comment.
+ (new_macro_table): New parameter comp_dir, add a comment for it.
+ (macro_source_fullname): new declaration.
+
2013-02-03 Jan Kratochvil <jan.kratochvil@redhat.com>
* dwarf2read.c (dw2_map_symtabs_matching_filename): Move variable
\f
/* Macro support. */
-/* Return the full name of file number I in *LH's file name table.
- Use COMP_DIR as the name of the current directory of the
- compilation. The result is allocated using xmalloc; the caller is
+/* Return file name relative to the compilation directory of file number I in
+ *LH's file name table. The result is allocated using xmalloc; the caller is
responsible for freeing it. */
+
static char *
-file_full_name (int file, struct line_header *lh, const char *comp_dir)
+file_file_name (int file, struct line_header *lh)
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
{
struct file_entry *fe = &lh->file_names[file - 1];
- if (IS_ABSOLUTE_PATH (fe->name))
+ if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0)
return xstrdup (fe->name);
- else
- {
- const char *dir;
-
- if (fe->dir_index == 0)
- dir = comp_dir;
- else
- {
- dir = lh->include_dirs[fe->dir_index - 1];
- if (!IS_ABSOLUTE_PATH (dir))
- return concat (comp_dir, SLASH_STRING, dir, SLASH_STRING,
- fe->name, NULL);
- }
-
- if (dir)
- return concat (dir, SLASH_STRING, fe->name, NULL);
- else
- return xstrdup (fe->name);
- }
+ return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING,
+ fe->name, NULL);
}
else
{
}
}
+/* Return the full name of file number I in *LH's file name table.
+ Use COMP_DIR as the name of the current directory of the
+ compilation. The result is allocated using xmalloc; the caller is
+ responsible for freeing it. */
+static char *
+file_full_name (int file, struct line_header *lh, const char *comp_dir)
+{
+ /* Is the file number a valid index into the line header's file name
+ table? Remember that file numbers start with one, not zero. */
+ if (1 <= file && file <= lh->num_file_names)
+ {
+ char *relative = file_file_name (file, lh);
+
+ if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL)
+ return relative;
+ return reconcat (relative, comp_dir, SLASH_STRING, relative, NULL);
+ }
+ else
+ return file_file_name (file, lh);
+}
+
static struct macro_source_file *
macro_start_file (int file, int line,
const char *comp_dir,
struct line_header *lh, struct objfile *objfile)
{
- /* The full name of this source file. */
- char *full_name = file_full_name (file, lh, comp_dir);
+ /* File name relative to the compilation directory of this source file. */
+ char *file_name = file_file_name (file, lh);
/* We don't create a macro table for this compilation unit
at all until we actually get a filename. */
if (! pending_macros)
pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack,
- objfile->per_bfd->macro_cache);
+ objfile->per_bfd->macro_cache,
+ comp_dir);
if (! current_file)
{
/* If we have no current file, then this must be the start_file
directive for the compilation unit's main source file. */
- current_file = macro_set_main (pending_macros, full_name);
+ current_file = macro_set_main (pending_macros, file_name);
macro_define_special (pending_macros);
}
else
- current_file = macro_include (current_file, line, full_name);
+ current_file = macro_include (current_file, line, file_name);
- xfree (full_name);
+ xfree (file_name);
return current_file;
}
struct macro_source_file *file,
int line)
{
- fprintf_filtered (stream, "%s:%d\n", file->filename, line);
+ char *fullname;
+
+ fullname = macro_source_fullname (file);
+ fprintf_filtered (stream, "%s:%d\n", fullname, line);
+ xfree (fullname);
while (file->included_by)
{
- fprintf_filtered (gdb_stdout, " included at %s:%d\n",
- file->included_by->filename,
+ fullname = macro_source_fullname (file->included_by);
+ fprintf_filtered (gdb_stdout, " included at %s:%d\n", fullname,
file->included_at_line);
+ xfree (fullname);
file = file->included_by;
}
}
void
_initialize_macroscope (void)
{
- macro_user_macros = new_macro_table (0, 0);
+ macro_user_macros = new_macro_table (NULL, NULL, NULL);
macro_set_main (macro_user_macros, "<user-defined>");
macro_allow_redefinitions (macro_user_macros);
}
#inclusion tree; everything else is #included from here. */
struct macro_source_file *main_source;
+ /* Compilation directory for all files of this macro table. It is allocated
+ on objfile's obstack. */
+ const char *comp_dir;
+
/* True if macros in this table can be redefined without issuing an
error. */
int redef_ok;
the new one? */
if (*link && line == (*link)->included_at_line)
{
+ char *link_fullname, *source_fullname;
+
/* This means the compiler is emitting bogus debug info. (GCC
circa March 2002 did this.) It also means that the splay
tree ordering function, macro_tree_compare, will abort,
should tolerate bad debug info. So:
First, squawk. */
+
+ link_fullname = macro_source_fullname (*link);
+ source_fullname = macro_source_fullname (source);
complaint (&symfile_complaints,
_("both `%s' and `%s' allegedly #included at %s:%d"),
- included, (*link)->filename, source->filename, line);
+ included, link_fullname, source_fullname, line);
+ xfree (source_fullname);
+ xfree (link_fullname);
/* Now, choose a new, unoccupied line number for this
#inclusion, after the alleged #inclusion line. */
if (filename_cmp (name, source->filename) == 0)
return source;
- /* The filename in the source structure is probably a full path, but
- NAME could be just the final component of the name. */
- {
- int name_len = strlen (name);
- int src_name_len = strlen (source->filename);
-
- /* We do mean < here, and not <=; if the lengths are the same,
- then the filename_cmp above should have triggered, and we need to
- check for a slash here. */
- if (name_len < src_name_len
- && IS_DIR_SEPARATOR (source->filename[src_name_len - name_len - 1])
- && filename_cmp (name,
- source->filename + src_name_len - name_len) == 0)
- return source;
- }
-
/* It's not us. Try all our children, and return the lowest. */
{
struct macro_source_file *child;
if (! same)
{
+ char *source_fullname, *found_key_fullname;
+
+ source_fullname = macro_source_fullname (source);
+ found_key_fullname = macro_source_fullname (found_key->start_file);
complaint (&symfile_complaints,
_("macro `%s' redefined at %s:%d; "
"original definition at %s:%d"),
- name, source->filename, line,
- found_key->start_file->filename, found_key->start_line);
+ name, source_fullname, line, found_key_fullname,
+ found_key->start_line);
+ xfree (found_key_fullname);
+ xfree (source_fullname);
}
return found_key;
#definition. */
if (key->end_file)
{
+ char *source_fullname, *key_fullname;
+
+ source_fullname = macro_source_fullname (source);
+ key_fullname = macro_source_fullname (key->end_file);
complaint (&symfile_complaints,
_("macro '%s' is #undefined twice,"
" at %s:%d and %s:%d"),
- name,
- source->filename, line,
- key->end_file->filename, key->end_line);
+ name, source_fullname, line, key_fullname,
+ key->end_line);
+ xfree (key_fullname);
+ xfree (source_fullname);
}
/* Whether or not we've seen a prior #undefinition, wipe out
splay_tree_node n = find_definition (name, source, line);
if (n)
- return fixup_definition (source->filename, line,
- (struct macro_definition *) n->value);
+ {
+ struct macro_definition *retval;
+ char *source_fullname;
+
+ source_fullname = macro_source_fullname (source);
+ retval = fixup_definition (source_fullname, line,
+ (struct macro_definition *) n->value);
+ xfree (source_fullname);
+ return retval;
+ }
else
return 0;
}
{
struct macro_for_each_data *datum = (struct macro_for_each_data *) arg;
struct macro_key *key = (struct macro_key *) node->key;
- struct macro_definition *def
- = fixup_definition (key->start_file->filename, key->start_line,
- (struct macro_definition *) node->value);
+ struct macro_definition *def;
+ char *key_fullname;
+
+ key_fullname = macro_source_fullname (key->start_file);
+ def = fixup_definition (key_fullname, key->start_line,
+ (struct macro_definition *) node->value);
+ xfree (key_fullname);
(*datum->fn) (key->name, def, key->start_file, key->start_line,
datum->user_data);
{
struct macro_for_each_data *datum = (struct macro_for_each_data *) info;
struct macro_key *key = (struct macro_key *) node->key;
- struct macro_definition *def
- = fixup_definition (datum->file->filename, datum->line,
- (struct macro_definition *) node->value);
+ struct macro_definition *def;
+ char *datum_fullname;
+
+ datum_fullname = macro_source_fullname (datum->file);
+ def = fixup_definition (datum_fullname, datum->line,
+ (struct macro_definition *) node->value);
+ xfree (datum_fullname);
/* See if this macro is defined before the passed-in line, and
extends past that line. */
struct macro_table *
-new_macro_table (struct obstack *obstack,
- struct bcache *b)
+new_macro_table (struct obstack *obstack, struct bcache *b,
+ const char *comp_dir)
{
struct macro_table *t;
t->obstack = obstack;
t->bcache = b;
t->main_source = NULL;
+ t->comp_dir = comp_dir;
t->redef_ok = 0;
t->definitions = (splay_tree_new_with_allocator
(macro_tree_compare,
/* Free the table of macro definitions. */
splay_tree_delete (table->definitions);
}
+
+/* See macrotab.h for the comment. */
+
+char *
+macro_source_fullname (struct macro_source_file *file)
+{
+ if (file->table->comp_dir == NULL || IS_ABSOLUTE_PATH (file->filename))
+ return xstrdup (file->filename);
+
+ return concat (file->table->comp_dir, SLASH_STRING, file->filename, NULL);
+}
a part of. */
struct macro_table *table;
- /* A source file --- possibly a header file. */
+ /* A source file --- possibly a header file. This filename is relative to
+ the compilation directory (table->comp_dir), it exactly matches the
+ symtab->filename content. */
const char *filename;
/* The location we were #included from, or zero if we are the
xmalloc if OBSTACK is zero. Use BCACHE to store all macro names,
arguments, definitions, and anything else that might be the same
amongst compilation units in an executable file; if BCACHE is zero,
- don't cache these things.
+ don't cache these things. COMP_DIR optionally contains the compilation
+ directory of all files for this macro table.
Note that, if either OBSTACK or BCACHE are non-zero, then removing
information from the table may leak memory. Neither obstacks nor
the same source location (although 'gcc -DFOO -UFOO -DFOO=2' does
do that in GCC 4.1.2.). */
struct macro_table *new_macro_table (struct obstack *obstack,
- struct bcache *bcache);
+ struct bcache *bcache,
+ const char *comp_dir);
/* Free TABLE, and any macro definitions, source file structures,
macro_callback_fn fn,
void *user_data);
+/* Return FILE->filename with possibly prepended compilation directory name.
+ This is raw concatenation without the "set substitute-path" and gdb_realpath
+ applications done by symtab_to_fullname. Returned string must be freed by
+ xfree.
+
+ THis function ignores the "set filename-display" setting. Its default
+ setting is "relative" which is backward compatible but the former behavior
+ of macro filenames printing was "absolute". */
+extern char *macro_source_fullname (struct macro_source_file *file);
#endif /* MACROTAB_H */
+2013-02-03 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * gdb.linespec/base/one/header.h: New file.
+ * gdb.linespec/base/two/header.h: New file.
+ * gdb.linespec/macro-relative.c: New file.
+ * gdb.linespec/macro-relative.exp: New file.
+
2013-02-03 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/fullpath-expand-func.c: New file.
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ 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 of the License, 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#if 1
+# define HEADER 1
+#endif
+#if 0
+# undef HEADER
+# define HEADER 2
+void header_two_func (void) {}
+#endif
+#if 1
+/* #include "header.h" does not work, why? */
+# include <header.h>
+#endif
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ 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 of the License, 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#if 0
+# define HEADER 1
+#endif
+#if 1
+# undef HEADER
+# define HEADER 2
+void header_two_func (void) {}
+#endif
+#if 0
+/* #include "header.h" does not work, why? */
+# include <header.h>
+#endif
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ 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 of the License, 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* GCC cannot compile directly a .h file. */
+
+/* Use trailing "./header.h" to match the #include line in "one/header.h". */
+
+#include "../one/./header.h"
+
+int
+main (void)
+{
+ header_two_func ();
+ return 0;
+}
--- /dev/null
+# Copyright 2013 Free Software Foundation, Inc.
+
+# 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 of the License, 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+set opts {debug additional_flags=-I.}
+
+get_compiler_info
+if [test_compiler_info gcc*] {
+ lappend opts additional_flags=-g3
+}
+
+if { [file pathtype $objdir] == "relative" } {
+ untested "objdir $objdir should be absolute"
+ return
+}
+set saved_pwd [pwd]
+cd $srcdir/${subdir}/base/two
+set err [gdb_compile "../../${srcfile}" "${binfile}" executable $opts]
+cd $saved_pwd
+if { $err != "" } {
+ untested "compilation failed"
+ return -1
+}
+
+clean_restart ${testfile}
+
+# Test macros respect DW_AT_comp_dir.
+
+# "list header_two_func" does not set exactly the one line we want.
+if ![runto header_two_func] {
+ return -1
+}
+
+gdb_test "info macro HEADER" "\r\n#define HEADER 2"