/* C preprocessor macro tables for GDB.
   Copyright (C) 2002, 2007-2012 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 "gdb_obstack.h"
#include "splay-tree.h"
#include "filenames.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "macrotab.h"
#include "gdb_assert.h"
#include "bcache.h"
#include "complaints.h"
#include "macroexp.h"


/* The macro table structure.  */

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

  /* 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 bcache (addr, len, t->bcache);
  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 (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 = 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 = 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 *new;
  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.  */
      complaint (&symfile_complaints,
		 _("both `%s' and `%s' allegedly #included at %s:%d"),
		 included, (*link)->filename, source->filename, 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.  */
  new = new_source_file (source->table, included);
  new->included_by = source;
  new->included_at_line = line;
  new->next_included = *link;
  *link = new;

  return new;
}


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;

  /* The filename in the source structure is probably a full path, but
     NAME could be just the final component of the name.  */
  {
    int name_len = strlen (name);
    int src_name_len = strlen (source->filename);

    /* We do mean < here, and not <=; if the lengths are the same,
       then the filename_cmp above should have triggered, and we need to
       check for a slash here.  */
    if (name_len < src_name_len
        && IS_DIR_SEPARATOR (source->filename[src_name_len - name_len - 1])
        && filename_cmp (name,
			 source->filename + src_name_len - name_len) == 0)
      return source;
  }

  /* It's not us.  Try all our children, and return the lowest.  */
  {
    struct macro_source_file *child;
    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 = 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 = 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 = 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)
        {
	  complaint (&symfile_complaints,
		     _("macro `%s' redefined at %s:%d; "
		       "original definition at %s:%d"),
		     name, source->filename, line,
		     found_key->start_file->filename, found_key->start_line);
        }

      return found_key;
    }
  else
    return 0;
}

/* 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 kind)
{
  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, macro_object_like,
				0, 0,
				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, macro_object_like, kind, 0, replacement);
  splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
}

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)
{
  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, macro_function_like,
				argc, argv,
				replacement);

  /* See comments about duplicate keys in macro_define_object.  */
  if (k && ! key_compare (k, name, source, line))
    return;

  /* We should also check here that all the argument names in ARGV are
     distinct.  */

  k = new_macro_key (t, name, source, line);
  d = new_macro_definition (t, macro_function_like, argc, argv, replacement);
  splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
}


void
macro_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)
            {
              complaint (&symfile_complaints,
                         _("macro '%s' is #undefined twice,"
                           " at %s:%d and %s:%d"),
                         name,
                         source->filename, line,
                         key->end_file->filename, 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 (&symfile_complaints,
		 _("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 char *saved_expansion;

  if (saved_expansion)
    {
      xfree (saved_expansion);
      saved_expansion = NULL;
    }

  if (def->kind == macro_object_like)
    {
      if (def->argc == macro_FILE)
	{
	  saved_expansion = macro_stringify (filename);
	  def->replacement = saved_expansion;
	}
      else if (def->argc == macro_LINE)
	{
	  saved_expansion = xstrprintf ("%d", line);
	  def->replacement = saved_expansion;
	}
    }

  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)
    return fixup_definition (source->filename, 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
{
  macro_callback_fn fn;
  void *user_data;
  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
    = fixup_definition (key->start_file->filename, key->start_line,
			(struct macro_definition *) node->value);

  (*datum->fn) (key->name, def, key->start_file, key->start_line,
		datum->user_data);
  return 0;
}

/* Call FN for every macro in TABLE.  */
void
macro_for_each (struct macro_table *table, macro_callback_fn fn,
		void *user_data)
{
  struct macro_for_each_data datum;

  datum.fn = fn;
  datum.user_data = user_data;
  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
    = fixup_definition (datum->file->filename, 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,
		  datum->user_data);
  return 0;
}

/* Call FN for every macro is visible in SCOPE.  */
void
macro_for_each_in_scope (struct macro_source_file *file, int line,
			 macro_callback_fn fn, void *user_data)
{
  struct macro_for_each_data datum;

  datum.fn = fn;
  datum.user_data = user_data;
  datum.file = file;
  datum.line = line;
  splay_tree_foreach (file->table->definitions,
		      foreach_macro_in_scope, &datum);
}



/* Creating and freeing macro tables.  */


struct macro_table *
new_macro_table (struct obstack *obstack,
                 struct bcache *b)
{
  struct macro_table *t;

  /* First, get storage for the `struct macro_table' itself.  */
  if (obstack)
    t = obstack_alloc (obstack, sizeof (*t));
  else
    t = xmalloc (sizeof (*t));

  memset (t, 0, sizeof (*t));
  t->obstack = obstack;
  t->bcache = b;
  t->main_source = NULL;
  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);
}
