Ejemplo n.º 1
0
struct symbol *
block_function (const struct block *bl)
{
  while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
    bl = BLOCK_SUPERBLOCK (bl);

  return BLOCK_FUNCTION (bl);
}
Ejemplo n.º 2
0
Archivo: block.c Proyecto: 5kg/gdb
struct symbol *
block_containing_function (const struct block *bl)
{
  while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
    bl = BLOCK_SUPERBLOCK (bl);

  return BLOCK_FUNCTION (bl);
}
Ejemplo n.º 3
0
Archivo: block.c Proyecto: 5kg/gdb
struct symbol *
block_linkage_function (const struct block *bl)
{
  while ((BLOCK_FUNCTION (bl) == NULL || block_inlined_p (bl))
	 && BLOCK_SUPERBLOCK (bl) != NULL)
    bl = BLOCK_SUPERBLOCK (bl);

  return BLOCK_FUNCTION (bl);
}
Ejemplo n.º 4
0
const struct block *
block_global_block(const struct block *block)
{
  if (block == NULL)
    return NULL;

  while (BLOCK_SUPERBLOCK(block) != NULL)
    block = BLOCK_SUPERBLOCK(block);

  return block;
}
Ejemplo n.º 5
0
const struct block *
block_static_block(const struct block *block)
{
  if ((block == NULL) || (BLOCK_SUPERBLOCK(block) == NULL))
    return NULL;

  while (BLOCK_SUPERBLOCK(BLOCK_SUPERBLOCK(block)) != NULL)
    block = BLOCK_SUPERBLOCK(block);

  return block;
}
Ejemplo n.º 6
0
struct symbol *
get_frame_function (struct frame_info *frame)
{
  struct block *bl = get_frame_block (frame, 0);

  if (bl == NULL)
    return NULL;

  while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
    bl = BLOCK_SUPERBLOCK (bl);

  return BLOCK_FUNCTION (bl);
}
Ejemplo n.º 7
0
static PyObject *
blpy_is_static (PyObject *self, void *closure)
{
  const struct block *block;

  BLPY_REQUIRE_VALID (self, block);

  if (BLOCK_SUPERBLOCK (block) != NULL
     && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}
Ejemplo n.º 8
0
char *
go_block_package_name (const struct block *block)
{
  while (block != NULL)
    {
      struct symbol *function = BLOCK_FUNCTION (block);

      if (function != NULL)
	{
	  char *package_name = go_symbol_package_name (function);

	  if (package_name != NULL)
	    return package_name;

	  /* Stop looking if we find a function without a package name.
	     We're most likely outside of Go and thus the concept of the
	     "current" package is gone.  */
	  return NULL;
	}

      block = BLOCK_SUPERBLOCK (block);
    }

  return NULL;
}
Ejemplo n.º 9
0
struct block *
get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
{
  CORE_ADDR pc;
  struct block *bl;
  int inline_count;

  if (!get_frame_address_in_block_if_available (frame, &pc))
    return NULL;

  if (addr_in_block)
    *addr_in_block = pc;

  bl = block_for_pc (pc);
  if (bl == NULL)
    return NULL;

  inline_count = frame_inlined_callees (frame);

  while (inline_count > 0)
    {
      if (block_inlined_p (bl))
	inline_count--;

      bl = BLOCK_SUPERBLOCK (bl);
      gdb_assert (bl != NULL);
    }

  return bl;
}
Ejemplo n.º 10
0
static struct block_symbol
d_lookup_symbol_module (const char *scope, const char *name,
			const struct block *block,
			const domain_enum domain)
{
  struct block_symbol sym;

  /* First, try to find the symbol in the given module.  */
  sym = d_lookup_symbol_in_module (scope, name,
				   block, domain, 1);
  if (sym.symbol != NULL)
    return sym;

  /* Search for name in modules imported to this and parent
     blocks.  */
  while (block != NULL)
    {
      sym = d_lookup_symbol_imports (scope, name, block, domain);

      if (sym.symbol != NULL)
	return sym;

      block = BLOCK_SUPERBLOCK (block);
    }

  return null_block_symbol;
}
Ejemplo n.º 11
0
const char *
block_scope (const struct block *block)
{
  for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
    {
      if (BLOCK_NAMESPACE (block) != NULL
	  && BLOCK_NAMESPACE (block)->scope != NULL)
	return BLOCK_NAMESPACE (block)->scope;
    }

  return "";
}
static PyObject *
blpy_get_superblock (PyObject *self, void *closure)
{
  struct block *block = NULL;
  struct block *super_block = NULL;
  block_object *self_obj  = (block_object *) self;

  BLPY_REQUIRE_VALID (self, block);

  super_block = BLOCK_SUPERBLOCK (block);
  if (super_block)
    return block_to_block_object (super_block, self_obj->objfile);

  Py_RETURN_NONE;
}
Ejemplo n.º 13
0
static PyObject *
blpy_get_static_block (PyObject *self, void *closure)
{
  const struct block *block;
  const struct block *static_block;
  block_object *self_obj  = (block_object *) self;

  BLPY_REQUIRE_VALID (self, block);

  if (BLOCK_SUPERBLOCK (block) == NULL)
    Py_RETURN_NONE;

  static_block = block_static_block (block);

  return block_to_block_object (static_block, self_obj->objfile);
}
Ejemplo n.º 14
0
int
contained_in (const struct block *a, const struct block *b)
{
  if (!a || !b)
    return 0;

  do
    {
      if (a == b)
	return 1;
      a = BLOCK_SUPERBLOCK (a);
    }
  while (a != NULL);

  return 0;
}
Ejemplo n.º 15
0
struct block *
allocate_block(struct obstack *obstack)
{
  struct block *bl = (struct block *)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;
  BLOCK_GCC_COMPILED(bl) = 0;
  /* APPLE LOCAL begin address ranges  */
  BLOCK_RANGES(bl) = NULL;
  /* APPLE LOCAL end address ranges  */

  return bl;
}
Ejemplo n.º 16
0
Archivo: block.c Proyecto: 5kg/gdb
int
contained_in (const struct block *a, const struct block *b)
{
  if (!a || !b)
    return 0;

  do
    {
      if (a == b)
	return 1;
      /* 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;
      a = BLOCK_SUPERBLOCK (a);
    }
  while (a != NULL);

  return 0;
}
Ejemplo n.º 17
0
struct blockvector *
blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
			 int *pindex, struct symtab *symtab)
{
  struct block *b;
  struct block *static_block;
  int bot, top, half;
  struct blockvector *bl;

  if (pindex)
    *pindex = 0;

  /* APPLE LOCAL begin cache lookup values for improved performance  */
  if ((pc == last_blockvector_lookup_pc)
      && (pc == last_mapped_section_lookup_pc)
      && (section == cached_mapped_section)
      && cached_blockvector && (pindex != NULL))
    {
      *pindex = cached_blockvector_index;
      return cached_blockvector;
    }

  last_blockvector_lookup_pc = pc;
  /* APPLE LOCAL end cache lookup values for improved performance  */

  if (symtab == 0)		/* if no symtab specified by caller */
    {
      /* First search all symtabs for one whose file contains our pc */
      symtab = find_pc_sect_symtab (pc, section);
      if (symtab == 0)
	/* APPLE LOCAL begin cache lookup values for improved performance  */
	{
	  cached_blockvector_index = -1;
	  cached_blockvector = NULL;
	  return 0;
	}
        /* APPLE LOCAL end cache lookup values for improved performance  */
    }

  bl = BLOCKVECTOR(symtab);
  static_block = BLOCKVECTOR_BLOCK(bl, STATIC_BLOCK);
  b = BLOCKVECTOR_BLOCK(bl, 0);
  gdb_assert(b != NULL);

  /* Then search that symtab for the smallest block that wins.  */
  /* Use binary search to find the last block that starts before PC.  */

  bot = 0;
  top = BLOCKVECTOR_NBLOCKS(bl);

  while (top - bot > 1)
    {
      half = (top - bot + 1) >> 1;
      b = BLOCKVECTOR_BLOCK(bl, (bot + half));
      /* APPLE LOCAL begin address ranges  */
      if (BLOCK_LOWEST_PC(b) <= pc)
      /* APPLE LOCAL end address ranges  */
	bot += half;
      else
	top = bot + half;
    }

  /* APPLE LOCAL We start with the block whose start/end address
     is higher than PC.  */

  /* Now search backward for a block that ends after PC.  */

  /* APPLE LOCAL: Stop at the first local block; i.e. don't iterate down
     to the global/static blocks.  */

  while (bot >= FIRST_LOCAL_BLOCK)
    {
      b = BLOCKVECTOR_BLOCK(bl, bot);
      /* APPLE LOCAL begin address ranges  */

      /* This condition is a little tricky.
         Given a function like
            func () {
               { subblock}
                // pc here
            }
	 BOT may be pointing to "subblock" and so the BOT block
	 start/end addrs are less than PC.  But we don't want to
	 terminate the search in this case - we need to keep iterating
         backwards to find "func"'s block.
         So I'm trying to restrict this to only quit searching if
         we're looking at a function's overall scope and both its
         highest/lowest addresses are lower than PC.  */
      if (BLOCK_SUPERBLOCK (b) == static_block
          && BLOCK_LOWEST_PC (b) < pc && BLOCK_HIGHEST_PC (b) < pc)
	/* APPLE LOCAL begin cache lookup values for improved performance  */
	{
	  cached_blockvector_index = -1;
	  cached_blockvector = NULL;
	  return 0;
	}
        /* APPLE LOCAL end cache lookup values for improved performance  */

      if (block_contains_pc(b, pc))
      /* APPLE LOCAL end address ranges  */
	{
	  if (pindex)
	    *pindex = bot;
	  /* APPLE LOCAL begom cache lookup values for improved
	     performance  */
	  cached_blockvector_index = bot;
	  cached_blockvector = bl;
	  /* APPLE LOCAL end cache lookup values for improved performance  */
	  return bl;
	}
      bot--;
    }
  /* APPLE LOCAL begin cache lookup values for improved performance  */
  cached_blockvector_index = -1;
  cached_blockvector = NULL;
  /* APPLE LOCAL end cache lookup values for improved performance  */
  return 0;
}
Ejemplo n.º 18
0
/* Print a list of the locals or the arguments for the currently
   selected frame.  If the argument passed is 0, printonly the names
   of the variables, if an argument of 1 is passed, print the values
   as well. */
static void
list_args_or_locals (int locals, int values, struct frame_info *fi)
{
  struct block *block;
  struct symbol *sym;
  struct dict_iterator iter;
  int nsyms;
  struct cleanup *cleanup_list;
  static struct ui_stream *stb = NULL;
  struct type *type;

  stb = ui_out_stream_new (uiout);

  block = get_frame_block (fi, 0);

  cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");

  while (block != 0)
    {
      ALL_BLOCK_SYMBOLS (block, iter, sym)
	{
          int print_me = 0;

	  switch (SYMBOL_CLASS (sym))
	    {
	    default:
	    case LOC_UNDEF:	/* catches errors        */
	    case LOC_CONST:	/* constant              */
	    case LOC_TYPEDEF:	/* local typedef         */
	    case LOC_LABEL:	/* local label           */
	    case LOC_BLOCK:	/* local function        */
	    case LOC_CONST_BYTES:	/* loc. byte seq.        */
	    case LOC_UNRESOLVED:	/* unresolved static     */
	    case LOC_OPTIMIZED_OUT:	/* optimized out         */
	      print_me = 0;
	      break;

	    case LOC_ARG:	/* argument              */
	    case LOC_REF_ARG:	/* reference arg         */
	    case LOC_REGPARM:	/* register arg          */
	    case LOC_REGPARM_ADDR:	/* indirect register arg */
	    case LOC_LOCAL_ARG:	/* stack arg             */
	    case LOC_BASEREG_ARG:	/* basereg arg           */
	    case LOC_COMPUTED_ARG:	/* arg with computed location */
	      if (!locals)
		print_me = 1;
	      break;

	    case LOC_LOCAL:	/* stack local           */
	    case LOC_BASEREG:	/* basereg local         */
	    case LOC_STATIC:	/* static                */
	    case LOC_REGISTER:	/* register              */
	    case LOC_COMPUTED:	/* computed location     */
	      if (locals)
		print_me = 1;
	      break;
	    }
	  if (print_me)
	    {
	      struct cleanup *cleanup_tuple = NULL;
	      struct symbol *sym2;
	      if (values != PRINT_NO_VALUES)
		cleanup_tuple =
		  make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	      ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));

	      if (!locals)
		sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
				      block, VAR_DOMAIN,
				      (int *) NULL,
				      (struct symtab **) NULL);
	      else
		    sym2 = sym;
	      switch (values)
		{
		case PRINT_SIMPLE_VALUES:
		  type = check_typedef (sym2->type);
		  type_print (sym2->type, "", stb->stream, -1);
		  ui_out_field_stream (uiout, "type", stb);
		  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
		      && TYPE_CODE (type) != TYPE_CODE_STRUCT
		      && TYPE_CODE (type) != TYPE_CODE_UNION)
		    {
		      print_variable_value (sym2, fi, stb->stream);
		      ui_out_field_stream (uiout, "value", stb);
		    }
		  do_cleanups (cleanup_tuple);
		  break;
		case PRINT_ALL_VALUES:
		  print_variable_value (sym2, fi, stb->stream);
		  ui_out_field_stream (uiout, "value", stb);
		  do_cleanups (cleanup_tuple);
		  break;
		}
	    }
	}
      if (BLOCK_FUNCTION (block))
	break;
      else
	block = BLOCK_SUPERBLOCK (block);
    }
Ejemplo n.º 19
0
static void
list_args_or_locals (enum what_to_list what, enum print_values values,
		     struct frame_info *fi, int skip_unavailable)
{
  const struct block *block;
  struct symbol *sym;
  struct block_iterator iter;
  struct cleanup *cleanup_list;
  struct type *type;
  char *name_of_result;
  struct ui_out *uiout = current_uiout;

  block = get_frame_block (fi, 0);

  switch (what)
    {
    case locals:
      name_of_result = "locals";
      break;
    case arguments:
      name_of_result = "args";
      break;
    case all:
      name_of_result = "variables";
      break;
    default:
      internal_error (__FILE__, __LINE__,
		      "unexpected what_to_list: %d", (int) what);
    }

  cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, name_of_result);

  while (block != 0)
    {
      ALL_BLOCK_SYMBOLS (block, iter, sym)
	{
          int print_me = 0;

	  switch (SYMBOL_CLASS (sym))
	    {
	    default:
	    case LOC_UNDEF:	/* catches errors        */
	    case LOC_CONST:	/* constant              */
	    case LOC_TYPEDEF:	/* local typedef         */
	    case LOC_LABEL:	/* local label           */
	    case LOC_BLOCK:	/* local function        */
	    case LOC_CONST_BYTES:	/* loc. byte seq.        */
	    case LOC_UNRESOLVED:	/* unresolved static     */
	    case LOC_OPTIMIZED_OUT:	/* optimized out         */
	      print_me = 0;
	      break;

	    case LOC_ARG:	/* argument              */
	    case LOC_REF_ARG:	/* reference arg         */
	    case LOC_REGPARM_ADDR:	/* indirect register arg */
	    case LOC_LOCAL:	/* stack local           */
	    case LOC_STATIC:	/* static                */
	    case LOC_REGISTER:	/* register              */
	    case LOC_COMPUTED:	/* computed location     */
	      if (what == all)
		print_me = 1;
	      else if (what == locals)
		print_me = !SYMBOL_IS_ARGUMENT (sym);
	      else
		print_me = SYMBOL_IS_ARGUMENT (sym);
	      break;
	    }
	  if (print_me)
	    {
	      struct symbol *sym2;
	      struct frame_arg arg, entryarg;

	      if (SYMBOL_IS_ARGUMENT (sym))
		sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
				      block, VAR_DOMAIN,
				      NULL);
	      else
		sym2 = sym;
	      gdb_assert (sym2 != NULL);

	      memset (&arg, 0, sizeof (arg));
	      arg.sym = sym2;
	      arg.entry_kind = print_entry_values_no;
	      memset (&entryarg, 0, sizeof (entryarg));
	      entryarg.sym = sym2;
	      entryarg.entry_kind = print_entry_values_no;

	      switch (values)
		{
		case PRINT_SIMPLE_VALUES:
		  type = check_typedef (sym2->type);
		  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
		      && TYPE_CODE (type) != TYPE_CODE_STRUCT
		      && TYPE_CODE (type) != TYPE_CODE_UNION)
		    {
		case PRINT_ALL_VALUES:
		  if (SYMBOL_IS_ARGUMENT (sym))
		    read_frame_arg (sym2, fi, &arg, &entryarg);
		  else
		    read_frame_local (sym2, fi, &arg);
		    }
		  break;
		}

	      if (arg.entry_kind != print_entry_values_only)
		list_arg_or_local (&arg, what, values, skip_unavailable);
	      if (entryarg.entry_kind != print_entry_values_no)
		list_arg_or_local (&entryarg, what, values, skip_unavailable);
	      xfree (arg.error);
	      xfree (entryarg.error);
	    }
	}

      if (BLOCK_FUNCTION (block))
	break;
      else
	block = BLOCK_SUPERBLOCK (block);
    }
Ejemplo n.º 20
0
static struct type *
get_out_value_type (struct symbol *func_sym, struct objfile *objfile,
		    enum compile_i_scope_types scope)
{
  struct symbol *gdb_ptr_type_sym;
  /* Initialize it just to avoid a GCC false warning.  */
  struct symbol *gdb_val_sym = NULL;
  struct type *gdb_ptr_type, *gdb_type_from_ptr, *gdb_type, *retval;
  /* Initialize it just to avoid a GCC false warning.  */
  const struct block *block = NULL;
  const struct blockvector *bv;
  int nblocks = 0;
  int block_loop = 0;

  bv = SYMTAB_BLOCKVECTOR (func_sym->owner.symtab);
  nblocks = BLOCKVECTOR_NBLOCKS (bv);

  gdb_ptr_type_sym = NULL;
  for (block_loop = 0; block_loop < nblocks; block_loop++)
    {
      struct symbol *function = NULL;
      const struct block *function_block;

      block = BLOCKVECTOR_BLOCK (bv, block_loop);
      if (BLOCK_FUNCTION (block) != NULL)
	continue;
      gdb_val_sym = block_lookup_symbol (block, COMPILE_I_EXPR_VAL, VAR_DOMAIN);
      if (gdb_val_sym == NULL)
	continue;

      function_block = block;
      while (function_block != BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)
	     && function_block != BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
	{
	  function_block = BLOCK_SUPERBLOCK (function_block);
	  function = BLOCK_FUNCTION (function_block);
	  if (function != NULL)
	    break;
	}
      if (function != NULL
	  && (BLOCK_SUPERBLOCK (function_block)
	      == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))
	  && (strcmp (SYMBOL_LINKAGE_NAME (function), GCC_FE_WRAPPER_FUNCTION)
	      == 0))
	break;
    }
  if (block_loop == nblocks)
    error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE);

  gdb_type = SYMBOL_TYPE (gdb_val_sym);
  gdb_type = check_typedef (gdb_type);

  gdb_ptr_type_sym = block_lookup_symbol (block, COMPILE_I_EXPR_PTR_TYPE,
					  VAR_DOMAIN);
  if (gdb_ptr_type_sym == NULL)
    error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE);
  gdb_ptr_type = SYMBOL_TYPE (gdb_ptr_type_sym);
  gdb_ptr_type = check_typedef (gdb_ptr_type);
  if (TYPE_CODE (gdb_ptr_type) != TYPE_CODE_PTR)
    error (_("Type of \"%s\" is not a pointer"), COMPILE_I_EXPR_PTR_TYPE);
  gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_ptr_type);

  if (types_deeply_equal (gdb_type, gdb_type_from_ptr))
    {
      if (scope != COMPILE_I_PRINT_ADDRESS_SCOPE)
	error (_("Expected address scope in compiled module \"%s\"."),
	       objfile_name (objfile));
      return gdb_type;
    }

  if (TYPE_CODE (gdb_type) != TYPE_CODE_PTR)
    error (_("Invalid type code %d of symbol \"%s\" "
	     "in compiled module \"%s\"."),
	   TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_VAL,
	   objfile_name (objfile));
  
  retval = gdb_type_from_ptr;
  switch (TYPE_CODE (gdb_type_from_ptr))
    {
    case TYPE_CODE_ARRAY:
      gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_type_from_ptr);
      break;
    case TYPE_CODE_FUNC:
      break;
    default:
      error (_("Invalid type code %d of symbol \"%s\" "
	       "in compiled module \"%s\"."),
	     TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_PTR_TYPE,
	     objfile_name (objfile));
    }
  if (!types_deeply_equal (gdb_type_from_ptr,
			   TYPE_TARGET_TYPE (gdb_type)))
    error (_("Referenced types do not match for symbols \"%s\" and \"%s\" "
	     "in compiled module \"%s\"."),
	   COMPILE_I_EXPR_PTR_TYPE, COMPILE_I_EXPR_VAL,
	   objfile_name (objfile));
  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE)
    return NULL;
  return retval;
}
Ejemplo n.º 21
0
struct block_symbol
cp_lookup_symbol_imports_or_template (const char *scope,
				      const char *name,
				      const struct block *block,
				      const domain_enum domain)
{
  struct symbol *function = BLOCK_FUNCTION (block);
  struct block_symbol result;

  if (symbol_lookup_debug)
    {
      fprintf_unfiltered (gdb_stdlog,
			  "cp_lookup_symbol_imports_or_template"
			  " (%s, %s, %s, %s)\n",
			  scope, name, host_address_to_string (block),
			  domain_name (domain));
    }

  if (function != NULL && SYMBOL_LANGUAGE (function) == language_cplus)
    {
      /* Search the function's template parameters.  */
      if (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (function))
	{
	  struct template_symbol *templ
	    = (struct template_symbol *) function;
	  struct symbol *sym = search_symbol_list (name,
						   templ->n_template_arguments,
						   templ->template_arguments);

	  if (sym != NULL)
	    {
	      if (symbol_lookup_debug)
		{
		  fprintf_unfiltered (gdb_stdlog,
				      "cp_lookup_symbol_imports_or_template"
				      " (...) = %s\n",
				      host_address_to_string (sym));
		}
	      return (struct block_symbol) {sym, block};
	    }
	}

      /* Search the template parameters of the function's defining
	 context.  */
      if (SYMBOL_NATURAL_NAME (function))
	{
	  struct type *context;
	  char *name_copy = xstrdup (SYMBOL_NATURAL_NAME (function));
	  struct cleanup *cleanups = make_cleanup (xfree, name_copy);
	  const struct language_defn *lang = language_def (language_cplus);
	  struct gdbarch *arch = symbol_arch (function);
	  const struct block *parent = BLOCK_SUPERBLOCK (block);
	  struct symbol *sym;

	  while (1)
	    {
	      unsigned int prefix_len = cp_entire_prefix_len (name_copy);

	      if (prefix_len == 0)
		context = NULL;
	      else
		{
		  name_copy[prefix_len] = '\0';
		  context = lookup_typename (lang, arch,
					     name_copy,
					     parent, 1);
		}

	      if (context == NULL)
		break;

	      sym
		= search_symbol_list (name,
				      TYPE_N_TEMPLATE_ARGUMENTS (context),
				      TYPE_TEMPLATE_ARGUMENTS (context));
	      if (sym != NULL)
		{
		  do_cleanups (cleanups);
		  if (symbol_lookup_debug)
		    {
		      fprintf_unfiltered
			(gdb_stdlog,
			 "cp_lookup_symbol_imports_or_template (...) = %s\n",
			 host_address_to_string (sym));
		    }
		  return (struct block_symbol) {sym, parent};
		}
	    }

	  do_cleanups (cleanups);
	}
    }