if (SYMBOL_NAMESPACE (*top) == namespace)
if (SYMBOL_DOMAIN (*top) == domain)
lookup_partial_symbol PARAMS ((struct partial_symtab *, const char *,			       int, namespace_enum));static struct symtab *lookup_symtab_1 PARAMS ((char *));static voidcplusplus_hint PARAMS ((char *));/* *//* The single non-language-specific builtin type */struct type *builtin_type_error;/* Block in which the most recently searched-for symbol was found.   Might be better to make this a parameter to lookup_symbol and    value_of_this. */const struct block *block_found;char no_symtab_msg[] = "No symbol table is loaded.  Use the \"file\" command.";/* While the C++ support is still in flux, issue a possibly helpful hint on   using the new command completion feature on single quoted demangled C++   symbols.  Remove when loose ends are cleaned up.   FIXME -fnf */static voidcplusplus_hint (name)     char *name;{  while (*name == '\'')    name++;  printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);  printf_filtered ("(Note leading single quote.)\n");}/* Check for a symtab of a specific name; first in symtabs, then in   psymtabs.  *If* there is no '/' in the name, a match after a '/'   in the symtab filename will also work.  */static struct symtab *lookup_symtab_1 (name)     char *name;{  register struct symtab *s;  register struct partial_symtab *ps;  register char *slash;  register struct objfile *objfile; got_symtab:  /* First, search for an exact match */  ALL_SYMTABS (objfile, s)    if (STREQ (name, s->filename))      return s;  slash = strchr (name, '/');  /* Now, search for a matching tail (only if name doesn't have any dirs) */  if (!slash)    ALL_SYMTABS (objfile, s)      {	char *p = s -> filename;	char *tail = strrchr (p, '/');	if (tail)	  p = tail + 1;	if (STREQ (p, name))	  return s;      }  /* Same search rules as above apply here, but now we look thru the     psymtabs.  */  ps = lookup_partial_symtab (name);  if (!ps)    return (NULL);  if (ps -> readin)    error ("Internal: readin %s pst for `%s' found when no symtab found.",	   ps -> filename, name);  s = PSYMTAB_TO_SYMTAB (ps);  if (s)    return s;  /* At this point, we have located the psymtab for this file, but     the conversion to a symtab has failed.  This usually happens     when we are looking up an include file.  In this case,     PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has     been created.  So, we need to run through the symtabs again in     order to find the file.     XXX - This is a crock, and should be fixed inside of the the     symbol parsing routines. */  goto got_symtab;}/* Lookup the symbol table of a source file named NAME.  Try a couple   of variations if the first lookup doesn't work.  */struct symtab *lookup_symtab (name)     char *name;{  register struct symtab *s;#if 0  register char *copy;#endif  s = lookup_symtab_1 (name);  if (s) return s;#if 0  /* This screws c-exp.y:yylex if there is both a type "tree" and a symtab     "tree.c".  */  /* If name not found as specified, see if adding ".c" helps.  */  /* Why is this?  Is it just a user convenience?  (If so, it's pretty     questionable in the presence of C++, FORTRAN, etc.).  It's not in     the GDB manual.  */  copy = (char *) alloca (strlen (name) + 3);  strcpy (copy, name);  strcat (copy, ".c");  s = lookup_symtab_1 (copy);  if (s) return s;#endif /* 0 */  /* We didn't find anything; die.  */  return 0;}/* Lookup the partial symbol table of a source file named NAME.   *If* there is no '/' in the name, a match after a '/'   in the psymtab filename will also work.  */struct partial_symtab *lookup_partial_symtab (name)char *name;{  register struct partial_symtab *pst;  register struct objfile *objfile;    ALL_PSYMTABS (objfile, pst)    {      if (STREQ (name, pst -> filename))	{	  return (pst);	}    }  /* Now, search for a matching tail (only if name doesn't have any dirs) */  if (!strchr (name, '/'))    ALL_PSYMTABS (objfile, pst)      {	char *p = pst -> filename;	char *tail = strrchr (p, '/');	if (tail)	  p = tail + 1;	if (STREQ (p, name))	  return (pst);      }  return (NULL);}/* Demangle a GDB method stub type.   Note that this function is g++ specific. */char *gdb_mangle_name (type, i, j)     struct type *type;     int i, j;{  int mangled_name_len;  char *mangled_name;  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);  struct fn_field *method = &f[j];  char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);  char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);  char *newname = type_name_no_tag (type);  /* Does the form of physname indicate that it is the full mangled name     of a constructor (not just the args)?  */  int is_full_physname_constructor;  int is_constructor;  int is_destructor = DESTRUCTOR_PREFIX_P (physname);  /* Need a new type prefix.  */  char *const_prefix = method->is_const ? "C" : "";  char *volatile_prefix = method->is_volatile ? "V" : "";  char buf[20];  int len = (newname == NULL ? 0 : strlen (newname));  is_full_physname_constructor =     ((physname[0]=='_' && physname[1]=='_' &&       (isdigit(physname[2]) || physname[2]=='Q' || physname[2]=='t'))     || (strncmp(physname, "__ct", 4) == 0));  is_constructor =    is_full_physname_constructor || (newname && STREQ(field_name, newname));  if (!is_destructor)    is_destructor = (strncmp(physname, "__dt", 4) == 0);   if (is_destructor || is_full_physname_constructor)    {      mangled_name = (char*) xmalloc(strlen(physname)+1);      strcpy(mangled_name, physname);      return mangled_name;    }  if (len == 0)    {      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);      if (strcmp(buf, "__") == 0)	buf[0] = '\0';    }  else if (newname != NULL && strchr (newname, '<') != NULL)    {      /* Template methods are fully mangled.  */      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);      newname = NULL;      len = 0;    }  else    {      sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);    }  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))			  + strlen (buf) + len			  + strlen (physname)			  + 1);  /* Only needed for GNU-mangled names.  ANSI-mangled names     work with the normal mechanisms.  */  if (OPNAME_PREFIX_P (field_name))    {      const char *opname = cplus_mangle_opname (field_name + 3, 0);      if (opname == NULL)	error ("No mangling for \"%s\"", field_name);      mangled_name_len += strlen (opname);      mangled_name = (char *)xmalloc (mangled_name_len);      strncpy (mangled_name, field_name, 3);      mangled_name[3] = '\0';      strcat (mangled_name, opname);    }  else    {      mangled_name = (char *)xmalloc (mangled_name_len);      if (is_constructor)	mangled_name[0] = '\0';      else	strcpy (mangled_name, field_name);    }  strcat (mangled_name, buf);  /* If the class doesn't have a name, i.e. newname NULL, then we just     mangle it using 0 for the length of the class.  Thus it gets mangled     as something starting with `::' rather than `classname::'. */   if (newname != NULL)    strcat (mangled_name, newname);  strcat (mangled_name, physname);  return (mangled_name);}/* Find which partial symtab on contains PC.  Return 0 if none.  */struct partial_symtab *find_pc_psymtab (pc)     register CORE_ADDR pc;{  register struct partial_symtab *pst;  register struct objfile *objfile;  ALL_PSYMTABS (objfile, pst)    {      if (pc >= pst->textlow && pc < pst->texthigh)	{	  struct minimal_symbol *msymbol;	  struct partial_symtab *tpst;	  /* An objfile that has its functions reordered might have	     many partial symbol tables containing the PC, but	     we want the partial symbol table that contains the	     function containing the PC.  */	  if (!(objfile->flags & OBJF_REORDERED))	    return (pst);	  msymbol = lookup_minimal_symbol_by_pc (pc);	  if (msymbol == NULL)	    return (pst);	  for (tpst = pst; tpst != NULL; tpst = tpst->next)	    {	      if (pc >= tpst->textlow && pc < tpst->texthigh)		{		  struct partial_symbol *p;		  p = find_pc_psymbol (tpst, pc);		  if (p != NULL		      && SYMBOL_VALUE_ADDRESS(p)			 == SYMBOL_VALUE_ADDRESS (msymbol))		    return (tpst);		}	    }	  return (pst);	}    }  return (NULL);}/* Find which partial symbol within a psymtab contains PC.  Return 0   if none.  Check all psymtabs if PSYMTAB is 0.  */struct partial_symbol *find_pc_psymbol (psymtab, pc)     struct partial_symtab *psymtab;     CORE_ADDR pc;{  struct partial_symbol *best = NULL, *p, **pp;  CORE_ADDR best_pc;    if (!psymtab)    psymtab = find_pc_psymtab (pc);  if (!psymtab)    return 0;  best_pc = psymtab->textlow - 1;  /* Search the global symbols as well as the static symbols, so that     find_pc_partial_function doesn't use a minimal symbol and thus     cache a bad endaddr.  */  for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;       (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)	< psymtab->n_global_syms);       pp++)    {      p = *pp;      if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE	  && SYMBOL_CLASS (p) == LOC_BLOCK	  && pc >= SYMBOL_VALUE_ADDRESS (p)	  && SYMBOL_VALUE_ADDRESS (p) > best_pc)	{	  best_pc = SYMBOL_VALUE_ADDRESS (p);	  best = p;	}    }  for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;       (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)	< psymtab->n_static_syms);       pp++)    {      p = *pp;      if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE	  && SYMBOL_CLASS (p) == LOC_BLOCK	  && pc >= SYMBOL_VALUE_ADDRESS (p)	  && SYMBOL_VALUE_ADDRESS (p) > best_pc)	{	  best_pc = SYMBOL_VALUE_ADDRESS (p);	  best = p;	}    }  if (best_pc == psymtab->textlow - 1)    return 0;  return best;}/* Find the definition for a specified symbol name NAME   in namespace NAMESPACE, visible from lexical block BLOCK.   Returns the struct symbol pointer, or zero if no symbol is found.   If SYMTAB is non-NULL, store the symbol table in which the   symbol was found there, or NULL if not found.   C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if   NAME is a field of the current implied argument `this'.  If so set   *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.    BLOCK_FOUND is set to the block in which NAME is found (in the case of   a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) *//* This function has a bunch of loops in it and it would seem to be   attractive to put in some QUIT's (though I'm not really sure   whether it can run long enough to be really important).  But there   are a few calls for which it would appear to be bad news to quit   out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and   nindy_frame_chain_valid in nindy-tdep.c.  (Note that there is C++   code below which can error(), but that probably doesn't affect   these calls since they are looking for a known variable and thus   can probably assume it will never hit the C++ code).  */struct symbol *lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)     const char *name;     register const struct block *block;     const namespace_enum namespace;     int *is_a_field_of_this;     struct symtab **symtab;{  register struct symbol *sym;  register struct symtab *s = NULL;  register struct partial_symtab *ps;  struct blockvector *bv;  register struct objfile *objfile;  register struct block *b;  register struct minimal_symbol *msymbol;  /* Search specified block and its superiors.  */  while (block != 0)    {      sym = lookup_block_symbol (block, name, namespace);      if (sym) 	{	  block_found = block;	  if (symtab != NULL)	    {	      /* Search the list of symtabs for one which contains the		 address of the start of this block.  */	      ALL_SYMTABS (objfile, s)		{		  bv = BLOCKVECTOR (s);		  b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);		  if (BLOCK_START (b) <= BLOCK_START (block)		      && BLOCK_END (b) > BLOCK_START (block))		    goto found;		}found:	      *symtab = s;	    }	  return (sym);	}      block = BLOCK_SUPERBLOCK (block);    }  /* FIXME: this code is never executed--block is always NULL at this     point.  What is it trying to do, anyway?  We already should have     checked the STATIC_BLOCK above (it is the superblock of top-level     blocks).  Why is VAR_NAMESPACE special-cased?  */  /* Don't need to mess with the psymtabs; if we have a block,     that file is read in.  If we don't, then we deal later with     all the psymtab stuff that needs checking.  */  if (namespace == VAR_NAMESPACE && block != NULL)    {      struct block *b;      /* Find the right symtab.  */      ALL_SYMTABS (objfile, s)	{	  bv = BLOCKVECTOR (s);	  b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);	  if (BLOCK_START (b) <= BLOCK_START (block)	      && BLOCK_END (b) > BLOCK_START (block))	    {	      sym = lookup_block_symbol (b, name, VAR_NAMESPACE);	      if (sym)		{		  block_found = b;		  if (symtab != NULL)		    *symtab = s;		  return sym;		}	    }	}    }  /* C++: If requested to do so by the caller,      check to see if NAME is a field of `this'. */  if (is_a_field_of_this)    {      struct value *v = value_of_this (0);            *is_a_field_of_this = 0;      if (v && check_field (v, name))	{	  *is_a_field_of_this = 1;	  if (symtab != NULL)	    *symtab = NULL;	  return 0;	}    }  /* Now search all global blocks.  Do the symtab's first, then     check the psymtab's */    ALL_SYMTABS (objfile, s)    {      bv = BLOCKVECTOR (s);      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);      sym = lookup_block_symbol (block, name, namespace);      if (sym) 	{	  block_found = block;	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  /* Check for the possibility of the symbol being a function or     a mangled variable that is stored in one of the minimal symbol tables.     Eventually, all global symbols might be resolved in this way.  */    if (namespace == VAR_NAMESPACE)    {      msymbol = lookup_minimal_symbol (name, NULL, NULL);      if (msymbol != NULL)	{	  s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));	  if (s != NULL)	    {	      /* This is a function which has a symtab for its address.  */	      bv = BLOCKVECTOR (s);	      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);	      sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),					 namespace);              /* We kept static functions in minimal symbol table as well as		 in static scope. We want to find them in the symbol table. */		if (!sym) {		  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);		  sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),					     namespace);		}	      /* sym == 0 if symbol was found in the minimal symbol table		 but not in the symtab.		 Return 0 to use the msymbol definition of "foo_".		 This happens for Fortran  "foo_" symbols,		 which are "foo" in the symtab.		 This can also happen if "asm" is used to make a		 regular symbol but not a debugging symbol, e.g.		 asm(".globl _main");		 asm("_main:");		 */	      if (symtab != NULL)		*symtab = s;	      return sym;	    }	  else if (MSYMBOL_TYPE (msymbol) != mst_text		   && MSYMBOL_TYPE (msymbol) != mst_file_text		   && !STREQ (name, SYMBOL_NAME (msymbol)))	    {	      /* This is a mangled variable, look it up by its		 mangled name.  */	      return lookup_symbol (SYMBOL_NAME (msymbol), block,				    namespace, is_a_field_of_this, symtab);	    }	  /* There are no debug symbols for this file, or we are looking	     for an unmangled variable.	     Try to find a matching static symbol below. */	}    }        ALL_PSYMTABS (objfile, ps)    {      if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))	{	  s = PSYMTAB_TO_SYMTAB(ps);	  bv = BLOCKVECTOR (s);	  block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);	  sym = lookup_block_symbol (block, name, namespace);	  if (!sym)	    error ("Internal: global symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  /* Now search all per-file blocks.     Not strictly correct, but more useful than an error.     Do the symtabs first, then check the psymtabs */  ALL_SYMTABS (objfile, s)    {      bv = BLOCKVECTOR (s);      block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);      sym = lookup_block_symbol (block, name, namespace);      if (sym) 	{	  block_found = block;	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  ALL_PSYMTABS (objfile, ps)    {      if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace))	{	  s = PSYMTAB_TO_SYMTAB(ps);	  bv = BLOCKVECTOR (s);	  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);	  sym = lookup_block_symbol (block, name, namespace);	  if (!sym)	    error ("Internal: static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);	  if (symtab != NULL)	    *symtab = s;	  return sym;	}    }  if (symtab != NULL)    *symtab = NULL;  return 0;}/* Look, in partial_symtab PST, for symbol NAME.  Check the global   symbols if GLOBAL, the static symbols if not */static struct partial_symbol *lookup_partial_symbol (pst, name, global, namespace)     struct partial_symtab *pst;     const char *name;     int global;     namespace_enum namespace;{  struct partial_symbol **start, **psym;  struct partial_symbol **top, **bottom, **center;  int length = (global ? pst->n_global_syms : pst->n_static_syms);  int do_linear_search = 1;  if (length == 0)    {      return (NULL);    }    start = (global ?	   pst->objfile->global_psymbols.list + pst->globals_offset :	   pst->objfile->static_psymbols.list + pst->statics_offset  );  if (global)		/* This means we can use a binary search. */    {      do_linear_search = 0;      /* Binary search.  This search is guaranteed to end with center         pointing at the earliest partial symbol with the correct	 name.  At that point *all* partial symbols with that name	 will be checked against the correct namespace. */      bottom = start;      top = start + length - 1;      while (top > bottom)	{	  center = bottom + (top - bottom) / 2;	  if (!(center < top))	    abort ();	  if (!do_linear_search && SYMBOL_LANGUAGE (*center) == language_cplus)	    {	      do_linear_search = 1;	    }	  if (STRCMP (SYMBOL_NAME (*center), name) >= 0)	    {	      top = center;	    }	  else	    {	      bottom = center + 1;	    }	}      if (!(top == bottom))	abort ();      while (STREQ (SYMBOL_NAME (*top), name))	{	  if (SYMBOL_NAMESPACE (*top) == namespace)	    {	      return (*top);	    }	  top ++;	}    }  /* Can't use a binary search or else we found during the binary search that     we should also do a linear search. */  if (do_linear_search)    {      for (psym = start; psym < start + length; psym++)	{	  if (namespace == SYMBOL_NAMESPACE (*psym))	    {	      if (SYMBOL_MATCHES_NAME (*psym, name))		{		  return (*psym);		}	    }	}    }  return (NULL);}