Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / block.c
index e388d6933fe85bbf846a1652061ad2095420d120..417567268d757dd0b10dcc2588d18aa8689584ee 100644 (file)
@@ -1,6 +1,6 @@
 /* Block-related functions for the GNU debugger, GDB.
 
-   Copyright (C) 2003-2014 Free Software Foundation, Inc.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -25,7 +25,7 @@
 #include "cp-support.h"
 #include "addrmap.h"
 #include "gdbtypes.h"
-#include "exceptions.h"
+#include "objfiles.h"
 
 /* This is used by struct block to store namespace-related info for
    C++ files, namely using declarations and the current namespace in
@@ -40,6 +40,31 @@ struct block_namespace_info
 static void block_initialize_namespace (struct block *block,
                                        struct obstack *obstack);
 
+/* See block.h.  */
+
+struct objfile *
+block_objfile (const struct block *block)
+{
+  const struct global_block *global_block;
+
+  if (BLOCK_FUNCTION (block) != NULL)
+    return symbol_objfile (BLOCK_FUNCTION (block));
+
+  global_block = (struct global_block *) block_global_block (block);
+  return COMPUNIT_OBJFILE (global_block->compunit_symtab);
+}
+
+/* See block.  */
+
+struct gdbarch *
+block_gdbarch (const struct block *block)
+{
+  if (BLOCK_FUNCTION (block) != NULL)
+    return symbol_arch (BLOCK_FUNCTION (block));
+
+  return get_objfile_arch (block_objfile (block));
+}
+
 /* Return Nonzero if block a is lexically nested within block b,
    or if a and b have the same pc range.
    Return zero otherwise.  */
@@ -107,7 +132,7 @@ block_inlined_p (const struct block *bl)
    It returns the containing block if there is one, or else NULL.  */
 
 static struct block *
-find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc)
+find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
 {
   struct block *b;
   int bot, top, half;
@@ -155,22 +180,23 @@ find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc)
    is none.  PBLOCK is a pointer to the block.  If PBLOCK is NULL, we
    don't pass this information back to the caller.  */
 
-struct blockvector *
+const struct blockvector *
 blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
-                        const struct block **pblock, struct symtab *symtab)
+                        const struct block **pblock,
+                        struct compunit_symtab *cust)
 {
-  struct blockvector *bl;
+  const struct blockvector *bl;
   struct block *b;
 
-  if (symtab == 0)             /* if no symtab specified by caller */
+  if (cust == NULL)
     {
       /* First search all symtabs for one whose file contains our pc */
-      symtab = find_pc_sect_symtab (pc, section);
-      if (symtab == 0)
+      cust = find_pc_sect_compunit_symtab (pc, section);
+      if (cust == NULL)
        return 0;
     }
 
-  bl = BLOCKVECTOR (symtab);
+  bl = COMPUNIT_BLOCKVECTOR (cust);
 
   /* Then search that symtab for the smallest block that wins.  */
   b = find_block_in_blockvector (bl, pc);
@@ -185,7 +211,7 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
 /* Return true if the blockvector BV contains PC, false otherwise.  */
 
 int
-blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc)
+blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc)
 {
   return find_block_in_blockvector (bv, pc) != NULL;
 }
@@ -197,14 +223,14 @@ blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc)
 struct call_site *
 call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  struct symtab *symtab;
+  struct compunit_symtab *cust;
   void **slot = NULL;
 
   /* -1 as tail call PC can be already after the compilation unit range.  */
-  symtab = find_pc_symtab (pc - 1);
+  cust = find_pc_compunit_symtab (pc - 1);
 
-  if (symtab != NULL && symtab->call_site_htab != NULL)
-    slot = htab_find_slot (symtab->call_site_htab, &pc, NO_INSERT);
+  if (cust != NULL && COMPUNIT_CALL_SITE_HTAB (cust) != NULL)
+    slot = htab_find_slot (COMPUNIT_CALL_SITE_HTAB (cust), &pc, NO_INSERT);
 
   if (slot == NULL)
     {
@@ -227,7 +253,7 @@ call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
    containing the specified pc value, or 0 if there is none.
    Backward compatibility, no section.  */
 
-struct blockvector *
+const struct blockvector *
 blockvector_for_pc (CORE_ADDR pc, const struct block **pblock)
 {
   return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
@@ -240,7 +266,7 @@ blockvector_for_pc (CORE_ADDR pc, const struct block **pblock)
 const struct block *
 block_for_pc_sect (CORE_ADDR pc, struct obj_section *section)
 {
-  struct blockvector *bl;
+  const struct blockvector *bl;
   const struct block *b;
 
   bl = blockvector_for_pc_sect (pc, section, &b, NULL);
@@ -374,14 +400,7 @@ block_global_block (const struct block *block)
 struct block *
 allocate_block (struct obstack *obstack)
 {
-  struct block *bl = obstack_alloc (obstack, sizeof (struct block));
-
-  BLOCK_START (bl) = 0;
-  BLOCK_END (bl) = 0;
-  BLOCK_FUNCTION (bl) = NULL;
-  BLOCK_SUPERBLOCK (bl) = NULL;
-  BLOCK_DICT (bl) = NULL;
-  BLOCK_NAMESPACE (bl) = NULL;
+  struct block *bl = OBSTACK_ZALLOC (obstack, struct block);
 
   return bl;
 }
@@ -396,30 +415,30 @@ allocate_global_block (struct obstack *obstack)
   return &bl->block;
 }
 
-/* Set the symtab of the global block.  */
+/* Set the compunit of the global block.  */
 
 void
-set_block_symtab (struct block *block, struct symtab *symtab)
+set_block_compunit_symtab (struct block *block, struct compunit_symtab *cu)
 {
   struct global_block *gb;
 
   gdb_assert (BLOCK_SUPERBLOCK (block) == NULL);
   gb = (struct global_block *) block;
-  gdb_assert (gb->symtab == NULL);
-  gb->symtab = symtab;
+  gdb_assert (gb->compunit_symtab == NULL);
+  gb->compunit_symtab = cu;
 }
 
-/* Return the symtab of the global block.  */
+/* Return the compunit of the global block.  */
 
-static struct symtab *
-get_block_symtab (const struct block *block)
+static struct compunit_symtab *
+get_block_compunit_symtab (const struct block *block)
 {
   struct global_block *gb;
 
   gdb_assert (BLOCK_SUPERBLOCK (block) == NULL);
   gb = (struct global_block *) block;
-  gdb_assert (gb->symtab != NULL);
-  return gb->symtab;
+  gdb_assert (gb->compunit_symtab != NULL);
+  return gb->compunit_symtab;
 }
 
 \f
@@ -433,19 +452,19 @@ initialize_block_iterator (const struct block *block,
                           struct block_iterator *iter)
 {
   enum block_enum which;
-  struct symtab *symtab;
+  struct compunit_symtab *cu;
 
   iter->idx = -1;
 
   if (BLOCK_SUPERBLOCK (block) == NULL)
     {
       which = GLOBAL_BLOCK;
-      symtab = get_block_symtab (block);
+      cu = get_block_compunit_symtab (block);
     }
   else if (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
     {
       which = STATIC_BLOCK;
-      symtab = get_block_symtab (BLOCK_SUPERBLOCK (block));
+      cu = get_block_compunit_symtab (BLOCK_SUPERBLOCK (block));
     }
   else
     {
@@ -458,14 +477,14 @@ initialize_block_iterator (const struct block *block,
 
   /* If this is an included symtab, find the canonical includer and
      use it instead.  */
-  while (symtab->user != NULL)
-    symtab = symtab->user;
+  while (cu->user != NULL)
+    cu = cu->user;
 
   /* Putting this check here simplifies the logic of the iterator
      functions.  If there are no included symtabs, we only need to
      search a single block, so we might as well just do that
      directly.  */
-  if (symtab->includes == NULL)
+  if (cu->includes == NULL)
     {
       iter->d.block = block;
       /* A signal value meaning that we're iterating over a single
@@ -474,20 +493,20 @@ initialize_block_iterator (const struct block *block,
     }
   else
     {
-      iter->d.symtab = symtab;
+      iter->d.compunit_symtab = cu;
       iter->which = which;
     }
 }
 
-/* A helper function that finds the current symtab over whose static
+/* A helper function that finds the current compunit over whose static
    or global block we should iterate.  */
 
-static struct symtab *
-find_iterator_symtab (struct block_iterator *iterator)
+static struct compunit_symtab *
+find_iterator_compunit_symtab (struct block_iterator *iterator)
 {
   if (iterator->idx == -1)
-    return iterator->d.symtab;
-  return iterator->d.symtab->includes[iterator->idx];
+    return iterator->d.compunit_symtab;
+  return iterator->d.compunit_symtab->includes[iterator->idx];
 }
 
 /* Perform a single step for a plain block iterator, iterating across
@@ -505,14 +524,16 @@ block_iterator_step (struct block_iterator *iterator, int first)
     {
       if (first)
        {
-         struct symtab *symtab = find_iterator_symtab (iterator);
+         struct compunit_symtab *cust
+           = find_iterator_compunit_symtab (iterator);
          const struct block *block;
 
          /* Iteration is complete.  */
-         if (symtab == NULL)
+         if (cust == NULL)
            return  NULL;
 
-         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which);
+         block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
+                                    iterator->which);
          sym = dict_iterator_first (BLOCK_DICT (block), &iterator->dict_iter);
        }
       else
@@ -570,14 +591,16 @@ block_iter_name_step (struct block_iterator *iterator, const char *name,
     {
       if (first)
        {
-         struct symtab *symtab = find_iterator_symtab (iterator);
+         struct compunit_symtab *cust
+           = find_iterator_compunit_symtab (iterator);
          const struct block *block;
 
          /* Iteration is complete.  */
-         if (symtab == NULL)
+         if (cust == NULL)
            return  NULL;
 
-         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which);
+         block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
+                                    iterator->which);
          sym = dict_iter_name_first (BLOCK_DICT (block), name,
                                      &iterator->dict_iter);
        }
@@ -639,14 +662,16 @@ block_iter_match_step (struct block_iterator *iterator,
     {
       if (first)
        {
-         struct symtab *symtab = find_iterator_symtab (iterator);
+         struct compunit_symtab *cust
+           = find_iterator_compunit_symtab (iterator);
          const struct block *block;
 
          /* Iteration is complete.  */
-         if (symtab == NULL)
+         if (cust == NULL)
            return  NULL;
 
-         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which);
+         block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
+                                    iterator->which);
          sym = dict_iter_match_first (BLOCK_DICT (block), name,
                                       compare, &iterator->dict_iter);
        }
@@ -693,3 +718,82 @@ block_iter_match_next (const char *name,
 
   return block_iter_match_step (iterator, name, compare, 0);
 }
+
+/* See block.h.
+
+   Note that if NAME is the demangled form of a C++ symbol, we will fail
+   to find a match during the binary search of the non-encoded names, but
+   for now we don't worry about the slight inefficiency of looking for
+   a match we'll never find, since it will go pretty quick.  Once the
+   binary search terminates, we drop through and do a straight linear
+   search on the symbols.  Each symbol which is marked as being a ObjC/C++
+   symbol (language_cplus or language_objc set) has both the encoded and
+   non-encoded names tested for a match.  */
+
+struct symbol *
+block_lookup_symbol (const struct block *block, const char *name,
+                    const domain_enum domain)
+{
+  struct block_iterator iter;
+  struct symbol *sym;
+
+  if (!BLOCK_FUNCTION (block))
+    {
+      ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
+       {
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+                                    SYMBOL_DOMAIN (sym), domain))
+           return sym;
+       }
+      return NULL;
+    }
+  else
+    {
+      /* Note that parameter symbols do not always show up last in the
+        list; this loop makes sure to take anything else other than
+        parameter symbols first; it only uses parameter symbols as a
+        last resort.  Note that this only takes up extra computation
+        time on a match.  */
+
+      struct symbol *sym_found = NULL;
+
+      ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
+       {
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+                                    SYMBOL_DOMAIN (sym), domain))
+           {
+             sym_found = sym;
+             if (!SYMBOL_IS_ARGUMENT (sym))
+               {
+                 break;
+               }
+           }
+       }
+      return (sym_found);      /* Will be NULL if not found.  */
+    }
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_lookup_symbol_primary (const struct block *block, const char *name,
+                            const domain_enum domain)
+{
+  struct symbol *sym;
+  struct dict_iterator dict_iter;
+
+  /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK.  */
+  gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
+             || BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
+
+  for (sym = dict_iter_name_first (block->dict, name, &dict_iter);
+       sym != NULL;
+       sym = dict_iter_name_next (name, &dict_iter))
+    {
+      if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+                                SYMBOL_DOMAIN (sym), domain))
+       return sym;
+    }
+
+  return NULL;
+}
This page took 0.030309 seconds and 4 git commands to generate.