Use an accessor function for general_symbol_info::language
[deliverable/binutils-gdb.git] / gdb / block.c
index 3192b33e9e9c3c71e33b9b864784cd2fae01cf45..58441bfe8993c37a94cf26148bc9420eaafb0db6 100644 (file)
@@ -65,29 +65,28 @@ block_gdbarch (const struct block *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.  */
+/* See block.h.  */
 
-int
-contained_in (const struct block *a, const struct block *b)
+bool
+contained_in (const struct block *a, const struct block *b,
+             bool allow_nested)
 {
   if (!a || !b)
-    return 0;
+    return false;
 
   do
     {
       if (a == b)
-       return 1;
+       return true;
       /* If A is a function block, then A cannot be contained in B,
          except if A was inlined.  */
-      if (BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a))
-        return 0;
+      if (!allow_nested && BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a))
+        return false;
       a = BLOCK_SUPERBLOCK (a);
     }
   while (a != NULL);
 
-  return 0;
+  return false;
 }
 
 
@@ -131,16 +130,16 @@ block_inlined_p (const struct block *bl)
 /* A helper function that checks whether PC is in the blockvector BL.
    It returns the containing block if there is one, or else NULL.  */
 
-static struct block *
+static const struct block *
 find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
 {
-  struct block *b;
+  const struct block *b;
   int bot, top, half;
 
   /* If we have an addrmap mapping code addresses to blocks, then use
      that.  */
   if (BLOCKVECTOR_MAP (bl))
-    return (struct block *) addrmap_find (BLOCKVECTOR_MAP (bl), pc);
+    return (const struct block *) addrmap_find (BLOCKVECTOR_MAP (bl), pc);
 
   /* Otherwise, use binary search to find the last block that starts
      before PC.
@@ -186,7 +185,7 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
                         struct compunit_symtab *cust)
 {
   const struct blockvector *bl;
-  struct block *b;
+  const struct block *b;
 
   if (cust == NULL)
     {
@@ -243,7 +242,7 @@ call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
                     "DW_TAG_call_site %s in %s"),
                   paddress (gdbarch, pc),
                   (msym.minsym == NULL ? "???"
-                   : MSYMBOL_PRINT_NAME (msym.minsym)));
+                   : msym.minsym->print_name ()));
     }
 
   return (struct call_site *) *slot;
@@ -344,7 +343,7 @@ block_set_using (struct block *block,
 }
 
 /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
-   ititialize its members to zero.  */
+   initialize its members to zero.  */
 
 static void
 block_initialize_namespace (struct block *block, struct obstack *obstack)
@@ -658,6 +657,43 @@ block_iter_match_next (const lookup_name_info &name,
   return block_iter_match_step (iterator, name, 0);
 }
 
+/* Return true if symbol A is the best match possible for DOMAIN.  */
+
+static bool
+best_symbol (struct symbol *a, const domain_enum domain)
+{
+  return (SYMBOL_DOMAIN (a) == domain
+         && SYMBOL_CLASS (a) != LOC_UNRESOLVED);
+}
+
+/* Return symbol B if it is a better match than symbol A for DOMAIN.
+   Otherwise return A.  */
+
+static struct symbol *
+better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain)
+{
+  if (a == NULL)
+    return b;
+  if (b == NULL)
+    return a;
+
+  if (SYMBOL_DOMAIN (a) == domain
+      && SYMBOL_DOMAIN (b) != domain)
+    return a;
+  if (SYMBOL_DOMAIN (b) == domain
+      && SYMBOL_DOMAIN (a) != domain)
+    return b;
+
+  if (SYMBOL_CLASS (a) != LOC_UNRESOLVED
+      && SYMBOL_CLASS (b) == LOC_UNRESOLVED)
+    return a;
+  if (SYMBOL_CLASS (b) != LOC_UNRESOLVED
+      && SYMBOL_CLASS (a) == LOC_UNRESOLVED)
+    return b;
+
+  return a;
+}
+
 /* See block.h.
 
    Note that if NAME is the demangled form of a C++ symbol, we will fail
@@ -685,15 +721,17 @@ block_lookup_symbol (const struct block *block, const char *name,
 
       ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
        {
-         if (SYMBOL_DOMAIN (sym) == domain)
+         /* See comment related to PR gcc/debug/91507 in
+            block_lookup_symbol_primary.  */
+         if (best_symbol (sym, domain))
            return sym;
          /* This is a bit of a hack, but symbol_matches_domain might ignore
             STRUCT vs VAR domain symbols.  So if a matching symbol is found,
             make sure there is no "better" matching symbol, i.e., one with
             exactly the same domain.  PR 16253.  */
-         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+         if (symbol_matches_domain (sym->language (),
                                     SYMBOL_DOMAIN (sym), domain))
-           other = sym;
+           other = better_symbol (other, sym, domain);
        }
       return other;
     }
@@ -712,7 +750,7 @@ block_lookup_symbol (const struct block *block, const char *name,
 
       ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
        {
-         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+         if (symbol_matches_domain (sym->language (),
                                     SYMBOL_DOMAIN (sym), domain))
            {
              sym_found = sym;
@@ -747,16 +785,42 @@ block_lookup_symbol_primary (const struct block *block, const char *name,
        sym != NULL;
        sym = mdict_iter_match_next (lookup_name, &mdict_iter))
     {
-      if (SYMBOL_DOMAIN (sym) == domain)
+      /* With the fix for PR gcc/debug/91507, we get for:
+        ...
+        extern char *zzz[];
+        char *zzz[ ] = {
+          "abc",
+          "cde"
+        };
+        ...
+        DWARF which will result in two entries in the symbol table, a decl
+        with type char *[] and a def with type char *[2].
+
+        If we return the decl here, we don't get the value of zzz:
+        ...
+        $ gdb a.spec.out -batch -ex "p zzz"
+        $1 = 0x601030 <zzz>
+        ...
+        because we're returning the symbol without location information, and
+        because the fallback that uses the address from the minimal symbols
+        doesn't work either because the type of the decl does not specify a
+        size.
+
+        To fix this, we prefer def over decl in best_symbol and
+        better_symbol.
+
+        In absence of the gcc fix, both def and decl have type char *[], so
+        the only option to make this work is improve the fallback to use the
+        size of the minimal symbol.  Filed as PR exp/24989.  */
+      if (best_symbol (sym, domain))
        return sym;
 
       /* This is a bit of a hack, but symbol_matches_domain might ignore
         STRUCT vs VAR domain symbols.  So if a matching symbol is found,
         make sure there is no "better" matching symbol, i.e., one with
         exactly the same domain.  PR 16253.  */
-      if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-                                SYMBOL_DOMAIN (sym), domain))
-       other = sym;
+      if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain))
+       other = better_symbol (other, sym, domain);
     }
 
   return other;
@@ -782,8 +846,7 @@ block_find_symbol (const struct block *block, const char *name,
     {
       /* 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)
+      if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain)
          && matcher (sym, data))
        return sym;
     }
This page took 0.027316 seconds and 4 git commands to generate.