/* C preprocessor macro tables for GDB.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2007 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "splay-tree.h"
#include "symtab.h"
#include "symfile.h"
/* Free a possibly bcached object OBJ. That is, if the macro table T
has a bcache, it's an error; otherwise, xfree OBJ. */
-void
+static void
macro_bcache_free (struct macro_table *t, void *obj)
{
gdb_assert (! t->bcache);
struct macro_source_file **link;
/* Find the right position in SOURCE's `includes' list for the new
- file. Scan until we find the first file we shouldn't follow ---
- which is therefore the file we should directly precede --- or
- reach the end of the list. */
+ file. Skip inclusions at earlier lines, until we find one at the
+ same line or later --- or until the end of the list. */
for (link = &source->includes;
- *link && line < (*link)->included_at_line;
+ *link && (*link)->included_at_line < line;
link = &(*link)->next_included)
;
should tolerate bad debug info. So:
First, squawk. */
- static struct complaint bogus_inclusion_line = {
- "both `%s' and `%s' allegedly #included at %s:%d", 0, 0
- };
-
- complain (&bogus_inclusion_line,
- included, (*link)->filename, source->filename, line);
+ complaint (&symfile_complaints,
+ _("both `%s' and `%s' allegedly #included at %s:%d"), included,
+ (*link)->filename, source->filename, line);
/* Now, choose a new, unoccupied line number for this
#inclusion, after the alleged #inclusion line. */
macro_lookup_inclusion (struct macro_source_file *source, const char *name)
{
/* Is SOURCE itself named NAME? */
- if (! strcmp (name, source->filename))
+ if (strcmp (name, source->filename) == 0)
return source;
/* The filename in the source structure is probably a full path, but
check for a slash here. */
if (name_len < src_name_len
&& source->filename[src_name_len - name_len - 1] == '/'
- && ! strcmp (name, source->filename + src_name_len - name_len))
+ && strcmp (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;
- struct macro_source_file *best = 0;
- int best_depth;
+ struct macro_source_file *best = NULL;
+ int best_depth = 0;
for (child = source->includes; child; child = child->next_included)
{
query.name = name;
query.start_file = file;
query.start_line = line;
- query.end_file = 0;
+ query.end_file = NULL;
n = splay_tree_lookup (t->definitions, (splay_tree_key) &query);
if (! n)
We just want to search within a given name's definitions. */
struct macro_key *found = (struct macro_key *) pred->key;
- if (! strcmp (found->name, name))
+ if (strcmp (found->name, name) == 0)
n = pred;
}
}
}
-/* If NAME already has a definition in scope at LINE in FILE, and
- return the key. Otherwise, return zero. */
+/* If NAME already has a definition in scope at LINE in SOURCE, return
+ the key. If the old definition is different from the definition
+ given by KIND, ARGC, ARGV, and REPLACEMENT, complain, too.
+ Otherwise, return zero. (ARGC and ARGV are meaningless unless KIND
+ is `macro_function_like'.) */
static struct macro_key *
check_for_redefinition (struct macro_source_file *source, int line,
- const char *name)
+ const char *name, enum macro_kind kind,
+ int argc, const char **argv,
+ const char *replacement)
{
splay_tree_node n = find_definition (name, source, line);
- /* This isn't really right. There's nothing wrong with redefining a
- macro if the new replacement list is the same as the old one. */
if (n)
{
struct macro_key *found_key = (struct macro_key *) n->key;
- static struct complaint macro_redefined = {
- "macro `%s' redefined at %s:%d;"
- "original definition at %s:%d", 0, 0
- };
- complain (¯o_redefined, name,
- source->filename, line,
- found_key->start_file->filename,
- found_key->start_line);
+ struct macro_definition *found_def
+ = (struct macro_definition *) n->value;
+ int same = 1;
+
+ /* Is this definition the same as the existing one?
+ According to the standard, this comparison needs to be done
+ on lists of tokens, not byte-by-byte, as we do here. But
+ that's too hard for us at the moment, and comparing
+ byte-by-byte will only yield false negatives (i.e., extra
+ warning messages), not false positives (i.e., unnoticed
+ definition changes). */
+ if (kind != found_def->kind)
+ same = 0;
+ else if (strcmp (replacement, found_def->replacement))
+ same = 0;
+ else if (kind == macro_function_like)
+ {
+ if (argc != found_def->argc)
+ same = 0;
+ else
+ {
+ int i;
+
+ for (i = 0; i < argc; i++)
+ if (strcmp (argv[i], found_def->argv[i]))
+ same = 0;
+ }
+ }
+
+ if (! same)
+ {
+ 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);
+ }
+
return found_key;
}
else
struct macro_key *k;
struct macro_definition *d;
- k = check_for_redefinition (source, line, name);
+ k = check_for_redefinition (source, line,
+ name, macro_object_like,
+ 0, 0,
+ replacement);
/* If we're redefining a symbol, and the existing key would be
identical to our new key, then the splay_tree_insert function
struct macro_key *k;
struct macro_definition *d;
- k = check_for_redefinition (source, line, name);
+ k = check_for_redefinition (source, line,
+ name, macro_function_like,
+ argc, argv,
+ replacement);
/* See comments about duplicate keys in macro_define_object. */
if (k && ! key_compare (k, name, source, line))
if (key->end_file)
{
- static struct complaint double_undef = {
- "macro '%s' is #undefined twice, at %s:%d and %s:%d",
- 0, 0
- };
- complain (&double_undef, name, source->filename, line,
- key->end_file->filename, key->end_line);
+ 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);
}
/* Whatever the case, wipe out the old ending point, and
has no macro definition in scope is ignored. So we should
ignore it too. */
#if 0
- static struct complaint no_macro_to_undefine = {
- "no definition for macro `%s' in scope to #undef at %s:%d",
- 0, 0
- };
- complain (&no_macro_to_undefine, name, source->filename, line);
+ complaint (&symfile_complaints,
+ _("no definition for macro `%s' in scope to #undef at %s:%d"),
+ name, source->filename, line);
#endif
}
}
memset (t, 0, sizeof (*t));
t->obstack = obstack;
t->bcache = b;
- t->main_source = 0;
+ t->main_source = NULL;
t->definitions = (splay_tree_new_with_allocator
(macro_tree_compare,
((splay_tree_delete_key_fn) macro_tree_delete_key),