/* 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, enum macro_kind kind, int argc, const char **argv, const char *replacement) { splay_tree_node n = find_definition (name, source, line); if (n) { struct macro_key *found_key = (struct macro_key *) n->key; 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) { 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_fullname, line, found_key_fullname, found_key->start_line); xfree (found_key_fullname); xfree (source_fullname); } return found_key; } else return 0; }
void macro_undef (struct macro_source_file *source, int line, const char *name) { splay_tree_node n = find_definition (name, source, line); if (n) { struct macro_key *key = (struct macro_key *) n->key; /* 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) { 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_fullname, line, key_fullname, key->end_line); xfree (key_fullname); xfree (source_fullname); } /* 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. */ #if 0 complaint (&symfile_complaints, _("no definition for macro `%s' in scope to #undef at %s:%d"), name, source->filename, line); #endif } }
struct macro_source_file * macro_include (struct macro_source_file *source, int line, const char *included) { struct macro_source_file *newobj; struct macro_source_file **link; /* Find the right position in SOURCE's `includes' list for the new 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 && (*link)->included_at_line < line; link = &(*link)->next_included) ; /* Did we find another file already #included at the same line as 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, because it can't tell which #inclusion came first. But GDB 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_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. */ while (*link && line == (*link)->included_at_line) { /* 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. */ newobj = new_source_file (source->table, included); newobj->included_by = source; newobj->included_at_line = line; newobj->next_included = *link; *link = newobj; return newobj; }
/* Outputs the include path of a macro starting at FILE and LINE to STREAM. Care should be taken that this function does not cause any lookups into the splay tree so that it can be safely used while iterating. */ static void show_pp_source_pos (struct ui_file *stream, struct macro_source_file *file, int line) { char *fullname; fullname = macro_source_fullname (file); fprintf_filtered (stream, "%s:%d\n", fullname, line); xfree (fullname); while (file->included_by) { 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; } }
/* 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; 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); return 0; }
struct macro_definition * macro_lookup_definition (struct macro_source_file *source, int line, const char *name) { splay_tree_node n = find_definition (name, source, line); if (n) { 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; }
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; 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. */ 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; }