/* Objective-C language support routines for GDB, the GNU debugger.

   Copyright (C) 2002-2025 Free Software Foundation, Inc.

   Contributed by Apple Computer, Inc.
   Written by Michael Snyder.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "event-top.h"
#include "exceptions.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "parser-defs.h"
#include "language.h"
#include "varobj.h"
#include "c-lang.h"
#include "objc-lang.h"
#include "complaints.h"
#include "value.h"
#include "symfile.h"
#include "objfiles.h"
#include "target.h"
#include "gdbcore.h"
#include "cli/cli-cmds.h"
#include "frame.h"
#include "gdbsupport/gdb_regex.h"
#include "regcache.h"
#include "block.h"
#include "infcall.h"
#include "valprint.h"
#include "cli/cli-utils.h"
#include "c-exp.h"

#include <algorithm>

struct objc_object {
  CORE_ADDR isa;
};

struct objc_class {
  CORE_ADDR isa; 
  CORE_ADDR super_class; 
  CORE_ADDR name;               
  long version;
  long info;
  long instance_size;
  CORE_ADDR ivars;
  CORE_ADDR methods;
  CORE_ADDR cache;
  CORE_ADDR protocols;
};

struct objc_super {
  CORE_ADDR receiver;
  CORE_ADDR theclass;
};

struct objc_method {
  CORE_ADDR name;
  CORE_ADDR types;
  CORE_ADDR imp;
};

static const registry<objfile>::key<unsigned int> objc_objfile_data;

/* Lookup a structure type named "struct NAME", visible in lexical
   block BLOCK.  If NOERR is nonzero, return zero if NAME is not
   suitably defined.  */

struct symbol *
lookup_struct_typedef (const char *name, const struct block *block, int noerr)
{
  struct symbol *sym;

  sym = lookup_symbol (name, block, SEARCH_STRUCT_DOMAIN, 0).symbol;

  if (sym == NULL)
    {
      if (noerr)
	return 0;
      else 
	error (_("No struct type named %s."), name);
    }
  if (sym->type ()->code () != TYPE_CODE_STRUCT)
    {
      if (noerr)
	return 0;
      else
	error (_("This context has class, union or enum %s, not a struct."), 
	       name);
    }
  return sym;
}

CORE_ADDR 
lookup_objc_class (struct gdbarch *gdbarch, const char *classname)
{
  struct type *char_type = builtin_type (gdbarch)->builtin_char;
  struct value * function, *classval;

  if (! target_has_execution ())
    {
      /* Can't call into inferior to lookup class.  */
      return 0;
    }

  if (lookup_minimal_symbol (current_program_space,
			     "objc_lookUpClass").minsym != nullptr)
    function = find_function_in_inferior("objc_lookUpClass", NULL);
  else if (lookup_minimal_symbol (current_program_space,
				  "objc_lookup_class").minsym != nullptr)
    function = find_function_in_inferior("objc_lookup_class", NULL);
  else
    {
      complaint (_("no way to lookup Objective-C classes"));
      return 0;
    }

  classval = value_string (classname, strlen (classname) + 1, char_type);
  classval = value_coerce_array (classval);
  return (CORE_ADDR) value_as_long (call_function_by_hand (function,
							   NULL,
							   classval));
}

CORE_ADDR
lookup_child_selector (struct gdbarch *gdbarch, const char *selname)
{
  struct type *char_type = builtin_type (gdbarch)->builtin_char;
  struct value * function, *selstring;

  if (! target_has_execution ())
    {
      /* Can't call into inferior to lookup selector.  */
      return 0;
    }

  if (lookup_minimal_symbol (current_program_space, "sel_getUid").minsym
      != nullptr)
    function = find_function_in_inferior("sel_getUid", NULL);
  else if (lookup_minimal_symbol (current_program_space,
				  "sel_get_any_uid").minsym != nullptr)
    function = find_function_in_inferior("sel_get_any_uid", NULL);
  else
    {
      complaint (_("no way to lookup Objective-C selectors"));
      return 0;
    }

  selstring = value_coerce_array (value_string (selname, 
						strlen (selname) + 1,
						char_type));
  return value_as_long (call_function_by_hand (function, NULL, selstring));
}

struct value * 
value_nsstring (struct gdbarch *gdbarch, const char *ptr, int len)
{
  struct type *char_type = builtin_type (gdbarch)->builtin_char;
  struct value *stringValue[3];
  struct value *function, *nsstringValue;
  struct symbol *sym;
  struct type *type;

  if (!target_has_execution ())
    return 0;		/* Can't call into inferior to create NSString.  */

  stringValue[2] = value_string(ptr, len, char_type);
  stringValue[2] = value_coerce_array(stringValue[2]);
  /* _NSNewStringFromCString replaces "istr" after Lantern2A.  */
  if (lookup_minimal_symbol (current_program_space,
			     "_NSNewStringFromCString").minsym != nullptr)
    {
      function = find_function_in_inferior("_NSNewStringFromCString", NULL);
      nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
    }
  else if (lookup_minimal_symbol (current_program_space,
				  "istr").minsym != nullptr)
    {
      function = find_function_in_inferior("istr", NULL);
      nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
    }
  else if (lookup_minimal_symbol (current_program_space,
				  "+[NSString stringWithCString:]").minsym
	   != nullptr)
    {
      function
	= find_function_in_inferior("+[NSString stringWithCString:]", NULL);
      type = builtin_type (gdbarch)->builtin_long;

      stringValue[0] = value_from_longest 
	(type, lookup_objc_class (gdbarch, "NSString"));
      stringValue[1] = value_from_longest 
	(type, lookup_child_selector (gdbarch, "stringWithCString:"));
      nsstringValue = call_function_by_hand(function, NULL, stringValue);
    }
  else
    error (_("NSString: internal error -- no way to create new NSString"));

  sym = lookup_struct_typedef("NSString", 0, 1);
  if (sym == NULL)
    sym = lookup_struct_typedef("NXString", 0, 1);
  if (sym == NULL)
    type = builtin_type (gdbarch)->builtin_data_ptr;
  else
    type = lookup_pointer_type(sym->type ());

  nsstringValue->deprecated_set_type (type);
  return nsstringValue;
}

/* Class representing the Objective-C language.  */

class objc_language : public language_defn
{
public:
  objc_language ()
    : language_defn (language_objc)
  { /* Nothing.  */ }

  /* See language.h.  */

  const char *name () const override
  { return "objective-c"; }

  /* See language.h.  */

  const char *natural_name () const override
  { return "Objective-C"; }

  /* See language.h.  */

  const std::vector<const char *> &filename_extensions () const override
  {
    static const std::vector<const char *> extensions = { ".m" };
    return extensions;
  }

  /* See language.h.  */
  void language_arch_info (struct gdbarch *gdbarch,
			   struct language_arch_info *lai) const override
  {
    c_language_arch_info (gdbarch, lai);
  }

  /* See language.h.  */
  bool sniff_from_mangled_name
       (const char *mangled, gdb::unique_xmalloc_ptr<char> *demangled)
       const override
  {
    *demangled = demangle_symbol (mangled, 0);
    return *demangled != NULL;
  }

  /* See language.h.  */

  gdb::unique_xmalloc_ptr<char> demangle_symbol (const char *mangled,
						 int options) const override;

  /* See language.h.  */

  bool can_print_type_offsets () const override
  {
    return true;
  }

  /* See language.h.  */

  void print_type (struct type *type, const char *varstring,
		   struct ui_file *stream, int show, int level,
		   const struct type_print_options *flags) const override
  {
    c_print_type (type, varstring, stream, show, level, la_language, flags);
  }

  /* See language.h.  */

  CORE_ADDR skip_trampoline (const frame_info_ptr &frame,
			     CORE_ADDR stop_pc) const override
  {
    struct gdbarch *gdbarch = get_frame_arch (frame);
    CORE_ADDR real_stop_pc;
    CORE_ADDR method_stop_pc;

    /* Determine if we are currently in the Objective-C dispatch function.
       If so, get the address of the method function that the dispatcher
       would call and use that as the function to step into instead.  Also
       skip over the trampoline for the function (if any).  This is better
       for the user since they are only interested in stepping into the
       method function anyway.  */

    real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);

    if (real_stop_pc != 0)
      find_objc_msgcall (real_stop_pc, &method_stop_pc);
    else
      find_objc_msgcall (stop_pc, &method_stop_pc);

    if (method_stop_pc)
      {
	real_stop_pc = gdbarch_skip_trampoline_code
	  (gdbarch, frame, method_stop_pc);
	if (real_stop_pc == 0)
	  real_stop_pc = method_stop_pc;
      }

    return real_stop_pc;
  }

  /* See language.h.  */

  const char *name_of_this () const override
  { return "self"; }

  /* See language.h.  */

  enum macro_expansion macro_expansion () const override
  { return macro_expansion_c; }
};

/* See declaration of objc_language::demangle_symbol above.  */

gdb::unique_xmalloc_ptr<char>
objc_language::demangle_symbol (const char *mangled, int options) const
{
  char *demangled, *cp;

  if (mangled[0] == '_'
      && (mangled[1] == 'i' || mangled[1] == 'c')
      && mangled[2] == '_')
    {
      cp = demangled = (char *) xmalloc (strlen (mangled) + 2);

      if (mangled[1] == 'i')
	*cp++ = '-';		/* for instance method */
      else
	*cp++ = '+';		/* for class    method */

      *cp++ = '[';		/* opening left brace  */
      strcpy(cp, mangled+3);	/* Tack on the rest of the mangled name.  */

      while (*cp != '\0' && *cp == '_')
	cp++;			/* Skip any initial underbars in class
				   name.  */

      cp = strchr(cp, '_');
      if (cp == nullptr)	/* Find first non-initial underbar.  */
	{
	  xfree(demangled);	/* not mangled name */
	  return nullptr;
	}
      if (cp[1] == '_')		/* Easy case: no category name.    */
	{
	  *cp++ = ' ';		/* Replace two '_' with one ' '.   */
	  strcpy(cp, mangled + (cp - demangled) + 2);
	}
      else
	{
	  *cp++ = '(';		/* Less easy case: category name.  */
	  cp = strchr(cp, '_');
	  if (cp == nullptr)
	    {
	      xfree(demangled);	/* not mangled name */
	      return nullptr;
	    }
	  *cp++ = ')';
	  *cp++ = ' ';		/* Overwriting 1st char of method name...  */
	  strcpy(cp, mangled + (cp - demangled));	/* Get it back.  */
	}

      while (*cp != '\0' && *cp == '_')
	cp++;			/* Skip any initial underbars in
				   method name.  */

      for (; *cp != '\0'; cp++)
	if (*cp == '_')
	  *cp = ':';		/* Replace remaining '_' with ':'.  */

      *cp++ = ']';		/* closing right brace */
      *cp++ = 0;		/* string terminator */
      return gdb::unique_xmalloc_ptr<char> (demangled);
    }
  else
    return nullptr;	/* Not an objc mangled name.  */
}

/* Single instance of the class representing the Objective-C language.  */

static objc_language objc_language_defn;

/*
 * ObjC:
 * Following functions help construct Objective-C message calls.
 */

struct selname		/* For parsing Objective-C.  */
  {
    struct selname *next;
    char *msglist_sel;
    int msglist_len;
  };

static int msglist_len;
static struct selname *selname_chain;
static char *msglist_sel;

void
start_msglist(void)
{
  struct selname *newobj = XNEW (struct selname);

  newobj->next = selname_chain;
  newobj->msglist_len = msglist_len;
  newobj->msglist_sel = msglist_sel;
  msglist_len = 0;
  msglist_sel = (char *)xmalloc(1);
  *msglist_sel = 0;
  selname_chain = newobj;
}

void
add_msglist(struct stoken *str, int addcolon)
{
  char *s;
  const char *p;
  int len, plen;

  if (str == 0)			/* Unnamed arg, or...  */
    {
      if (addcolon == 0)	/* variable number of args.  */
	{
	  msglist_len++;
	  return;
	}
      p = "";
      plen = 0;
    }
  else
    {
      p = str->ptr;
      plen = str->length;
    }
  len = plen + strlen(msglist_sel) + 2;
  s = (char *)xmalloc(len);
  strcpy(s, msglist_sel);
  strncat(s, p, plen);
  xfree(msglist_sel);
  msglist_sel = s;
  if (addcolon)
    {
      s[len-2] = ':';
      s[len-1] = 0;
      msglist_len++;
    }
  else
    s[len-2] = '\0';
}

int
end_msglist (struct parser_state *ps)
{
  int val = msglist_len;
  struct selname *sel = selname_chain;
  char *p = msglist_sel;
  CORE_ADDR selid;

  std::vector<expr::operation_up> args = ps->pop_vector (val);
  expr::operation_up target = ps->pop ();

  selname_chain = sel->next;
  msglist_len = sel->msglist_len;
  msglist_sel = sel->msglist_sel;
  selid = lookup_child_selector (ps->gdbarch (), p);
  if (!selid)
    error (_("Can't find selector \"%s\""), p);

  ps->push_new<expr::objc_msgcall_operation> (selid, std::move (target),
					      std::move (args));

  xfree(p);
  xfree(sel);

  return val;
}

/*
 * Function: specialcmp (const char *a, const char *b)
 *
 * Special strcmp: treats ']' and ' ' as end-of-string.
 * Used for qsorting lists of objc methods (either by class or selector).
 */

static int
specialcmp (const char *a, const char *b)
{
  while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
    {
      if (*a != *b)
	return *a - *b;
      a++, b++;
    }
  if (*a && *a != ' ' && *a != ']')
    return  1;		/* a is longer therefore greater.  */
  if (*b && *b != ' ' && *b != ']')
    return -1;		/* a is shorter therefore lesser.  */
  return    0;		/* a and b are identical.  */
}

/*
 * Function: compare_selectors (const void *, const void *)
 *
 * Comparison function for use with qsort.  Arguments are symbols or
 * msymbols Compares selector part of objc method name alphabetically.
 */

static int
compare_selectors (const void *a, const void *b)
{
  const char *aname, *bname;

  aname = (*(struct symbol **) a)->print_name ();
  bname = (*(struct symbol **) b)->print_name ();
  if (aname == NULL || bname == NULL)
    error (_("internal: compare_selectors(1)"));

  aname = strchr(aname, ' ');
  bname = strchr(bname, ' ');
  if (aname == NULL || bname == NULL)
    error (_("internal: compare_selectors(2)"));

  return specialcmp (aname+1, bname+1);
}

/*
 * Function: selectors_info (regexp, from_tty)
 *
 * Implements the "Info selectors" command.  Takes an optional regexp
 * arg.  Lists all objective c selectors that match the regexp.  Works
 * by grepping through all symbols for objective c methods.  Output list
 * is sorted and uniqued. 
 */

static void
info_selectors_command (const char *regexp, int from_tty)
{
  const char            *name;
  char                  *val;
  int                    matches = 0;
  int                    maxlen  = 0;
  int                    ix;
  char                   myregexp[2048];
  char                   asel[256];
  struct symbol        **sym_arr;
  int                    plusminus = 0;

  if (regexp == NULL)
    strcpy(myregexp, ".*]");	/* Null input, match all objc methods.  */
  else
    {
      if (*regexp == '+' || *regexp == '-')
	{ /* User wants only class methods or only instance methods.  */
	  plusminus = *regexp++;
	  while (*regexp == ' ' || *regexp == '\t')
	    regexp++;
	}
      if (*regexp == '\0')
	strcpy(myregexp, ".*]");
      else
	{
	  /* Allow a few extra bytes because of the strcat below.  */
	  if (sizeof (myregexp) < strlen (regexp) + 4)
	    error (_("Regexp is too long: %s"), regexp);
	  strcpy(myregexp, regexp);
	  if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
	    myregexp[strlen(myregexp) - 1] = ']';    /* end of method name */
	  else
	    strcat(myregexp, ".*]");
	}
    }

  if (regexp != NULL)
    {
      val = re_comp (myregexp);
      if (val != 0)
	error (_("Invalid regexp (%s): %s"), val, regexp);
    }

  /* First time through is JUST to get max length and count.  */
  for (objfile &objfile : current_program_space->objfiles ())
    {
      for (minimal_symbol *msymbol : objfile.msymbols ())
	{
	  QUIT;
	  name = msymbol->natural_name ();
	  if (name
	      && (name[0] == '-' || name[0] == '+')
	      && name[1] == '[')		/* Got a method name.  */
	    {
	      /* Filter for class/instance methods.  */
	      if (plusminus && name[0] != plusminus)
		continue;
	      /* Find selector part.  */
	      name = (char *) strchr (name+2, ' ');
	      if (name == NULL)
		{
		  complaint (_("Bad method name '%s'"),
			     msymbol->natural_name ());
		  continue;
		}
	      if (regexp == NULL || re_exec(++name) != 0)
		{ 
		  const char *mystart = name;
		  const char *myend   = strchr (mystart, ']');
	      
		  if (myend && (myend - mystart > maxlen))
		    maxlen = myend - mystart;	/* Get longest selector.  */
		  matches++;
		}
	    }
	}
    }
  if (matches)
    {
      gdb_printf (_("Selectors matching \"%s\":\n\n"), 
		  regexp ? regexp : "*");

      sym_arr = XALLOCAVEC (struct symbol *, matches);
      matches = 0;
      for (objfile &objfile : current_program_space->objfiles ())
	{
	  for (minimal_symbol *msymbol : objfile.msymbols ())
	    {
	      QUIT;
	      name = msymbol->natural_name ();
	      if (name &&
		  (name[0] == '-' || name[0] == '+') &&
		  name[1] == '[')		/* Got a method name.  */
		{
		  /* Filter for class/instance methods.  */
		  if (plusminus && name[0] != plusminus)
		    continue;
		  /* Find selector part.  */
		  name = (char *) strchr(name+2, ' ');
		  if (regexp == NULL || re_exec(++name) != 0)
		    sym_arr[matches++] = (struct symbol *) msymbol;
		}
	    }
	}

      qsort (sym_arr, matches, sizeof (struct minimal_symbol *), 
	     compare_selectors);
      /* Prevent compare on first iteration.  */
      asel[0] = 0;
      for (ix = 0; ix < matches; ix++)	/* Now do the output.  */
	{
	  char *p = asel;

	  QUIT;
	  name = sym_arr[ix]->natural_name ();
	  name = strchr (name, ' ') + 1;
	  if (p[0] && specialcmp(name, p) == 0)
	    continue;		/* Seen this one already (not unique).  */

	  /* Copy selector part.  */
	  while (*name && *name != ']')
	    *p++ = *name++;
	  *p++ = '\0';
	  /* Print in columns.  */
	  puts_tabular(asel, maxlen + 1, 0);
	}
      begin_line();
    }
  else
    gdb_printf (_("No selectors matching \"%s\"\n"),
		regexp ? regexp : "*");
}

/*
 * Function: compare_classes (const void *, const void *)
 *
 * Comparison function for use with qsort.  Arguments are symbols or
 * msymbols Compares class part of objc method name alphabetically. 
 */

static int
compare_classes (const void *a, const void *b)
{
  const char *aname, *bname;

  aname = (*(struct symbol **) a)->print_name ();
  bname = (*(struct symbol **) b)->print_name ();
  if (aname == NULL || bname == NULL)
    error (_("internal: compare_classes(1)"));

  return specialcmp (aname+1, bname+1);
}

/*
 * Function: classes_info(regexp, from_tty)
 *
 * Implements the "info classes" command for objective c classes.
 * Lists all objective c classes that match the optional regexp.
 * Works by grepping through the list of objective c methods.  List will
 * be sorted and uniqued (since one class may have many methods).
 * BUGS: will not list a class that has no methods. 
 */

static void
info_classes_command (const char *regexp, int from_tty)
{
  const char            *name;
  char                  *val;
  int                    matches = 0;
  int                    maxlen  = 0;
  int                    ix;
  char                   myregexp[2048];
  char                   aclass[256];
  struct symbol        **sym_arr;

  if (regexp == NULL)
    strcpy(myregexp, ".* ");	/* Null input: match all objc classes.  */
  else
    {
      /* Allow a few extra bytes because of the strcat below.  */
      if (sizeof (myregexp) < strlen (regexp) + 4)
	error (_("Regexp is too long: %s"), regexp);
      strcpy(myregexp, regexp);
      if (myregexp[strlen(myregexp) - 1] == '$')
	/* In the method name, the end of the class name is marked by ' '.  */
	myregexp[strlen(myregexp) - 1] = ' ';
      else
	strcat(myregexp, ".* ");
    }

  if (regexp != NULL)
    {
      val = re_comp (myregexp);
      if (val != 0)
	error (_("Invalid regexp (%s): %s"), val, regexp);
    }

  /* First time through is JUST to get max length and count.  */
  for (objfile &objfile : current_program_space->objfiles ())
    {
      for (minimal_symbol *msymbol : objfile.msymbols ())
	{
	  QUIT;
	  name = msymbol->natural_name ();
	  if (name &&
	      (name[0] == '-' || name[0] == '+') &&
	      name[1] == '[')			/* Got a method name.  */
	    if (regexp == NULL || re_exec(name+2) != 0)
	      { 
		/* Compute length of classname part.  */
		const char *mystart = name + 2;
		const char *myend   = strchr (mystart, ' ');
	    
		if (myend && (myend - mystart > maxlen))
		  maxlen = myend - mystart;
		matches++;
	      }
	}
    }
  if (matches)
    {
      gdb_printf (_("Classes matching \"%s\":\n\n"), 
		  regexp ? regexp : "*");
      sym_arr = XALLOCAVEC (struct symbol *, matches);
      matches = 0;
      for (objfile &objfile : current_program_space->objfiles ())
	{
	  for (minimal_symbol *msymbol : objfile.msymbols ())
	    {
	      QUIT;
	      name = msymbol->natural_name ();
	      if (name &&
		  (name[0] == '-' || name[0] == '+') &&
		  name[1] == '[') /* Got a method name.  */
		if (regexp == NULL || re_exec(name+2) != 0)
		  sym_arr[matches++] = (struct symbol *) msymbol;
	    }
	}

      qsort (sym_arr, matches, sizeof (struct minimal_symbol *), 
	     compare_classes);
      /* Prevent compare on first iteration.  */
      aclass[0] = 0;
      for (ix = 0; ix < matches; ix++)	/* Now do the output.  */
	{
	  char *p = aclass;

	  QUIT;
	  name = sym_arr[ix]->natural_name ();
	  name += 2;
	  if (p[0] && specialcmp(name, p) == 0)
	    continue;	/* Seen this one already (not unique).  */

	  /* Copy class part of method name.  */
	  while (*name && *name != ' ')
	    *p++ = *name++;
	  *p++ = '\0';
	  /* Print in columns.  */
	  puts_tabular(aclass, maxlen + 1, 0);
	}
      begin_line();
    }
  else
    gdb_printf (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
}

static char * 
parse_selector (char *method, char **selector)
{
  char *s1 = NULL;
  char *s2 = NULL;
  int found_quote = 0;

  char *nselector = NULL;

  gdb_assert (selector != NULL);

  s1 = method;

  s1 = skip_spaces (s1);
  if (*s1 == '\'') 
    {
      found_quote = 1;
      s1++;
    }
  s1 = skip_spaces (s1);
   
  nselector = s1;
  s2 = s1;

  for (;;)
    {
      if (c_isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
	*s1++ = *s2;
      else if (c_isspace (*s2))
	;
      else if ((*s2 == '\0') || (*s2 == '\''))
	break;
      else
	return NULL;
      s2++;
    }
  *s1++ = '\0';

  s2 = skip_spaces (s2);
  if (found_quote)
    {
      if (*s2 == '\'') 
	s2++;
      s2 = skip_spaces (s2);
    }

  if (selector != NULL)
    *selector = nselector;

  return s2;
}

static char * 
parse_method (char *method, char *type, char **theclass,
	      char **category, char **selector)
{
  char *s1 = NULL;
  char *s2 = NULL;
  int found_quote = 0;

  char ntype = '\0';
  char *nclass = NULL;
  char *ncategory = NULL;
  char *nselector = NULL;

  gdb_assert (type != NULL);
  gdb_assert (theclass != NULL);
  gdb_assert (category != NULL);
  gdb_assert (selector != NULL);
  
  s1 = method;

  s1 = skip_spaces (s1);
  if (*s1 == '\'') 
    {
      found_quote = 1;
      s1++;
    }
  s1 = skip_spaces (s1);
  
  if ((s1[0] == '+') || (s1[0] == '-'))
    ntype = *s1++;

  s1 = skip_spaces (s1);

  if (*s1 != '[')
    return NULL;
  s1++;

  nclass = s1;
  while (c_isalnum (*s1) || (*s1 == '_'))
    s1++;
  
  s2 = s1;
  s2 = skip_spaces (s2);
  
  if (*s2 == '(')
    {
      s2++;
      s2 = skip_spaces (s2);
      ncategory = s2;
      while (c_isalnum (*s2) || (*s2 == '_'))
	s2++;
      *s2++ = '\0';
    }

  /* Truncate the class name now that we're not using the open paren.  */
  *s1++ = '\0';

  nselector = s2;
  s1 = s2;

  for (;;)
    {
      if (c_isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
	*s1++ = *s2;
      else if (c_isspace (*s2))
	;
      else if (*s2 == ']')
	break;
      else
	return NULL;
      s2++;
    }
  *s1++ = '\0';
  s2++;

  s2 = skip_spaces (s2);
  if (found_quote)
    {
      if (*s2 != '\'') 
	return NULL;
      s2++;
      s2 = skip_spaces (s2);
    }

  if (type != NULL)
    *type = ntype;
  if (theclass != NULL)
    *theclass = nclass;
  if (category != NULL)
    *category = ncategory;
  if (selector != NULL)
    *selector = nselector;

  return s2;
}

static void
find_methods (char type, const char *theclass, const char *category, 
	      const char *selector,
	      std::vector<const char *> *symbol_names)
{
  const char *symname = NULL;

  char ntype = '\0';
  char *nclass = NULL;
  char *ncategory = NULL;
  char *nselector = NULL;

  static char *tmp = NULL;
  static unsigned int tmplen = 0;

  gdb_assert (symbol_names != NULL);

  for (objfile &objfile : current_program_space->objfiles ())
    {
      unsigned int *objc_csym;

      /* The objfile_csym variable counts the number of ObjC methods
	 that this objfile defines.  We save that count as a private
	 objfile data.	If we have already determined that this objfile
	 provides no ObjC methods, we can skip it entirely.  */

      unsigned int objfile_csym = 0;

      objc_csym = objc_objfile_data.get (&objfile);
      if (objc_csym != NULL && *objc_csym == 0)
	/* There are no ObjC symbols in this objfile.  Skip it entirely.  */
	continue;

      for (minimal_symbol *msymbol : objfile.msymbols ())
	{
	  QUIT;

	  /* Check the symbol name first as this can be done entirely without
	     sending any query to the target.  */
	  symname = msymbol->natural_name ();
	  if (symname == NULL)
	    continue;

	  if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
	    /* Not a method name.  */
	    continue;

	  objfile_csym++;

	  /* Now that thinks are a bit sane, clean up the symname.  */
	  while ((strlen (symname) + 1) >= tmplen)
	    {
	      tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
	      tmp = (char *) xrealloc (tmp, tmplen);
	    }
	  strcpy (tmp, symname);

	  if (parse_method (tmp, &ntype, &nclass,
			    &ncategory, &nselector) == NULL)
	    continue;

	  if ((type != '\0') && (ntype != type))
	    continue;

	  if ((theclass != NULL)
	      && ((nclass == NULL) || (strcmp (theclass, nclass) != 0)))
	    continue;

	  if ((category != NULL) && 
	      ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
	    continue;

	  if ((selector != NULL) && 
	      ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
	    continue;

	  symbol_names->push_back (symname);
	}

      if (objc_csym == NULL)
	objc_csym = objc_objfile_data.emplace (&objfile, objfile_csym);
      else
	/* Count of ObjC methods in this objfile should be constant.  */
	gdb_assert (*objc_csym == objfile_csym);
    }
}

/* Uniquify a vector of strings.  */

static void
uniquify_strings (std::vector<const char *> *strings)
{
  if (strings->empty ())
    return;

  std::sort (strings->begin (), strings->end (), compare_cstrings);
  strings->erase (std::unique (strings->begin (), strings->end (), streq),
		  strings->end ());
}

/* 
 * Function: find_imps (const char *selector, struct symbol **sym_arr)
 *
 * Input:  a string representing a selector
 *         a pointer to an array of symbol pointers
 *         possibly a pointer to a symbol found by the caller.
 *
 * Output: number of methods that implement that selector.  Side
 * effects: The array of symbol pointers is filled with matching syms.
 *
 * By analogy with function "find_methods" (symtab.c), builds a list
 * of symbols matching the ambiguous input, so that "decode_line_2"
 * (symtab.c) can list them and ask the user to choose one or more.
 * In this case the matches are objective c methods
 * ("implementations") matching an objective c selector.
 *
 * Note that it is possible for a normal (c-style) function to have
 * the same name as an objective c selector.  To prevent the selector
 * from eclipsing the function, we allow the caller (decode_line_1) to
 * search for such a function first, and if it finds one, pass it in
 * to us.  We will then integrate it into the list.  We also search
 * for one here, among the minsyms.
 *
 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
 *       into two parts: debuggable (struct symbol) syms, and
 *       non_debuggable (struct minimal_symbol) syms.  The debuggable
 *       ones will come first, before NUM_DEBUGGABLE (which will thus
 *       be the index of the first non-debuggable one).
 */

const char *
find_imps (const char *method, std::vector<const char *> *symbol_names)
{
  char type = '\0';
  char *theclass = NULL;
  char *category = NULL;
  char *selector = NULL;

  char *buf = NULL;
  char *tmp = NULL;

  int selector_case = 0;

  gdb_assert (symbol_names != NULL);

  buf = (char *) alloca (strlen (method) + 1);
  strcpy (buf, method);
  tmp = parse_method (buf, &type, &theclass, &category, &selector);

  if (tmp == NULL)
    {
      strcpy (buf, method);
      tmp = parse_selector (buf, &selector);

      if (tmp == NULL)
	return NULL;

      selector_case = 1;
    }

  find_methods (type, theclass, category, selector, symbol_names);

  /* If we hit the "selector" case, and we found some methods, then
     add the selector itself as a symbol, if it exists.  */
  if (selector_case && !symbol_names->empty ())
    {
      struct symbol *sym = lookup_symbol (selector, NULL, SEARCH_VFT,
					  0).symbol;

      if (sym != NULL) 
	symbol_names->push_back (sym->natural_name ());
      else
	{
	  bound_minimal_symbol msym
	    = lookup_minimal_symbol (current_program_space, selector);

	  if (msym.minsym != NULL) 
	    symbol_names->push_back (msym.minsym->natural_name ());
	}
    }

  uniquify_strings (symbol_names);

  return method + (tmp - buf);
}

static void 
print_object_command (const char *args, int from_tty)
{
  struct value *object, *function, *description;
  CORE_ADDR string_addr, object_addr;
  int i = 0;
  gdb_byte c = 0;

  if (!args || !*args)
    error (
"The 'print-object' command requires an argument (an Objective-C object)");

  {
    expression_up expr = parse_expression (args);

    object = expr->evaluate (builtin_type (expr->gdbarch)->builtin_data_ptr);
  }

  /* Validate the address for sanity.  */
  object_addr = value_as_long (object);
  read_memory (object_addr, &c, 1);

  function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
  if (function == NULL)
    error (_("Unable to locate _NSPrintForDebugger in child process"));

  description = call_function_by_hand (function, NULL, object);

  string_addr = value_as_long (description);
  if (string_addr == 0)
    error (_("object returns null description"));

  read_memory (string_addr + i++, &c, 1);
  if (c != 0)
    do
      { /* Read and print characters up to EOS.  */
	QUIT;
	gdb_printf ("%c", c);
	read_memory (string_addr + i++, &c, 1);
      } while (c != 0);
  else
    gdb_printf(_("<object returns empty description>"));
  gdb_printf ("\n");
}

/* The data structure 'methcalls' is used to detect method calls (through
 * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
 * and ultimately find the method being called.
 */

struct objc_methcall {
  const char *name;
 /* Return instance method to be called.  */
  int (*stop_at) (CORE_ADDR, CORE_ADDR *);
  /* Start of pc range corresponding to method invocation.  */
  CORE_ADDR begin;
  /* End of pc range corresponding to method invocation.  */
  CORE_ADDR end;
};

static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);

static struct objc_methcall methcalls[] = {
  { "_objc_msgSend", resolve_msgsend, 0, 0},
  { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
  { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
  { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
  { "_objc_getClass", NULL, 0, 0},
  { "_objc_getMetaClass", NULL, 0, 0}
};

#define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))

/* The following function, "find_objc_msgsend", fills in the data
 * structure "objc_msgs" by finding the addresses of each of the
 * (currently four) functions that it holds (of which objc_msgSend is
 * the first).  This must be called each time symbols are loaded, in
 * case the functions have moved for some reason.
 */

static void 
find_objc_msgsend (void)
{
  unsigned int i;

  for (i = 0; i < nmethcalls; i++)
    {
      /* Try both with and without underscore.  */
      bound_minimal_symbol func
	= lookup_minimal_symbol (current_program_space, methcalls[i].name);
      if ((func.minsym == NULL) && (methcalls[i].name[0] == '_'))
	{
	  func = lookup_minimal_symbol (current_program_space,
					methcalls[i].name + 1);
	}
      if (func.minsym == NULL)
	{ 
	  methcalls[i].begin = 0;
	  methcalls[i].end = 0;
	  continue; 
	}

      methcalls[i].begin = func.value_address ();
      methcalls[i].end = minimal_symbol_upper_bound (func);
    }
}

/* find_objc_msgcall (replaces pc_off_limits)
 *
 * ALL that this function now does is to determine whether the input
 * address ("pc") is the address of one of the Objective-C message
 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
 * if so, it returns the address of the method that will be called.
 *
 * The old function "pc_off_limits" used to do a lot of other things
 * in addition, such as detecting shared library jump stubs and
 * returning the address of the shlib function that would be called.
 * That functionality has been moved into the gdbarch_skip_trampoline_code and
 * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
 * dependent modules.
 */

static int 
find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
			     CORE_ADDR pc, 
			     CORE_ADDR *new_pc)
{
  try
    {
      if (f (pc, new_pc) == 0)
	return 1;
    }
  catch (const gdb_exception_error &ex)
    {
      exception_fprintf (gdb_stderr, ex,
			 "Unable to determine target of "
			 "Objective-C method call (ignoring):\n");
    }

  return 0;
}

int 
find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
{
  unsigned int i;

  find_objc_msgsend ();
  if (new_pc != NULL)
    {
      *new_pc = 0;
    }

  for (i = 0; i < nmethcalls; i++) 
    if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end)) 
      {
	if (methcalls[i].stop_at != NULL) 
	  return find_objc_msgcall_submethod (methcalls[i].stop_at, 
					      pc, new_pc);
	else 
	  return 0;
      }

  return 0;
}

INIT_GDB_FILE (objc_language)
{
  add_info ("selectors", info_selectors_command,
	    _("All Objective-C selectors, or those matching REGEXP."));
  add_info ("classes", info_classes_command,
	    _("All Objective-C classes, or those matching REGEXP."));
  cmd_list_element *print_object_cmd
    = add_com ("print-object", class_vars, print_object_command,
	       _("Ask an Objective-C object to print itself."));
  add_com_alias ("po", print_object_cmd, class_vars, 1);
}

static void 
read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
		  struct objc_method *method)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  method->name  = read_memory_unsigned_integer (addr + 0, 4, byte_order);
  method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
  method->imp   = read_memory_unsigned_integer (addr + 8, 4, byte_order);
}

static unsigned long
read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  return read_memory_unsigned_integer (addr + 4, 4, byte_order);
}

static void 
read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
			   unsigned long num, struct objc_method *method)
{
  gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
  read_objc_method (gdbarch, addr + 8 + (12 * num), method);
}
  
static void 
read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
		  struct objc_object *object)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
}

static void 
read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
		 struct objc_super *super)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
  super->theclass = read_memory_unsigned_integer (addr + 4, 4, byte_order);
};

static void 
read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
		 struct objc_class *theclass)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  theclass->isa = read_memory_unsigned_integer (addr, 4, byte_order);
  theclass->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
  theclass->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
  theclass->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
  theclass->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
  theclass->instance_size = read_memory_unsigned_integer (addr + 18, 4,
						       byte_order);
  theclass->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
  theclass->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
  theclass->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
  theclass->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
}

static CORE_ADDR
find_implementation_from_class (struct gdbarch *gdbarch,
				CORE_ADDR theclass, CORE_ADDR sel)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR subclass = theclass;

  while (subclass != 0) 
    {

      struct objc_class class_str;
      unsigned mlistnum = 0;

      read_objc_class (gdbarch, subclass, &class_str);

      for (;;) 
	{
	  CORE_ADDR mlist;
	  unsigned long nmethods;
	  unsigned long i;
      
	  mlist = read_memory_unsigned_integer (class_str.methods + 
						(4 * mlistnum),
						4, byte_order);
	  if (mlist == 0) 
	    break;

	  nmethods = read_objc_methlist_nmethods (gdbarch, mlist);

	  for (i = 0; i < nmethods; i++) 
	    {
	      struct objc_method meth_str;

	      read_objc_methlist_method (gdbarch, mlist, i, &meth_str);

	      if (meth_str.name == sel) 
		/* FIXME: hppa arch was doing a pointer dereference
		   here.  There needs to be a better way to do that.  */
		return meth_str.imp;
	    }
	  mlistnum++;
	}
      subclass = class_str.super_class;
    }

  return 0;
}

static CORE_ADDR
find_implementation (struct gdbarch *gdbarch,
		     CORE_ADDR object, CORE_ADDR sel)
{
  struct objc_object ostr;

  if (object == 0)
    return 0;
  read_objc_object (gdbarch, object, &ostr);
  if (ostr.isa == 0)
    return 0;

  return find_implementation_from_class (gdbarch, ostr.isa, sel);
}

static int
resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
{
  frame_info_ptr frame = get_current_frame ();
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;

  CORE_ADDR object;
  CORE_ADDR sel;
  CORE_ADDR res;

  object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);

  res = find_implementation (gdbarch, object, sel);
  if (new_pc != 0)
    *new_pc = res;
  if (res == 0)
    return 1;
  return 0;
}

static int
resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
{
  frame_info_ptr frame = get_current_frame ();
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;

  CORE_ADDR object;
  CORE_ADDR sel;
  CORE_ADDR res;

  object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);

  res = find_implementation (gdbarch, object, sel);
  if (new_pc != 0)
    *new_pc = res;
  if (res == 0)
    return 1;
  return 0;
}

static int
resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
{
  frame_info_ptr frame = get_current_frame ();
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;

  struct objc_super sstr;

  CORE_ADDR super;
  CORE_ADDR sel;
  CORE_ADDR res;

  super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);

  read_objc_super (gdbarch, super, &sstr);
  if (sstr.theclass == 0)
    return 0;
  
  res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
  if (new_pc != 0)
    *new_pc = res;
  if (res == 0)
    return 1;
  return 0;
}

static int
resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
{
  frame_info_ptr frame = get_current_frame ();
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;

  struct objc_super sstr;

  CORE_ADDR super;
  CORE_ADDR sel;
  CORE_ADDR res;

  super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);

  read_objc_super (gdbarch, super, &sstr);
  if (sstr.theclass == 0)
    return 0;
  
  res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
  if (new_pc != 0)
    *new_pc = res;
  if (res == 0)
    return 1;
  return 0;
}
