/* C preprocessor macro tables for GDB.
   Copyright (C) 2002-2026 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 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/>.  */

#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 "bcache.h"
#include "complaints.h"
#include "macroexp.h"


/* The macro table structure.  */

struct macro_table
{
  /* The obstack this table's data should be allocated in, or zero if
     we should use xmalloc.  */
  struct obstack *obstack;

  /* The bcache we should use to hold macro names, argument names, and
     definitions, or zero if we should use xmalloc.  */
  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
     an #undefinition in between), we sort the definitions by the
     order they would appear in the preprocessor's output.  That is,
     if `a.c' #includes `m.h' and then #includes `n.h', and both
     header files #define X (with an #undef somewhere in between),
     then the definition from `m.h' appears in our splay tree before
     the one from `n.h'.

     The splay tree's keys are `struct macro_key' pointers;
     the values are `struct macro_definition' pointers.

     The splay tree, its nodes, and the keys and values are allocated
     in obstack, if it's non-zero, or with xmalloc otherwise.  The
     macro names, argument names, argument name arrays, and definition
     strings are all allocated in bcache, if non-zero, or with xmalloc
     otherwise.  */
  splay_tree definitions;
};



/* Allocation and freeing functions.  */

/* Allocate SIZE bytes of memory appropriately for the macro table T.
   This just checks whether T has an obstack, or whether its pieces
   should be allocated with xmalloc.  */
static void *
macro_alloc (int size, struct macro_table *t)
{
  if (t->obstack)
    return obstack_alloc (t->obstack, size);
  else
    return xmalloc (size);
}


static void
macro_free (void *object, struct macro_table *t)
{
  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);
}


/* If the macro table T has a bcache, then cache the LEN bytes at ADDR
   there, and return the cached copy.  Otherwise, just xmalloc a copy
   of the bytes, and return a pointer to that.  */
template<typename U>
static const U *
macro_bcache (struct macro_table *t, const U *addr, int len)
{
  if (t->bcache)
    return t->bcache->insert (addr, len);
  else
    {
      void *copy = xmalloc (len);

      memcpy (copy, addr, len);
      return (const U *) copy;
    }
}


/* If the macro table T has a bcache, cache the null-terminated string
   S there, and return a pointer to the cached copy.  Otherwise,
   xmalloc a copy and return that.  */
static const char *
macro_bcache_str (struct macro_table *t, const char *s)
{
  return macro_bcache (t, s, strlen (s) + 1);
}


/* Free a possibly bcached object OBJ.  That is, if the macro table T
   has a bcache, do nothing; otherwise, xfree OBJ.  */
static void
macro_bcache_free (struct macro_table *t, void *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);
}



/* Macro tree keys, w/their comparison, allocation, and freeing functions.  */

/* A key in the splay tree.  */
struct macro_key
{
  /* The table we're in.  We only need this in order to free it, since
     the splay tree library's key and value freeing functions require
     that the key or value contain all the information needed to free
     themselves.  */
  struct macro_table *table;

  /* The name of the macro.  This is in the table's bcache, if it has
     one.  */
  const char *name;

  /* The source file and line number where the definition's scope
     begins.  This is also the line of the definition itself.  */
  struct macro_source_file *start_file;
  int start_line;

  /* The first source file and line after the definition's scope.
     (That is, the scope does not include this endpoint.)  If end_file
     is zero, then the definition extends to the end of the
     compilation unit.  */
  struct macro_source_file *end_file;
  int end_line;
};


/* Return the #inclusion depth of the source file FILE.  This is the
   number of #inclusions it took to reach this file.  For the main
   source file, the #inclusion depth is zero; for a file it #includes
   directly, the depth would be one; and so on.  */
static int
inclusion_depth (struct macro_source_file *file)
{
  int depth;

  for (depth = 0; file->included_by; depth++)
    file = file->included_by;

  return depth;
}


/* Compare two source locations (from the same compilation unit).
   This is part of the comparison function for the tree of
   definitions.

   LINE1 and LINE2 are line numbers in the source files FILE1 and
   FILE2.  Return a value:
   - less than zero if {LINE,FILE}1 comes before {LINE,FILE}2,
   - greater than zero if {LINE,FILE}1 comes after {LINE,FILE}2, or
   - zero if they are equal.

   When the two locations are in different source files --- perhaps
   one is in a header, while another is in the main source file --- we
   order them by where they would appear in the fully pre-processed
   sources, where all the #included files have been substituted into
   their places.  */
static int
compare_locations (struct macro_source_file *file1, int line1,
		   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
     include.  As we walk up the #inclusion tree toward the main
     source file, we update fileX and lineX as we go; includedX
     indicates whether the original position was from the #included
     file.  */
  int included1 = 0;
  int included2 = 0;

  /* If a file is zero, that means "end of compilation unit."  Handle
     that specially.  */
  if (! file1)
    {
      if (! file2)
	return 0;
      else
	return 1;
    }
  else if (! file2)
    return -1;

  /* If the two files are not the same, find their common ancestor in
     the #inclusion tree.  */
  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.  */
      int depth1 = inclusion_depth (file1);
      int depth2 = inclusion_depth (file2);

      /* Only one of these while loops will ever execute in any given
	 case.  */
      while (depth1 > depth2)
	{
	  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--;
	}

      /* Now both file1 and file2 are at the same depth.  Walk toward
	 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);
	}
    }

  /* 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.  */
      gdb_assert (! included1 || ! included2);

      /* Any #included position comes after a non-#included position
	 with the same line number in the #including file.  */
      if (included1)
	return 1;
      else if (included2)
	return -1;
      else
	return 0;
    }
  else
    return line1 - line2;
}


/* Compare a macro key KEY against NAME, the source file FILE, and
   line number LINE.

   Sort definitions by name; for two definitions with the same name,
   place the one whose definition comes earlier before the one whose
   definition comes later.

   Return -1, 0, or 1 if key comes before, is identical to, or comes
   after NAME, FILE, and LINE.  */
static int
key_compare (struct macro_key *key,
	     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);
}


/* The macro tree comparison function, typed for the splay tree
   library's happiness.  */
static int
macro_tree_compare (splay_tree_key untyped_key1,
		    splay_tree_key untyped_key2)
{
  struct macro_key *key1 = (struct macro_key *) untyped_key1;
  struct macro_key *key2 = (struct macro_key *) untyped_key2;

  return key_compare (key1, key2->name, key2->start_file, key2->start_line);
}


/* Construct a new macro key node for a macro in table T whose name is
   NAME, and whose scope starts at LINE in FILE; register the name in
   the bcache.  */
static struct macro_key *
new_macro_key (struct macro_table *t,
	       const char *name,
	       struct macro_source_file *file,
	       int line)
{
  struct macro_key *k = (struct macro_key *) macro_alloc (sizeof (*k), t);

  memset (k, 0, sizeof (*k));
  k->table = t;
  k->name = macro_bcache_str (t, name);
  k->start_file = file;
  k->start_line = line;
  k->end_file = 0;

  return k;
}


static void
macro_tree_delete_key (void *untyped_key)
{
  struct macro_key *key = (struct macro_key *) untyped_key;

  macro_bcache_free (key->table, (char *) key->name);
  macro_free (key, key->table);
}



/* Building and querying the tree of #included files.  */


/* Allocate and initialize a new source file structure.  */
static struct macro_source_file *
new_source_file (struct macro_table *t,
		 const char *filename)
{
  /* Get space for the source file structure itself.  */
  struct macro_source_file *f
    = (struct macro_source_file *) macro_alloc (sizeof (*f), t);

  memset (f, 0, sizeof (*f));
  f->table = t;
  f->filename = macro_bcache_str (t, filename);
  f->includes = 0;

  return f;
}


/* Free a source file, and all the source files it #included.  */
static void
free_macro_source_file (struct macro_source_file *src)
{
  struct macro_source_file *child, *next_child;

  /* Free this file's children.  */
  for (child = src->includes; child; child = next_child)
    {
      next_child = child->next_included;
      free_macro_source_file (child);
    }

  macro_bcache_free (src->table, (char *) src->filename);
  macro_free (src, src->table);
}


struct macro_source_file *
macro_set_main (struct macro_table *t,
		const char *filename)
{
  /* You can't change a table's main source file.  What would that do
     to the tree?  */
  gdb_assert (! t->main_source);

  t->main_source = new_source_file (t, filename);

  return t->main_source;
}


struct macro_source_file *
macro_main (struct macro_table *t)
{
  gdb_assert (t->main_source);

  return t->main_source;
}


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)
{
  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)
    {
      /* 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.  */

      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.  */
      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;
}


struct macro_source_file *
macro_lookup_inclusion (struct macro_source_file *source, const char *name)
{
  /* Is SOURCE itself named NAME?  */
  if (filename_cmp (name, source->filename) == 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 = NULL;
    int best_depth = 0;

    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;
	      }
	  }
      }

    return best;
  }
}



/* Registering and looking up macro definitions.  */


/* Construct a definition for a macro in table T.  Cache all strings,
   and the macro_definition structure itself, in T's bcache.  */
static macro_definition *
new_macro_definition (macro_table *t, macro_kind kind,
		      macro_special_kind special_kind,
		      const std::vector<std::string> &argv,
		      const char *replacement)
{
  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);

  if (kind == macro_function_like)
    {
      d->argc = argv.size ();

      /* Bcache all the arguments.  */
      if (d->argc > 0)
	{
	  std::vector<const char *> cached_argv;

	  for (const auto &arg : argv)
	    cached_argv.push_back (macro_bcache_str (t, arg.c_str ()));

	  /* Now bcache the array of argument pointers itself.  */
	  d->argv = macro_bcache (t, cached_argv.data (),
				  cached_argv.size () * sizeof (const char *));
	}
    }
  else
    d->argc = special_kind;

  /* We don't bcache the entire definition structure because it's got
     a pointer to the macro table in it; since each compilation unit
     has its own macro table, you'd only get bcache hits for identical
     definitions within a compilation unit, which seems unlikely.

     "So, why do macro definitions have pointers to their macro tables
     at all?"  Well, when the splay tree library wants to free a
     node's value, it calls the value freeing function with nothing
     but the value itself.  It makes the (apparently reasonable)
     assumption that the value carries enough information to free
     itself.  But not all macro tables have bcaches, so not all macro
     definitions would be bcached.  There's no way to tell whether a
     given definition is bcached without knowing which table the
     definition belongs to.  ...  blah.  The thing's only sixteen
     bytes anyway, and we can still bcache the name, args, and
     definition, so we just don't bother bcaching the definition
     structure itself.  */
  return d;
}


/* Free a macro definition.  */
static void
macro_tree_delete_value (void *untyped_definition)
{
  struct macro_definition *d = (struct macro_definition *) untyped_definition;
  struct macro_table *t = d->table;

  if (d->kind == macro_function_like)
    {
      int i;

      for (i = 0; i < d->argc; i++)
	macro_bcache_free (t, (char *) d->argv[i]);
      macro_bcache_free (t, (char **) d->argv);
    }

  macro_bcache_free (t, (char *) d->replacement);
  macro_free (d, t);
}


/* Find the splay tree node for the definition of NAME at LINE in
   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_table *t = file->table;
  splay_tree_node n;

  /* Construct a macro_key object, just for the query.  */
  struct macro_key query;

  query.name = name;
  query.start_file = file;
  query.start_line = line;
  query.end_file = NULL;

  n = splay_tree_lookup (t->definitions, (splay_tree_key) &query);
  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.  */
      splay_tree_node pred = splay_tree_predecessor (t->definitions,
						     (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 (streq (found->name, name))
	    n = pred;
	}
    }

  if (n)
    {
      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?  */
      if (compare_locations (file, line, found->end_file, found->end_line) < 0)
	return n;
      else
	return 0;
    }
  else
    return 0;
}


/* 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, ARGV, and REPLACEMENT, complain, too.
   Otherwise, return nullptr.  (ARGV is meaningless unless KIND
   is `macro_function_like'.)  */
static macro_key *
check_for_redefinition (macro_source_file *source, int line, const char *name,
			macro_kind kind, const std::vector<std::string> &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 (!streq (replacement, found_def->replacement))
	same = 0;
      else if (kind == macro_function_like)
	{
	  if (argv.size () != found_def->argc)
	    same = 0;
	  else
	    {
	      int i = 0;

	      for (const auto &arg : argv)
		if (arg != found_def->argv[i++])
		  same = 0;
	    }
	}

      if (! same)
	{
	  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;
    }
  else
    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 possible special kind is given by
   SPECIAL_KIND, and ARGV is meaningless.

   When KIND is macro_function_like, ARGV gives the macro argument names, and
   SPECIAL_KIND is meaningless.  */

static void
macro_define_internal (macro_source_file *source, int line, const char *name,
		       macro_kind kind, macro_special_kind special_kind,
		       const std::vector<std::string> &argv,
		       const char *replacement)
{
  struct macro_table *t = source->table;
  struct macro_key *k = NULL;
  struct macro_definition *d;

  if (! t->redef_ok)
    k = check_for_redefinition (source, line, name, kind, 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
     will try to delete the old definition.  When the definition is
     living on an obstack, this isn't a happy thing.

     Since this only happens in the presence of questionable debug
     info, we just ignore all definitions after the first.  The only
     case I know of where this arises is in GCC's output for
     predefined macros, and all the definitions are the same in that
     case.  */
  if (k && ! key_compare (k, name, source, line))
    return;

  k = new_macro_key (t, name, source, line);
  d = new_macro_definition (t, kind, special_kind, 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.  */

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)
{
  macro_define_internal (source, line, name, macro_object_like, special_kind,
			 {}, replacement);
}

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);
}

/* See macrotab.h.  */

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 (macro_source_file *source, int line, const char *name,
		       const std::vector<std::string> &argv,
		       const char *replacement)
{
  macro_define_internal (source, line, name, macro_function_like,
			 macro_ordinary, argv, replacement);
}

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)
	    {
	      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.  */
#if 0
      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<char> 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)
{
  splay_tree_node n = find_definition (name, source, line);

  if (n)
    {
      std::string source_fullname = macro_source_fullname (source);
      return fixup_definition (source_fullname.c_str (), line,
			       (struct macro_definition *) n->value);
    }
  else
    return 0;
}


struct macro_source_file *
macro_definition_location (struct macro_source_file *source,
			   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;
    }
  else
    return 0;
}


/* 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<macro_callback_fn> 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<macro_callback_fn> 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<macro_callback_fn> 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, gdb::bcache *b,
		 struct compunit_symtab *cust)
{
  struct macro_table *t;

  /* First, get storage for the `struct macro_table' itself.  */
  if (obstack)
    t = XOBNEW (obstack, struct macro_table);
  else
    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));

  return t;
}


void
free_macro_table (struct macro_table *table)
{
  /* Free the source file tree.  */
  free_macro_source_file (table->main_source);

  /* 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);
}
