/* C preprocessor macro tables for GDB.
   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 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 "defs.h"
#include "gdbsupport/gdb_obstack.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.  */
static const void *
macro_bcache (struct macro_table *t, const void *addr, int len)
{
  if (t->bcache)
    return t->bcache->insert (addr, len);
  else
    {
      void *copy = xmalloc (len);

      memcpy (copy, addr, len);
      return 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 (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, 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 struct macro_definition *
new_macro_definition (struct macro_table *t,
		      enum macro_kind kind,
		      int argc, const char **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);
  d->argc = argc;

  if (kind == macro_function_like)
    {
      int i;
      const char **cached_argv;
      int cached_argv_size = argc * sizeof (*cached_argv);

      /* Bcache all the arguments.  */
      cached_argv = (const char **) alloca (cached_argv_size);
      for (i = 0; i < argc; i++)
	cached_argv[i] = macro_bcache_str (t, argv[i]);

      /* Now bcache the array of argument pointers itself.  */
      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
     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 (strcmp (found->name, name) == 0)
	    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, 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)
	{
	  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 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.  */

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 = NULL;
  struct macro_definition *d;

  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
     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, 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.  */

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, NULL,
			 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 (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)
{
  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 std::string (comp_dir) + SLASH_STRING + file->filename;
}
