X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fmacrotab.c;h=108e6f1bbaeddec35382e988d2920ae85a503a43;hb=387e00f3b3e6ea3719f144d7090c1a242174be4d;hp=5bc5b7327daf89772c77de93d7c05c8d6412ae16;hpb=72367fb45badc6ee3fe515b31348266310bff371;p=binutils-gdb.git diff --git a/gdb/macrotab.c b/gdb/macrotab.c index 5bc5b7327da..108e6f1bbae 100644 --- a/gdb/macrotab.c +++ b/gdb/macrotab.c @@ -1,12 +1,12 @@ /* C preprocessor macro tables for GDB. - Copyright 2002 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. Contributed by Red Hat, Inc. This file is part of GDB. 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 2 of the License, or + 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, @@ -15,20 +15,20 @@ 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, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" -#include "gdb_obstack.h" +#include "gdbsupport/gdb_obstack.h" +#include "gdbsupport/pathstuff.h" #include "splay-tree.h" +#include "filenames.h" #include "symtab.h" #include "symfile.h" #include "objfiles.h" #include "macrotab.h" -#include "gdb_assert.h" #include "bcache.h" #include "complaints.h" +#include "macroexp.h" /* The macro table structure. */ @@ -41,13 +41,20 @@ struct macro_table /* The bcache we should use to hold macro names, argument names, and definitions, or zero if we should use xmalloc. */ - struct bcache *bcache; + gdb::bcache *bcache; /* The main source file for this compilation unit --- the one whose name was given to the compiler. This is the root of the #inclusion tree; everything else is #included from here. */ struct macro_source_file *main_source; + /* Backlink to containing compilation unit, or NULL if there isn't one. */ + struct compunit_symtab *compunit_symtab; + + /* True if macros in this table can be redefined without issuing an + error. */ + int redef_ok; + /* The table of macro definitions. This is a splay tree (an ordered binary tree that stays balanced, effectively), sorted by macro name. Where a macro gets defined more than once (presumably with @@ -89,8 +96,14 @@ macro_alloc (int size, struct macro_table *t) static void macro_free (void *object, struct macro_table *t) { - gdb_assert (! t->obstack); - xfree (object); + if (t->obstack) + /* There are cases where we need to remove entries from a macro + table, even when reading debugging information. This should be + rare, and there's no easy way to free arbitrary data from an + obstack, so we just leak it. */ + ; + else + xfree (object); } @@ -101,10 +114,11 @@ static const void * macro_bcache (struct macro_table *t, const void *addr, int len) { if (t->bcache) - return bcache (addr, len, t->bcache); + return t->bcache->insert (addr, len); else { void *copy = xmalloc (len); + memcpy (copy, addr, len); return copy; } @@ -117,17 +131,23 @@ macro_bcache (struct macro_table *t, const void *addr, int len) static const char * macro_bcache_str (struct macro_table *t, const char *s) { - return (char *) macro_bcache (t, s, strlen (s) + 1); + return (const char *) macro_bcache (t, s, strlen (s) + 1); } /* Free a possibly bcached object OBJ. That is, if the macro table T - has a bcache, it's an error; otherwise, xfree OBJ. */ -void + has a bcache, do nothing; otherwise, xfree OBJ. */ +static void macro_bcache_free (struct macro_table *t, void *obj) { - gdb_assert (! t->bcache); - xfree (obj); + if (t->bcache) + /* There are cases where we need to remove entries from a macro + table, even when reading debugging information. This should be + rare, and there's no easy way to free data from a bcache, so we + just leak it. */ + ; + else + xfree (obj); } @@ -144,7 +164,7 @@ struct macro_key struct macro_table *table; /* The name of the macro. This is in the table's bcache, if it has - one. */ + one. */ const char *name; /* The source file and line number where the definition's scope @@ -194,7 +214,7 @@ inclusion_depth (struct macro_source_file *file) their places. */ static int compare_locations (struct macro_source_file *file1, int line1, - struct macro_source_file *file2, int line2) + struct macro_source_file *file2, int line2) { /* We want to treat positions in an #included file as coming *after* the line containing the #include, but *before* the line after the @@ -210,9 +230,9 @@ compare_locations (struct macro_source_file *file1, int line1, if (! file1) { if (! file2) - return 0; + return 0; else - return 1; + return 1; } else if (! file2) return -1; @@ -222,66 +242,66 @@ compare_locations (struct macro_source_file *file1, int line1, if (file1 != file2) { /* If one file is deeper than the other, walk up the #inclusion - chain until the two files are at least at the same *depth*. - Then, walk up both files in synchrony until they're the same - file. That file is the common ancestor. */ + chain until the two files are at least at the same *depth*. + Then, walk up both files in synchrony until they're the same + file. That file is the common ancestor. */ int depth1 = inclusion_depth (file1); int depth2 = inclusion_depth (file2); /* Only one of these while loops will ever execute in any given - case. */ + case. */ while (depth1 > depth2) - { - line1 = file1->included_at_line; - file1 = file1->included_by; - included1 = 1; - depth1--; - } + { + line1 = file1->included_at_line; + file1 = file1->included_by; + included1 = 1; + depth1--; + } while (depth2 > depth1) - { - line2 = file2->included_at_line; - file2 = file2->included_by; - included2 = 1; - depth2--; - } + { + line2 = file2->included_at_line; + file2 = file2->included_by; + included2 = 1; + depth2--; + } /* Now both file1 and file2 are at the same depth. Walk toward - the root of the tree until we find where the branches meet. */ + the root of the tree until we find where the branches meet. */ while (file1 != file2) - { - line1 = file1->included_at_line; - file1 = file1->included_by; - /* At this point, we know that the case the includedX flags - are trying to deal with won't come up, but we'll just - maintain them anyway. */ - included1 = 1; - - line2 = file2->included_at_line; - file2 = file2->included_by; - included2 = 1; - - /* Sanity check. If file1 and file2 are really from the - same compilation unit, then they should both be part of - the same tree, and this shouldn't happen. */ - gdb_assert (file1 && file2); - } + { + line1 = file1->included_at_line; + file1 = file1->included_by; + /* At this point, we know that the case the includedX flags + are trying to deal with won't come up, but we'll just + maintain them anyway. */ + included1 = 1; + + line2 = file2->included_at_line; + file2 = file2->included_by; + included2 = 1; + + /* Sanity check. If file1 and file2 are really from the + same compilation unit, then they should both be part of + the same tree, and this shouldn't happen. */ + gdb_assert (file1 && file2); + } } /* Now we've got two line numbers in the same file. */ if (line1 == line2) { /* They can't both be from #included files. Then we shouldn't - have walked up this far. */ + have walked up this far. */ gdb_assert (! included1 || ! included2); /* Any #included position comes after a non-#included position - with the same line number in the #including file. */ + with the same line number in the #including file. */ if (included1) - return 1; + return 1; else if (included2) - return -1; + return -1; else - return 0; + return 0; } else return line1 - line2; @@ -299,14 +319,15 @@ compare_locations (struct macro_source_file *file1, int line1, after NAME, FILE, and LINE. */ static int key_compare (struct macro_key *key, - const char *name, struct macro_source_file *file, int line) + const char *name, struct macro_source_file *file, int line) { int names = strcmp (key->name, name); + if (names) return names; return compare_locations (key->start_file, key->start_line, - file, line); + file, line); } @@ -314,7 +335,7 @@ key_compare (struct macro_key *key, library's happiness. */ static int macro_tree_compare (splay_tree_key untyped_key1, - splay_tree_key untyped_key2) + splay_tree_key untyped_key2) { struct macro_key *key1 = (struct macro_key *) untyped_key1; struct macro_key *key2 = (struct macro_key *) untyped_key2; @@ -328,11 +349,11 @@ macro_tree_compare (splay_tree_key untyped_key1, the bcache. */ static struct macro_key * new_macro_key (struct macro_table *t, - const char *name, - struct macro_source_file *file, - int line) + const char *name, + struct macro_source_file *file, + int line) { - struct macro_key *k = macro_alloc (sizeof (*k), t); + struct macro_key *k = (struct macro_key *) macro_alloc (sizeof (*k), t); memset (k, 0, sizeof (*k)); k->table = t; @@ -362,10 +383,11 @@ macro_tree_delete_key (void *untyped_key) /* Allocate and initialize a new source file structure. */ static struct macro_source_file * new_source_file (struct macro_table *t, - const char *filename) + const char *filename) { /* Get space for the source file structure itself. */ - struct macro_source_file *f = macro_alloc (sizeof (*f), t); + struct macro_source_file *f + = (struct macro_source_file *) macro_alloc (sizeof (*f), t); memset (f, 0, sizeof (*f)); f->table = t; @@ -396,7 +418,7 @@ free_macro_source_file (struct macro_source_file *src) struct macro_source_file * macro_set_main (struct macro_table *t, - const char *filename) + const char *filename) { /* You can't change a table's main source file. What would that do to the tree? */ @@ -417,20 +439,27 @@ macro_main (struct macro_table *t) } +void +macro_allow_redefinitions (struct macro_table *t) +{ + gdb_assert (! t->obstack); + t->redef_ok = 1; +} + + struct macro_source_file * macro_include (struct macro_source_file *source, - int line, - const char *included) + int line, + const char *included) { - struct macro_source_file *new; + struct macro_source_file *newobj; 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) ; @@ -439,39 +468,39 @@ macro_include (struct macro_source_file *source, if (*link && line == (*link)->included_at_line) { /* 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, - because it can't tell which #inclusion came first. But GDB - should tolerate bad debug info. So: + circa March 2002 did this.) It also means that the splay + tree ordering function, macro_tree_compare, will abort, + because it can't tell which #inclusion came first. But GDB + should tolerate bad debug info. So: - First, squawk. */ - static struct deprecated_complaint bogus_inclusion_line = { - "both `%s' and `%s' allegedly #included at %s:%d", 0, 0 - }; + First, squawk. */ - complain (&bogus_inclusion_line, - included, (*link)->filename, source->filename, line); + std::string link_fullname = macro_source_fullname (*link); + std::string source_fullname = macro_source_fullname (source); + complaint (_("both `%s' and `%s' allegedly #included at %s:%d"), + included, link_fullname.c_str (), source_fullname.c_str (), + line); /* Now, choose a new, unoccupied line number for this - #inclusion, after the alleged #inclusion line. */ + #inclusion, after the alleged #inclusion line. */ while (*link && line == (*link)->included_at_line) - { - /* This line number is taken, so try the next line. */ - line++; - link = &(*link)->next_included; - } + { + /* This line number is taken, so try the next line. */ + line++; + link = &(*link)->next_included; + } } /* At this point, we know that LINE is an unused line number, and *LINK points to the entry an #inclusion at that line should precede. */ - new = new_source_file (source->table, included); - new->included_by = source; - new->included_at_line = line; - new->next_included = *link; - *link = new; + newobj = new_source_file (source->table, included); + newobj->included_by = source; + newobj->included_at_line = line; + newobj->next_included = *link; + *link = newobj; - return new; + return newobj; } @@ -479,24 +508,9 @@ struct macro_source_file * macro_lookup_inclusion (struct macro_source_file *source, const char *name) { /* Is SOURCE itself named NAME? */ - if (strcmp (name, source->filename) == 0) + 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 strcmp above should have triggered, and we need to - 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) == 0) - return source; - } - /* It's not us. Try all our children, and return the lowest. */ { struct macro_source_file *child; @@ -505,19 +519,19 @@ macro_lookup_inclusion (struct macro_source_file *source, const char *name) for (child = source->includes; child; child = child->next_included) { - struct macro_source_file *result - = macro_lookup_inclusion (child, name); - - if (result) - { - int result_depth = inclusion_depth (result); - - if (! best || result_depth < best_depth) - { - best = result; - best_depth = result_depth; - } - } + struct macro_source_file *result + = macro_lookup_inclusion (child, name); + + if (result) + { + int result_depth = inclusion_depth (result); + + if (! best || result_depth < best_depth) + { + best = result; + best_depth = result_depth; + } + } } return best; @@ -533,16 +547,18 @@ macro_lookup_inclusion (struct macro_source_file *source, const char *name) and the macro_definition structure itself, in T's bcache. */ static struct macro_definition * new_macro_definition (struct macro_table *t, - enum macro_kind kind, - int argc, const char **argv, - const char *replacement) + enum macro_kind kind, + int argc, const char **argv, + const char *replacement) { - struct macro_definition *d = macro_alloc (sizeof (*d), t); + struct macro_definition *d + = (struct macro_definition *) macro_alloc (sizeof (*d), t); memset (d, 0, sizeof (*d)); d->table = t; d->kind = kind; d->replacement = macro_bcache_str (t, replacement); + d->argc = argc; if (kind == macro_function_like) { @@ -551,13 +567,13 @@ new_macro_definition (struct macro_table *t, int cached_argv_size = argc * sizeof (*cached_argv); /* Bcache all the arguments. */ - cached_argv = alloca (cached_argv_size); + cached_argv = (const char **) alloca (cached_argv_size); for (i = 0; i < argc; i++) - cached_argv[i] = macro_bcache_str (t, argv[i]); + cached_argv[i] = macro_bcache_str (t, argv[i]); /* Now bcache the array of argument pointers itself. */ - d->argv = macro_bcache (t, cached_argv, cached_argv_size); - d->argc = argc; + d->argv = ((const char * const *) + macro_bcache (t, cached_argv, cached_argv_size)); } /* We don't bcache the entire definition structure because it's got @@ -593,7 +609,7 @@ macro_tree_delete_value (void *untyped_definition) int i; for (i = 0; i < d->argc; i++) - macro_bcache_free (t, (char *) d->argv[i]); + macro_bcache_free (t, (char *) d->argv[i]); macro_bcache_free (t, (char **) d->argv); } @@ -606,8 +622,8 @@ macro_tree_delete_value (void *untyped_definition) SOURCE, or zero if there is none. */ static splay_tree_node find_definition (const char *name, - struct macro_source_file *file, - int line) + struct macro_source_file *file, + int line) { struct macro_table *t = file->table; splay_tree_node n; @@ -624,23 +640,23 @@ find_definition (const char *name, if (! n) { /* It's okay for us to do two queries like this: the real work - of the searching is done when we splay, and splaying the tree - a second time at the same key is a constant time operation. - If this still bugs you, you could always just extend the - splay tree library with a predecessor-or-equal operation, and - use that. */ + of the searching is done when we splay, and splaying the tree + a second time at the same key is a constant time operation. + If this still bugs you, you could always just extend the + splay tree library with a predecessor-or-equal operation, and + use that. */ splay_tree_node pred = splay_tree_predecessor (t->definitions, - (splay_tree_key) &query); + (splay_tree_key) &query); if (pred) - { - /* Make sure this predecessor actually has the right name. - 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) == 0) - n = pred; - } + { + /* Make sure this predecessor actually has the right name. + 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) == 0) + n = pred; + } } if (n) @@ -648,12 +664,12 @@ find_definition (const char *name, struct macro_key *found = (struct macro_key *) n->key; /* Okay, so this definition has the right name, and its scope - begins before the given source location. But does its scope - end after the given source location? */ + begins before the given source location. But does its scope + end after the given source location? */ if (compare_locations (file, line, found->end_file, found->end_line) < 0) - return n; + return n; else - return 0; + return 0; } else return 0; @@ -667,9 +683,9 @@ find_definition (const char *name, is `macro_function_like'.) */ static struct macro_key * check_for_redefinition (struct macro_source_file *source, int line, - const char *name, enum macro_kind kind, - int argc, const char **argv, - const char *replacement) + const char *name, enum macro_kind kind, + int argc, const char **argv, + const char *replacement) { splay_tree_node n = find_definition (name, source, line); @@ -677,46 +693,45 @@ check_for_redefinition (struct macro_source_file *source, int line, { struct macro_key *found_key = (struct macro_key *) n->key; struct macro_definition *found_def - = (struct macro_definition *) n->value; + = (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). */ + 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; + same = 0; else if (strcmp (replacement, found_def->replacement)) - same = 0; + 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 (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) - { - static struct deprecated_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); - } + { + std::string source_fullname = macro_source_fullname (source); + std::string found_key_fullname + = macro_source_fullname (found_key->start_file); + complaint (_("macro `%s' redefined at %s:%d; " + "original definition at %s:%d"), + name, source_fullname.c_str (), line, + found_key_fullname.c_str (), + found_key->start_line); + } return found_key; } @@ -724,19 +739,27 @@ check_for_redefinition (struct macro_source_file *source, int line, return 0; } +/* A helper function to define a new object-like or function-like macro + according to KIND. When KIND is macro_object_like, + the macro_special_kind must be provided as ARGC, and ARGV must be NULL. + When KIND is macro_function_like, ARGC and ARGV are giving the function + arguments. */ -void -macro_define_object (struct macro_source_file *source, int line, - const char *name, const char *replacement) +static void +macro_define_internal (struct macro_source_file *source, int line, + const char *name, enum macro_kind kind, + int argc, const char **argv, + const char *replacement) { struct macro_table *t = source->table; - struct macro_key *k; + struct macro_key *k = NULL; struct macro_definition *d; - k = check_for_redefinition (source, line, - name, macro_object_like, - 0, 0, - replacement); + if (! t->redef_ok) + k = check_for_redefinition (source, line, + name, kind, + argc, argv, + replacement); /* If we're redefining a symbol, and the existing key would be identical to our new key, then the splay_tree_insert function @@ -752,92 +775,145 @@ macro_define_object (struct macro_source_file *source, int line, return; k = new_macro_key (t, name, source, line); - d = new_macro_definition (t, macro_object_like, 0, 0, replacement); + d = new_macro_definition (t, kind, argc, argv, replacement); splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d); } +/* A helper function to define a new object-like macro. */ -void -macro_define_function (struct macro_source_file *source, int line, - const char *name, int argc, const char **argv, - const char *replacement) +static void +macro_define_object_internal (struct macro_source_file *source, int line, + const char *name, const char *replacement, + enum macro_special_kind special_kind) { - struct macro_table *t = source->table; - struct macro_key *k; - struct macro_definition *d; - - k = check_for_redefinition (source, line, - name, macro_function_like, - argc, argv, - replacement); + macro_define_internal (source, line, + name, macro_object_like, + special_kind, NULL, + replacement); +} - /* See comments about duplicate keys in macro_define_object. */ - if (k && ! key_compare (k, name, source, line)) - return; +void +macro_define_object (struct macro_source_file *source, int line, + const char *name, const char *replacement) +{ + macro_define_object_internal (source, line, name, replacement, + macro_ordinary); +} - /* We should also check here that all the argument names in ARGV are - distinct. */ +/* See macrotab.h. */ - k = new_macro_key (t, name, source, line); - d = new_macro_definition (t, macro_function_like, argc, argv, replacement); - splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d); +void +macro_define_special (struct macro_table *table) +{ + macro_define_object_internal (table->main_source, -1, "__FILE__", "", + macro_FILE); + macro_define_object_internal (table->main_source, -1, "__LINE__", "", + macro_LINE); } +void +macro_define_function (struct macro_source_file *source, int line, + const char *name, int argc, const char **argv, + const char *replacement) +{ + macro_define_internal (source, line, + name, macro_function_like, + argc, argv, + replacement); +} void macro_undef (struct macro_source_file *source, int line, - const char *name) + const char *name) { splay_tree_node n = find_definition (name, source, line); if (n) { - /* This function is the only place a macro's end-of-scope - location gets set to anything other than "end of the - compilation unit" (i.e., end_file is zero). So if this macro - already has its end-of-scope set, then we're probably seeing - a second #undefinition for the same #definition. */ struct macro_key *key = (struct macro_key *) n->key; - if (key->end_file) - { - static struct deprecated_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); - } - - /* Whatever the case, wipe out the old ending point, and - make this the ending point. */ - key->end_file = source; - key->end_line = line; + /* If we're removing a definition at exactly the same point that + we defined it, then just delete the entry altogether. GCC + 4.1.2 will generate DWARF that says to do this if you pass it + arguments like '-DFOO -UFOO -DFOO=2'. */ + if (source == key->start_file + && line == key->start_line) + splay_tree_remove (source->table->definitions, n->key); + + else + { + /* This function is the only place a macro's end-of-scope + location gets set to anything other than "end of the + compilation unit" (i.e., end_file is zero). So if this + macro already has its end-of-scope set, then we're + probably seeing a second #undefinition for the same + #definition. */ + if (key->end_file) + { + std::string source_fullname = macro_source_fullname (source); + std::string key_fullname = macro_source_fullname (key->end_file); + complaint (_("macro '%s' is #undefined twice," + " at %s:%d and %s:%d"), + name, source_fullname.c_str (), line, + key_fullname.c_str (), + key->end_line); + } + + /* Whether or not we've seen a prior #undefinition, wipe out + the old ending point, and make this the ending point. */ + key->end_file = source; + key->end_line = line; + } } else { /* According to the ISO C standard, an #undef for a symbol that - has no macro definition in scope is ignored. So we should - ignore it too. */ + has no macro definition in scope is ignored. So we should + ignore it too. */ #if 0 - static struct deprecated_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 (_("no definition for macro `%s' in scope to #undef at %s:%d"), + name, source->filename, line); #endif } } +/* A helper function that rewrites the definition of a special macro, + when needed. */ + +static struct macro_definition * +fixup_definition (const char *filename, int line, struct macro_definition *def) +{ + static gdb::unique_xmalloc_ptr saved_expansion; + + if (def->kind == macro_object_like) + { + if (def->argc == macro_FILE) + { + saved_expansion = macro_stringify (filename); + def->replacement = saved_expansion.get (); + } + else if (def->argc == macro_LINE) + { + saved_expansion = xstrprintf ("%d", line); + def->replacement = saved_expansion.get (); + } + } + + return def; +} struct macro_definition * macro_lookup_definition (struct macro_source_file *source, - int line, const char *name) + int line, const char *name) { splay_tree_node n = find_definition (name, source, line); if (n) - return (struct macro_definition *) n->value; + { + std::string source_fullname = macro_source_fullname (source); + return fixup_definition (source_fullname.c_str (), line, + (struct macro_definition *) n->value); + } else return 0; } @@ -845,15 +921,16 @@ macro_lookup_definition (struct macro_source_file *source, struct macro_source_file * macro_definition_location (struct macro_source_file *source, - int line, - const char *name, - int *definition_line) + int line, + const char *name, + int *definition_line) { splay_tree_node n = find_definition (name, source, line); if (n) { struct macro_key *key = (struct macro_key *) n->key; + *definition_line = key->start_line; return key->start_file; } @@ -862,33 +939,111 @@ macro_definition_location (struct macro_source_file *source, } +/* The type for callback data for iterating the splay tree in + macro_for_each and macro_for_each_in_scope. Only the latter uses + the FILE and LINE fields. */ +struct macro_for_each_data +{ + gdb::function_view fn; + struct macro_source_file *file; + int line; +}; + +/* Helper function for macro_for_each. */ +static int +foreach_macro (splay_tree_node node, void *arg) +{ + 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; + + std::string key_fullname = macro_source_fullname (key->start_file); + def = fixup_definition (key_fullname.c_str (), key->start_line, + (struct macro_definition *) node->value); + + datum->fn (key->name, def, key->start_file, key->start_line); + return 0; +} + +/* Call FN for every macro in TABLE. */ +void +macro_for_each (struct macro_table *table, + gdb::function_view fn) +{ + struct macro_for_each_data datum; + + datum.fn = fn; + datum.file = NULL; + datum.line = 0; + splay_tree_foreach (table->definitions, foreach_macro, &datum); +} + +static int +foreach_macro_in_scope (splay_tree_node node, void *info) +{ + 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; + + std::string datum_fullname = macro_source_fullname (datum->file); + def = fixup_definition (datum_fullname.c_str (), datum->line, + (struct macro_definition *) node->value); + + /* See if this macro is defined before the passed-in line, and + extends past that line. */ + if (compare_locations (key->start_file, key->start_line, + datum->file, datum->line) < 0 + && (!key->end_file + || compare_locations (key->end_file, key->end_line, + datum->file, datum->line) >= 0)) + datum->fn (key->name, def, key->start_file, key->start_line); + return 0; +} + +/* Call FN for every macro is visible in SCOPE. */ +void +macro_for_each_in_scope (struct macro_source_file *file, int line, + gdb::function_view fn) +{ + struct macro_for_each_data datum; + + datum.fn = fn; + datum.file = file; + datum.line = line; + splay_tree_foreach (file->table->definitions, + foreach_macro_in_scope, &datum); +} + + /* Creating and freeing macro tables. */ struct macro_table * -new_macro_table (struct obstack *obstack, - struct bcache *b) +new_macro_table (struct obstack *obstack, gdb::bcache *b, + struct compunit_symtab *cust) { struct macro_table *t; /* First, get storage for the `struct macro_table' itself. */ if (obstack) - t = obstack_alloc (obstack, sizeof (*t)); + t = XOBNEW (obstack, struct macro_table); else - t = xmalloc (sizeof (*t)); + t = XNEW (struct macro_table); memset (t, 0, sizeof (*t)); t->obstack = obstack; t->bcache = b; t->main_source = NULL; + t->compunit_symtab = cust; + t->redef_ok = 0; t->definitions = (splay_tree_new_with_allocator - (macro_tree_compare, - ((splay_tree_delete_key_fn) macro_tree_delete_key), - ((splay_tree_delete_value_fn) macro_tree_delete_value), - ((splay_tree_allocate_fn) macro_alloc), - ((splay_tree_deallocate_fn) macro_free), - t)); + (macro_tree_compare, + ((splay_tree_delete_key_fn) macro_tree_delete_key), + ((splay_tree_delete_value_fn) macro_tree_delete_value), + ((splay_tree_allocate_fn) macro_alloc), + ((splay_tree_deallocate_fn) macro_free), + t)); return t; } @@ -903,3 +1058,19 @@ free_macro_table (struct macro_table *table) /* Free the table of macro definitions. */ splay_tree_delete (table->definitions); } + +/* See macrotab.h for the comment. */ + +std::string +macro_source_fullname (struct macro_source_file *file) +{ + const char *comp_dir = NULL; + + if (file->table->compunit_symtab != NULL) + comp_dir = file->table->compunit_symtab->dirname (); + + if (comp_dir == NULL || IS_ABSOLUTE_PATH (file->filename)) + return file->filename; + + return path_join (comp_dir, file->filename); +}