sim: trace: add set of system helpers
[deliverable/binutils-gdb.git] / gdb / block.c
index a4b9ef550ba107364662d6b50a3f199123cb90e2..79a8f195db80602d65fee17ef44dcc331707215a 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
 struct block_namespace_info
 {
   const char *scope;
-  struct using_direct *using;
+  struct using_direct *using_decl;
 };
 
 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.  */
@@ -157,20 +182,21 @@ find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
 
 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)
 {
   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);
@@ -197,14 +223,14 @@ blockvector_contains_pc (const 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)
     {
@@ -300,7 +326,7 @@ block_using (const struct block *block)
   if (block == NULL || BLOCK_NAMESPACE (block) == NULL)
     return NULL;
   else
-    return BLOCK_NAMESPACE (block)->using;
+    return BLOCK_NAMESPACE (block)->using_decl;
 }
 
 /* Set BLOCK's using member to USING; if needed, allocate memory via
@@ -309,12 +335,12 @@ block_using (const struct block *block)
 
 void
 block_set_using (struct block *block,
-                struct using_direct *using,
+                struct using_direct *using_decl,
                 struct obstack *obstack)
 {
   block_initialize_namespace (block, obstack);
 
-  BLOCK_NAMESPACE (block)->using = using;
+  BLOCK_NAMESPACE (block)->using_decl = using_decl;
 }
 
 /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
@@ -328,7 +354,7 @@ block_initialize_namespace (struct block *block, struct obstack *obstack)
       BLOCK_NAMESPACE (block)
        = obstack_alloc (obstack, sizeof (struct block_namespace_info));
       BLOCK_NAMESPACE (block)->scope = NULL;
-      BLOCK_NAMESPACE (block)->using = NULL;
+      BLOCK_NAMESPACE (block)->using_decl = 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,129 @@ 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;
+}
+
+/* See block.h.  */
+
+struct symbol *
+block_find_symbol (const struct block *block, const char *name,
+                  const domain_enum domain,
+                  block_symbol_matcher_ftype *matcher, void *data)
+{
+  struct block_iterator iter;
+  struct symbol *sym;
+
+  /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK.  */
+  gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
+             || BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
+
+  ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
+    {
+      /* MATCHER is deliberately called second here so that it never sees
+        a non-domain-matching symbol.  */
+      if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+                                SYMBOL_DOMAIN (sym), domain)
+         && matcher (sym, data))
+       return sym;
+    }
+  return NULL;
+}
+
+/* See block.h.  */
+
+int
+block_find_non_opaque_type (struct symbol *sym, void *data)
+{
+  return !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym));
+}
+
+/* See block.h.  */
+
+int
+block_find_non_opaque_type_preferred (struct symbol *sym, void *data)
+{
+  struct symbol **best = data;
+
+  if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+    return 1;
+  *best = sym;
+  return 0;
+}
This page took 0.029824 seconds and 4 git commands to generate.