Restored Objective-C language support

Message ID 3AC64B67-79FD-4F55-8F6E-3784C3C4A13B@crelg.com
State New, archived
Headers

Commit Message

Giah de Barag Sept. 13, 2016, 9:20 p.m. UTC
  2016-09-13  Giah de Barag  <gdb@crelg.com>


Summary
-------

Patches are presented which restore objective-c language support.

These patches are relative to the head of the gdb-7.11-branch.


Impact
------

These changes impact only objective-c language mode.


Description
-----------

These patches enable GDB to (once again) evaluate objective-c
expressions:

(a) [object message:arg] messages,
(b) @"foo" NSStrings, and
(c) @selector(foo:bar:) selectors.
(d) "foo" c strings

These patches complete the previously-unfinished work of merging
objc-exp.y into c-exp.y.


Explanation of Changes
----------------------

Problem 1: Evaluating "foo" c-string literals fails in objective-c
           language mode.

    Description:

        (gdb) set language objective-c
        (gdb) p "hello"
        $1 = <error reading variable>

        Creating a basic C string literal does not work when
        language is objective-c.

    Solution:

        Change objective-c evaluate_subexp_standard to
        evaluate_subexp_c.

    Test:

        The current source language is "auto; currently objective-c".
        (gdb) p strlen("test")
        $1 = 4


Problem 2: Evaluating objc expressions fails in objective-c language
           mode. Examples:

           (a) [object message:arg] messages,
           (b) @"foo" NSStrings, and
           (c) @selector(foo:bar:) selectors.

    Description:

        (gdb) p [@"hello" performSelector:@selector(length)]

        Crashes and burns in many specactular ways, reported in
        bugs 20501 and 20503.

        /* file: c-exp.y */

        exp : NSSTRING
            { write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING);
              write_exp_string (pstate, $1);
              write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING); } ;

        exp : SELECTOR
            { write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR);
              write_exp_string (pstate, $1);
              write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR); } ;

        Communication between scanner and parser is broken; when the
        program attempts to reduce these productions, $1 is null.
        

    Solution:

        Establish communication between the scanner and the parser by
        creating a global variable, last_parsed_token, to hold the last
        scanned token (struct typed_stoken) for string and for selector.

        The existing @selector() scanner was weak. A new, robust
        @selector() scanner was written and inserted to improve quality.

        The string scanner puts a pointer to the last scanned token into
        last_parsed_token (in its choice of object names, gdb sometimes
        conflates the meaning of scanning and parsing, which we went along
        with). The newly-created selector scanner also does the same.

    Test:

        (gdb) p [@"hello" performSelector:@selector(length)]
        $2 = 5
        (gdb)

        Here is another test, more complicated and pedantic, that
        invokes all the features that were broken, creating an
        NSString on the fly and sending it a a message which turns it
        into an NSArray, then sending that NSArray a message which
        sends a message to all its objects and creates another NSArray
        out of the results.

        (gdb) po [[@"(london, paris, rome, berlin)" propertyList]  \
              performSelector:@selector(mappedArrayUsingSelector:) \
                   withObject:@selector(capitalizedString)]
        (London, Paris, Rome, Berlin)
        (gdb)

        This single invocation tests:
        ----------------------------
        * the “po” command
        * creating a literal NSString @"foo" (which responds to messages)
        * sending a message [obj message:arg] to the result of a message
        * referencing a selector @selector(foo) (two different ones in
          one invocation)


Bugs Fixed
----------

These patches fix all bugs reported in:

    https://sourceware.org/bugzilla/show_bug.cgi?id=20501
    https://sourceware.org/bugzilla/show_bug.cgi?id=20503

By the way, this bug is obsolete and should be updated:

    https://sourceware.org/bugzilla/show_bug.cgi?id=11925


Note to GDB Maintainers
-----------------------

Can you adapt these patches to all relevant branches, or do you need me to
provide patches relative to other branches?

I can supply a recipe to build GNUstep if you want to test this patch
yourself.

Also, this is the first time I am doing something like this, so if I am
neglecting any rule of communication of this list, please inform me, and I
will correct it.


Patches
-------

Here are the patches relative to gdb-7.11-branch. Do you need them
relative to the other branches?


----- CUT HERE -----
  

Comments

Tom Tromey Sept. 14, 2016, 10:54 p.m. UTC | #1
>>>>> "Giah" == Giah de Barag <gdb@crelg.com> writes:

Giah> Patches are presented which restore objective-c language support.
Giah> These patches are relative to the head of the gdb-7.11-branch.

I didn't read the patches really, but I feel a bit responsible since I
merged objc-exp.y into c-exp.y back in the day, and apparently not well.

I think the most important thing to do to avoid future problems is make
sure the objc tests are working.  The last time I looked at this, I
think they weren't working properly at all.

Also, it would be good to have new tests for the patches you wrote.

Giah> Also, this is the first time I am doing something like this, so if
Giah> I am neglecting any rule of communication of this list, please
Giah> inform me, and I will correct it.

Nothing wrong with your email but there are some contribution
instructions for gdb:

    https://sourceware.org/gdb/wiki/ContributionChecklist

Tom
  
Matt Rice Sept. 15, 2016, 12:31 a.m. UTC | #2
On Wed, Sep 14, 2016 at 3:54 PM, Tom Tromey <tom@tromey.com> wrote:
>>>>>> "Giah" == Giah de Barag <gdb@crelg.com> writes:
>
> Giah> Patches are presented which restore objective-c language support.
> Giah> These patches are relative to the head of the gdb-7.11-branch.
>
> I didn't read the patches really, but I feel a bit responsible since I
> merged objc-exp.y into c-exp.y back in the day, and apparently not well.
>
> I think the most important thing to do to avoid future problems is make
> sure the objc tests are working.  The last time I looked at this, I
> think they weren't working properly at all.

I Agree, part of the problem is that during some "modernization" of
the objective-c runtime, the "Object" class, the root class that is
distributed with the runtime was neutered basically into
non-existence...

I didn't really manage to catch it before release, and gave up afterwords...

https://github.com/gnustep/libobjc2/blob/master/objc/Object.h
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libobjc/objc/Object.h;h=f69f8139e8c0b0841e806f72747d09ca641dd2f8;hb=refs/heads/trunk

There used to be... methods, in particular there was a method called 'new'
which allowed one to actually allocate and instantiate an object in a
portable fashion.

given that there are about 50 different objective-c runtimes,
It seemed completely out of scope for the gdb testsuite...

I'm not sure what gcc and clang themselves are using to test i'd
imagine the c/runtime specific interface they provide... but it's a
bit inconvenient for a project like gdb that sits between gcc and
something external like gnustep (which provides its own mechanism for
instantiating objects).

> Also, it would be good to have new tests for the patches you wrote.
>
> Giah> Also, this is the first time I am doing something like this, so if
> Giah> I am neglecting any rule of communication of this list, please
> Giah> inform me, and I will correct it.
>
> Nothing wrong with your email but there are some contribution
> instructions for gdb:
>
>     https://sourceware.org/gdb/wiki/ContributionChecklist
>
> Tom
  
Giah de Barag Sept. 15, 2016, 7:12 p.m. UTC | #3
GDB and Objective C
-------------------

1. GDB Objective C Language Support
2. How GDB Creates Objective C NSString Objects
3. How GDB Looks Up Objective C Selectors
4. GNUstep Source & Build Scripts
5. GNUstep and GDB Test
6. Questions Regarding the Patch


1. GDB Objective C Language Support
-----------------------------------

GDB support for Objective C (GCC libobjc and GNUstep) is deep,
powerful, and way beyond mature. The transition from Object to
NSObject was made somewhere around 1990.

GNUstep is *the* (the) GNU library of Objective C high-level types
(string, array, dictionary, set, process, thread, file, etc).

GCC libobjc is one of the two (2) low-level implementations of the
object-oriented runtime design (object, method, selector, etc.) that
work with GCC/GDB.

GNUstep is a part of the GNU software collection, is trivial to build
and package, and is a package on GNU-type system distributions.

GDB’s Objective C language support code has interacted with GNUstep
and the NSObject hierarchy for decades. That code is simple, easy to
understand, and easy to maintain.


2. How GDB Creates Objective C NSString Objects
-----------------------------------------------

Here is a look at part of the GDB/GNUstep debugger API.

In this example, GDB creates a GNUstep NSString when the user types
@"foo". It looks for a convenience function _NSNewStringFromCString,
and if not found, it sends the message stringWithCString to the
GNUstep class NSString.

  if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym)
    {
      function = find_function_in_inferior("_NSNewStringFromCString", NULL);
      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
    }
  else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym)
    {
      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, 3, &stringValue[0]);
    }
  else
    error (_("NSString: internal error -- no way to create new NSString"));

In http://svn.gna.org/svn/gnustep/libs/base/trunk/Source/NSDebug.m,
which is in the GNUstep repository, at the very end of the file, you
can see the implementation of _NSNewStringFromCString. Also there is
the function _NSPrintForDebugger which handles the “po” (print object)
command of GDB.

    // GNUstep debugger support functions
    NSString *_NSNewStringFromCString(const char *cstring);
    const char *_NSPrintForDebugger(id object);


3. How GDB Looks Up Objective C Selectors
-----------------------------------------

Here is GDB’s code that looks up a selector.

In the previous example, GDB addressed GNUstep, the high-level type
library, to create an Objective C string (NSString), and here we are
interacting with the low-level runtime library, GCC libobjc, and its
function sel_getUid.

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

In https://github.com/gcc-mirror/gcc/blob/master/libobjc/selector.c at the
very end you can see sel_getUid, which takes the string name representing a
method and returns the selector for it, SEL sel_getUid (const char *name).


4. GNUstep Source & Build Scripts
---------------------------------

GNUstep is trivial to install. If it is not a package, you can check
it out and build it.

You only need the “base” library which implements the basic high-level
types like NSString and has the GDB debugger support functions.

Source:
  svn co http://svn.gna.org/svn/gnustep/modules/core

  (For GDB Objective C language support,
  only “make” and “base” are needed.)

Build Scripts:
  http://svn.gna.org/svn/gnustep/tools/scripts/trunk/

It would be good for the teams (GCC/GDB/GNUstep) to be more in step
with each other. What do you think?


5. GNUstep and GDB Test
-----------------------

This is a test of:

    a) printing an object with po
    b) sending a message with [obj msg:arg]
    c) creating an NSString with @"foo"
    d) looking up a selector with @selector(msg)

GDB console session:

    (gdb) po [@"foo" performSelector:@selector(uppercaseString)]
    FOO
    (gdb) 


6. Questions Regarding the Patch
--------------------------------

FAOD:

1. About the Contribution Checklist. Do you need me to update this
   patch to conform to the Contribution Checklist?

2. About tests. Are there in fact no automated tests for objective-c
   support, and do you need me to create them?

3. Are there any barriers to this patch getting into 7.11, 7.12, and
   master (other than the above two questions)?

Thank you.
  
Giah de Barag Sept. 16, 2016, 5:52 a.m. UTC | #4
> On Sep 14, 2016, at 18:54, Tom Tromey <tom@tromey.com> wrote:
> 
> I think the most important thing to do to
> avoid future problems is make sure the objc
> tests are working. The last time I looked at
> this, I think they weren't working properly at
> all.
> 
> Also, it would be good to have new tests for
> the patches you wrote.

I will work on fixing the broken tests and
writing new tests for the patches I
submitted.

(Ignore the question about tests in my
previous message.)
  
Giah de Barag Sept. 27, 2016, 8:11 p.m. UTC | #5
2016-09-27  Giah de Barag  <gdb@crelg.com>


Summary
-------

This new patch restores a newly-discovered removed piece of objective-c
language support.

This piece (like those previously reported) seems to have been
inadvertently removed when objc-eval.y was deleted.


Problem Behavior
----------------

This problem surfaces when typecasting an object pointer to a class type
(in order to dereference it and examine its member variables).

(gdb) p (NSAutoreleasePool *)pool
A syntax error in expression, near `NSAutoreleasePool *)pool'.
(gdb)


Correction
----------

Applying this patch corrects the problem by simply restoring a rule from
objc-eval.y (that was lost when objc-eval.y was deleted).


Corrected Behavior
------------------

After applying the patch, the problem disappears and the missing
language support reappears. Here is a pointer to an object being
typecast in order to be dereferenced.

(gdb) p (NSAutoreleasePool *)pool
$2 = (struct NSAutoreleasePool *) 0x6e0a58
(gdb) p *$
$3 =
{
  {
    isa = 0x671fee80 <_OBJC_Class_NSAutoreleasePool>
  },
  _parent = 0x0,
  _child = 0x0,
  _released = 0x4c15818,
  _released_head = 0x6e1178,
  _released_count = 8889,
  _addImp = 0x670219fa <-[NSAutoreleasePool addObject:]>,
  _internal = 0x0
}
(gdb)


Patch
-----

Here is the patch. It restores one rule from objc-eval.y.

----- CUT HERE -----
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
@@ -1216,6 +1221,14 @@ type	:	ptype
 typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
 	:	TYPENAME
 			{ $$ = $1.type; }
+	|	CLASSNAME
+			{
+			  if ($1.type == NULL)
+			    error ("No symbol \"%s\" in current context.", 
+				   copy_name($1.stoken));
+			  else
+			    $$ = $1.type;
+			}
 	|	INT_KEYWORD
 			{ $$ = lookup_signed_typename (parse_language (pstate),
 						       parse_gdbarch (pstate),
----- CUT HERE -----
  
Tom Tromey Oct. 12, 2016, 2:14 a.m. UTC | #6
>>>>> "Giah" == Giah de Barag <gdb@crelg.com> writes:

Giah> This new patch restores a newly-discovered removed piece of
Giah> objective-c language support.

Giah> This piece (like those previously reported) seems to have been
Giah> inadvertently removed when objc-eval.y was deleted.

I think the thing to do is (1) make sure the tests work, and (2) re-send
the patches following the usual contribution instructions, in particular
with a ChangeLog entry.

With that, assuming your copyright assignment is up to date, I wouldn't
expect many problems.

Tom
  

Patch

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f99a7ab..d3a5a44 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -10563,6 +10563,7 @@  watchpoint_exp_is_const (const struct expression *exp)
 	case OP_TYPEID:
 	case OP_NAME:
 	case OP_OBJC_NSSTRING:
+	case OP_OBJC_SELECTOR:
 
 	case UNOP_NEG:
 	case UNOP_LOGICAL_NOT:
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 9f2a229..4a6b0b0 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -129,6 +129,8 @@  void yyerror (char *);
 
 static int type_aggregate_p (struct type *);
 
+static struct typed_stoken *last_parsed_token;
+
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -175,6 +177,8 @@  static struct stoken operator_stoken (const char *);
 static void check_parameter_typelist (VEC (type_ptr) *);
 static void write_destructor_name (struct parser_state *par_state,
 				   struct stoken);
+static void write_exp_nsstring (struct parser_state *par_state, struct typed_stoken *token);
+static void write_exp_selector (struct parser_state *par_state, struct typed_stoken *token);
 
 #ifdef YYBISON
 static void c_print_token (FILE *file, int type, YYSTYPE value);
@@ -209,7 +213,7 @@  static void c_print_token (FILE *file, int type, YYSTYPE value);
 
 %token <tsval> STRING
 %token <sval> NSSTRING		/* ObjC Foundation "NSString" literal */
-%token SELECTOR			/* ObjC "@selector" pseudo-operator   */
+%token <sval> SELECTOR		/* ObjC "@selector" pseudo-operator   */
 %token <tsval> CHAR
 %token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
 %token <ssym> UNKNOWN_CPP_NAME
@@ -779,10 +783,11 @@  exp	:	VARIABLE
 			}
 	;
 
-exp	:	SELECTOR '(' name ')'
-			{
-			  write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR);
-			  write_exp_string (pstate, $3);
+exp	:	SELECTOR	/* ObjC selector literal
+				 * of the form @selector(foo:bar:)
+				 */
+			{ write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR);
+			  write_exp_selector   (pstate, last_parsed_token);
 			  write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR); }
 	;
 
@@ -894,11 +899,11 @@  exp	:	string_exp
 			}
 	;
 
-exp     :	NSSTRING	/* ObjC NextStep NSString constant
-				 * of the form '@' '"' string '"'.
+exp     :	NSSTRING	/* ObjC GNUstep NSString literal
+				 * of the form @"foo"
 				 */
 			{ write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING);
-			  write_exp_string (pstate, $1);
+			  write_exp_nsstring   (pstate, last_parsed_token);
 			  write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING); }
 	;
 
@@ -1659,6 +1664,26 @@  name_not_typename :	NAME
 
 %%
 
+static void
+write_exp_nsstring (struct parser_state *par_state, struct typed_stoken *value)
+/* Like write_exp_string, but for Objective C NSString literal, @"foo" */
+{
+  struct stoken token;
+  token.length = value->length;
+  token.ptr    = value->ptr;
+  write_exp_string (par_state, token);
+}
+
+static void
+write_exp_selector (struct parser_state *par_state, struct typed_stoken *value)
+/* Like write_exp_string, but for Objective C selector macro, @selector(foo:bar:) */
+{
+  struct stoken token;
+  token.length = value->length;
+  token.ptr    = value->ptr;
+  write_exp_string (par_state, token);
+}
+
 /* Like write_exp_string, but prepends a '~'.  */
 
 static void
@@ -2250,11 +2275,113 @@  parse_string_or_char (const char *tokptr, const char **outptr,
   value->ptr = (char *) obstack_base (&tempbuf);
   value->length = obstack_object_size (&tempbuf);
 
+  last_parsed_token = value;
+
   *outptr = tokptr;
 
   return quote == '"' ? (is_objc ? NSSTRING : STRING) : CHAR;
 }
 
+/* Scan an objc selector literal (described by the following regex) from
+   TOKEN_STREAM, place $1 (the value inside the literal parens) into VALUE
+   and return a pointer to the next input in the token_stream.
+ 
+       @?selector\(([0-9A-Za-z_:-]+)\)                                    
+ */
+static const char * 
+parse_objc_selector_literal (const char *tokptr, struct typed_stoken *value)
+{
+  const char	*s1  = NULL;
+  const char	*s2  = NULL;
+  const char	*str = NULL;	/* not null-terminated, just a pointer into token_stream */
+  int		 len = 0;
+  static unsigned sl;
+
+  /* skip any leading whitespace */
+  s1 = tokptr;
+  s1 = skip_spaces_const (s1);
+
+  /* parse the '@' */
+  if (*s1 == '@')
+    s1++;
+  s1 = skip_spaces_const (s1);
+
+  /* parse the word "selector" */
+  if (!sl)
+    sl = strlen("selector");
+  if (strncmp (s1, "selector", sl) != 0)
+    {
+      /* error (_("malformed @selector() macro: expected 'selector'")); */
+      return NULL;
+    }
+  s1 += sl;
+  s1 = skip_spaces_const (s1);
+
+  /* parse the open paren */
+  if (*s1 != '(')
+    {
+      error (_("malformed @selector() macro: expected '('"));
+      return NULL;
+    }
+  s1++;
+  s1 = skip_spaces_const (s1);
+  
+  str = s1;
+  s2  = s1;
+
+  /* parse the selector string [0-9A-Za-z_: -]) */
+  for (;;)
+    {
+      if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':') || (*s2 == '-'))
+	;
+      else if (*s2 == ')' || isspace(*s2))
+	break;
+      else
+	{
+	  int buflen = s2 - s1;
+	  if (!tempbuf_init)
+	    tempbuf_init = 1;
+	  else
+	    obstack_free (&tempbuf, NULL);
+	  obstack_init (&tempbuf);
+	  obstack_grow (&tempbuf, str, buflen);
+	  obstack_1grow (&tempbuf, '\0');
+	  error ("illegal selector: \"%s\"", tempbuf);
+	  obstack_free (&tempbuf, NULL);
+	  return NULL;
+	}
+      s2++;
+    }
+  len = s2 - s1;
+
+  /* slurp up spaces if terminator was ')' */
+  s2++;
+  s2 = skip_spaces_const (s2);
+
+  /* slurp up ')' if terminator was space(s) */
+  if (*s2 == ')')
+      s2++;
+  s2 = skip_spaces_const (s2);
+
+  /* save the token for reference in the productions */
+  gdb_assert (value != NULL);
+  if (!tempbuf_init)
+      tempbuf_init = 1;
+  else
+      obstack_free (&tempbuf, NULL);
+
+  obstack_init (&tempbuf);
+  obstack_grow (&tempbuf, str, len);
+
+  value->type   = SELECTOR;
+  value->ptr    = (char *) obstack_base (&tempbuf);
+  value->length = obstack_object_size (&tempbuf);
+
+  last_parsed_token = value;
+
+  return s2;
+}
+
 /* This is used to associate some attributes with a token.  */
 
 enum token_flag
@@ -2655,14 +2782,14 @@  lex_one_token (struct parser_state *par_state, int *is_quoted_name)
 
 	if (parse_language (par_state)->la_language == language_objc)
 	  {
-	    size_t len = strlen ("selector");
-
-	    if (strncmp (p, "selector", len) == 0
-		&& (p[len] == '\0' || isspace (p[len])))
+	    /* try to parse a selector literal */
+	    const char *newlexptr = parse_objc_selector_literal(p, &yylval.tsval);
+	    if (newlexptr != NULL)
 	      {
-		lexptr = p + len;
+		lexptr = newlexptr; /* p + yylval.tsval.length */
 		return SELECTOR;
 	      }
+	    /* there was no selector so try to parse a string literal */
 	    else if (*p == '"')
 	      goto parse_string;
 	  }
@@ -3291,6 +3418,7 @@  c_print_token (FILE *file, int type, YYSTYPE value)
       break;
 
     case NSSTRING:
+    case SELECTOR:
     case VARIABLE:
       fprintf (file, "sval<%s>", copy_name (value.sval));
       break;
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index f58b1c4..d7ec15b 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -339,6 +339,7 @@  static const struct op_print objc_op_print_tab[] =
     {"/",  BINOP_DIV, PREC_MUL, 0},
     {"%",  BINOP_REM, PREC_MUL, 0},
     {"@",  BINOP_REPEAT, PREC_REPEAT, 0},
+    {"+",  UNOP_PLUS, PREC_PREFIX, 0},
     {"-",  UNOP_NEG, PREC_PREFIX, 0},
     {"!",  UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
     {"~",  UNOP_COMPLEMENT, PREC_PREFIX, 0},
@@ -358,7 +359,7 @@  const struct language_defn objc_language_defn = {
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
-  &exp_descriptor_standard,
+  &exp_descriptor_c,
   c_parse,
   c_error,
   null_post_parser,
@@ -385,7 +386,7 @@  const struct language_defn objc_language_defn = {
   c_language_arch_info,
   default_print_array_index,
   default_pass_by_reference,
-  default_get_string,
+  c_get_string,
   NULL,				/* la_get_symbol_name_cmp */
   iterate_over_symbols,
   &default_varobj_ops,