/* C preprocessor macro tables for GDB.
   Copyright (C) 2002-2024 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 (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, 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 (strcmp (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);
}
