Add some more casts (2/2)
[deliverable/binutils-gdb.git] / gdb / python / py-xmethods.c
1 /* Support for debug methods in Python.
2
3 Copyright (C) 2013-2015 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "extension-priv.h"
23 #include "objfiles.h"
24 #include "value.h"
25 #include "language.h"
26
27 #include "python.h"
28 #include "python-internal.h"
29
30 static const char enabled_field_name[] = "enabled";
31 static const char match_method_name[] = "match";
32 static const char get_arg_types_method_name[] = "get_arg_types";
33 static const char get_result_type_method_name[] = "get_result_type";
34 static const char invoke_method_name[] = "invoke";
35 static const char matchers_attr_str[] = "xmethods";
36
37 static PyObject *py_match_method_name = NULL;
38 static PyObject *py_get_arg_types_method_name = NULL;
39 static PyObject *py_get_result_type_method_name = NULL;
40 static PyObject *py_invoke_method_name = NULL;
41
42 struct gdbpy_worker_data
43 {
44 PyObject *worker;
45 PyObject *this_type;
46 };
47
48 static struct xmethod_worker *new_python_xmethod_worker (PyObject *item,
49 PyObject *py_obj_type);
50
51 /* Implementation of free_xmethod_worker_data for Python. */
52
53 void
54 gdbpy_free_xmethod_worker_data (const struct extension_language_defn *extlang,
55 void *data)
56 {
57 struct gdbpy_worker_data *worker_data = (struct gdbpy_worker_data *) data;
58 struct cleanup *cleanups;
59
60 gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
61
62 /* We don't do much here, but we still need the GIL. */
63 cleanups = ensure_python_env (get_current_arch (), current_language);
64
65 Py_DECREF (worker_data->worker);
66 Py_DECREF (worker_data->this_type);
67 xfree (worker_data);
68
69 do_cleanups (cleanups);
70 }
71
72 /* Implementation of clone_xmethod_worker_data for Python. */
73
74 void *
75 gdbpy_clone_xmethod_worker_data (const struct extension_language_defn *extlang,
76 void *data)
77 {
78 struct gdbpy_worker_data *worker_data
79 = (struct gdbpy_worker_data *) data, *new_data;
80 struct cleanup *cleanups;
81
82 gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
83
84 /* We don't do much here, but we still need the GIL. */
85 cleanups = ensure_python_env (get_current_arch (), current_language);
86
87 new_data = XCNEW (struct gdbpy_worker_data);
88 new_data->worker = worker_data->worker;
89 new_data->this_type = worker_data->this_type;
90 Py_INCREF (new_data->worker);
91 Py_INCREF (new_data->this_type);
92
93 do_cleanups (cleanups);
94
95 return new_data;
96 }
97
98 /* Invoke the "match" method of the MATCHER and return a new reference
99 to the result. Returns NULL on error. */
100
101 static PyObject *
102 invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
103 const char *xmethod_name)
104 {
105 PyObject *py_xmethod_name;
106 PyObject *match_method, *enabled_field, *match_result;
107 struct cleanup *cleanups;
108 int enabled;
109
110 cleanups = make_cleanup (null_cleanup, NULL);
111
112 enabled_field = PyObject_GetAttrString (matcher, enabled_field_name);
113 if (enabled_field == NULL)
114 {
115 do_cleanups (cleanups);
116 return NULL;
117 }
118 make_cleanup_py_decref (enabled_field);
119
120 enabled = PyObject_IsTrue (enabled_field);
121 if (enabled == -1)
122 {
123 do_cleanups (cleanups);
124 return NULL;
125 }
126 if (enabled == 0)
127 {
128 /* Return 'None' if the matcher is not enabled. */
129 do_cleanups (cleanups);
130 Py_RETURN_NONE;
131 }
132
133 match_method = PyObject_GetAttrString (matcher, match_method_name);
134 if (match_method == NULL)
135 {
136 do_cleanups (cleanups);
137 return NULL;
138 }
139 make_cleanup_py_decref (match_method);
140
141 py_xmethod_name = PyString_FromString (xmethod_name);
142 if (py_xmethod_name == NULL)
143 {
144 do_cleanups (cleanups);
145 return NULL;
146 }
147 make_cleanup_py_decref (py_xmethod_name);
148
149 match_result = PyObject_CallMethodObjArgs (matcher,
150 py_match_method_name,
151 py_obj_type,
152 py_xmethod_name,
153 NULL);
154
155 do_cleanups (cleanups);
156
157 return match_result;
158 }
159
160 /* Implementation of get_matching_xmethod_workers for Python. */
161
162 enum ext_lang_rc
163 gdbpy_get_matching_xmethod_workers
164 (const struct extension_language_defn *extlang,
165 struct type *obj_type, const char *method_name,
166 xmethod_worker_vec **dm_vec)
167 {
168 struct cleanup *cleanups;
169 struct objfile *objfile;
170 VEC (xmethod_worker_ptr) *worker_vec = NULL;
171 PyObject *py_type, *py_progspace;
172 PyObject *py_xmethod_matcher_list = NULL, *list_iter, *matcher;
173
174 gdb_assert (obj_type != NULL && method_name != NULL);
175
176 cleanups = ensure_python_env (get_current_arch (), current_language);
177
178 py_type = type_to_type_object (obj_type);
179 if (py_type == NULL)
180 {
181 gdbpy_print_stack ();
182 do_cleanups (cleanups);
183
184 return EXT_LANG_RC_ERROR;
185 }
186 make_cleanup_py_decref (py_type);
187
188 /* Create an empty list of debug methods. */
189 py_xmethod_matcher_list = PyList_New (0);
190 if (py_xmethod_matcher_list == NULL)
191 {
192 gdbpy_print_stack ();
193 do_cleanups (cleanups);
194
195 return EXT_LANG_RC_ERROR;
196 }
197
198 /* Gather debug method matchers registered with the object files.
199 This could be done differently by iterating over each objfile's matcher
200 list individually, but there's no data yet to show it's needed. */
201 ALL_OBJFILES (objfile)
202 {
203 PyObject *py_objfile = objfile_to_objfile_object (objfile);
204 PyObject *objfile_matchers, *temp = py_xmethod_matcher_list;
205
206 if (py_objfile == NULL)
207 {
208 gdbpy_print_stack ();
209 Py_DECREF (py_xmethod_matcher_list);
210 do_cleanups (cleanups);
211
212 return EXT_LANG_RC_ERROR;
213 }
214
215 objfile_matchers = objfpy_get_xmethods (py_objfile, NULL);
216 py_xmethod_matcher_list = PySequence_Concat (temp, objfile_matchers);
217 Py_DECREF (temp);
218 Py_DECREF (objfile_matchers);
219 if (py_xmethod_matcher_list == NULL)
220 {
221 gdbpy_print_stack ();
222 do_cleanups (cleanups);
223
224 return EXT_LANG_RC_ERROR;
225 }
226 }
227
228 /* Gather debug methods matchers registered with the current program
229 space. */
230 py_progspace = pspace_to_pspace_object (current_program_space);
231 if (py_progspace != NULL)
232 {
233 PyObject *temp = py_xmethod_matcher_list;
234 PyObject *pspace_matchers = pspy_get_xmethods (py_progspace, NULL);
235
236 py_xmethod_matcher_list = PySequence_Concat (temp, pspace_matchers);
237 Py_DECREF (temp);
238 Py_DECREF (pspace_matchers);
239 if (py_xmethod_matcher_list == NULL)
240 {
241 gdbpy_print_stack ();
242 do_cleanups (cleanups);
243
244 return EXT_LANG_RC_ERROR;
245 }
246 }
247 else
248 {
249 gdbpy_print_stack ();
250 Py_DECREF (py_xmethod_matcher_list);
251 do_cleanups (cleanups);
252
253 return EXT_LANG_RC_ERROR;
254 }
255
256 /* Gather debug method matchers registered globally. */
257 if (gdb_python_module != NULL
258 && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
259 {
260 PyObject *gdb_matchers;
261 PyObject *temp = py_xmethod_matcher_list;
262
263 gdb_matchers = PyObject_GetAttrString (gdb_python_module,
264 matchers_attr_str);
265 if (gdb_matchers != NULL)
266 {
267 py_xmethod_matcher_list = PySequence_Concat (temp, gdb_matchers);
268 Py_DECREF (temp);
269 Py_DECREF (gdb_matchers);
270 if (py_xmethod_matcher_list == NULL)
271 {
272 gdbpy_print_stack ();
273 do_cleanups (cleanups);
274
275 return EXT_LANG_RC_ERROR;
276 }
277 }
278 else
279 {
280 gdbpy_print_stack ();
281 Py_DECREF (py_xmethod_matcher_list);
282 do_cleanups (cleanups);
283
284 return EXT_LANG_RC_ERROR;
285 }
286 }
287
288 /* Safe to make a cleanup for py_xmethod_matcher_list now as it
289 will not change any more. */
290 make_cleanup_py_decref (py_xmethod_matcher_list);
291
292 list_iter = PyObject_GetIter (py_xmethod_matcher_list);
293 if (list_iter == NULL)
294 {
295 gdbpy_print_stack ();
296 do_cleanups (cleanups);
297
298 return EXT_LANG_RC_ERROR;
299 }
300 while ((matcher = PyIter_Next (list_iter)) != NULL)
301 {
302 PyObject *match_result = invoke_match_method (matcher, py_type,
303 method_name);
304
305 if (match_result == NULL)
306 {
307 gdbpy_print_stack ();
308 Py_DECREF (matcher);
309 do_cleanups (cleanups);
310
311 return EXT_LANG_RC_ERROR;
312 }
313 if (match_result == Py_None)
314 ; /* This means there was no match. */
315 else if (PySequence_Check (match_result))
316 {
317 PyObject *iter = PyObject_GetIter (match_result);
318 PyObject *py_worker;
319
320 if (iter == NULL)
321 {
322 gdbpy_print_stack ();
323 Py_DECREF (matcher);
324 Py_DECREF (match_result);
325 do_cleanups (cleanups);
326
327 return EXT_LANG_RC_ERROR;
328 }
329 while ((py_worker = PyIter_Next (iter)) != NULL)
330 {
331 struct xmethod_worker *worker;
332
333 worker = new_python_xmethod_worker (py_worker, py_type);
334 VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
335 Py_DECREF (py_worker);
336 }
337 Py_DECREF (iter);
338 /* Report any error that could have occurred while iterating. */
339 if (PyErr_Occurred ())
340 {
341 gdbpy_print_stack ();
342 Py_DECREF (matcher);
343 Py_DECREF (match_result);
344 do_cleanups (cleanups);
345
346 return EXT_LANG_RC_ERROR;
347 }
348 }
349 else
350 {
351 struct xmethod_worker *worker;
352
353 worker = new_python_xmethod_worker (match_result, py_type);
354 VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
355 }
356
357 Py_DECREF (match_result);
358 Py_DECREF (matcher);
359 }
360 Py_DECREF (list_iter);
361 /* Report any error that could have occurred while iterating. */
362 if (PyErr_Occurred ())
363 {
364 gdbpy_print_stack ();
365 do_cleanups (cleanups);
366
367 return EXT_LANG_RC_ERROR;
368 }
369
370 do_cleanups (cleanups);
371 *dm_vec = worker_vec;
372
373 return EXT_LANG_RC_OK;
374 }
375
376 /* Implementation of get_xmethod_arg_types for Python. */
377
378 enum ext_lang_rc
379 gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
380 struct xmethod_worker *worker,
381 int *nargs, struct type ***arg_types)
382 {
383 struct gdbpy_worker_data *worker_data
384 = (struct gdbpy_worker_data *) worker->data;
385 PyObject *py_worker = worker_data->worker;
386 PyObject *get_arg_types_method;
387 PyObject *py_argtype_list, *list_iter = NULL, *item;
388 struct cleanup *cleanups;
389 struct type **type_array, *obj_type;
390 int i = 1, arg_count;
391
392 /* Set nargs to -1 so that any premature return from this function returns
393 an invalid/unusable number of arg types. */
394 *nargs = -1;
395
396 cleanups = ensure_python_env (get_current_arch (), current_language);
397
398 get_arg_types_method = PyObject_GetAttrString (py_worker,
399 get_arg_types_method_name);
400 if (get_arg_types_method == NULL)
401 {
402 gdbpy_print_stack ();
403 do_cleanups (cleanups);
404
405 return EXT_LANG_RC_ERROR;
406 }
407 make_cleanup_py_decref (get_arg_types_method);
408
409 py_argtype_list = PyObject_CallMethodObjArgs (py_worker,
410 py_get_arg_types_method_name,
411 NULL);
412 if (py_argtype_list == NULL)
413 {
414 gdbpy_print_stack ();
415 do_cleanups (cleanups);
416
417 return EXT_LANG_RC_ERROR;
418 }
419 make_cleanup_py_decref (py_argtype_list);
420 if (py_argtype_list == Py_None)
421 arg_count = 0;
422 else if (PySequence_Check (py_argtype_list))
423 {
424 arg_count = PySequence_Size (py_argtype_list);
425 if (arg_count == -1)
426 {
427 gdbpy_print_stack ();
428 do_cleanups (cleanups);
429
430 return EXT_LANG_RC_ERROR;
431 }
432
433 list_iter = PyObject_GetIter (py_argtype_list);
434 if (list_iter == NULL)
435 {
436 gdbpy_print_stack ();
437 do_cleanups (cleanups);
438
439 return EXT_LANG_RC_ERROR;
440 }
441 make_cleanup_py_decref (list_iter);
442 }
443 else
444 arg_count = 1;
445
446 /* Include the 'this' argument in the size. */
447 type_array = XCNEWVEC (struct type *, arg_count + 1);
448 i = 1;
449 if (list_iter != NULL)
450 {
451 while ((item = PyIter_Next (list_iter)) != NULL)
452 {
453 struct type *arg_type = type_object_to_type (item);
454
455 Py_DECREF (item);
456 if (arg_type == NULL)
457 {
458 PyErr_SetString (PyExc_TypeError,
459 _("Arg type returned by the get_arg_types "
460 "method of a debug method worker object is "
461 "not a gdb.Type object."));
462 break;
463 }
464
465 type_array[i] = arg_type;
466 i++;
467 }
468 }
469 else if (arg_count == 1)
470 {
471 /* py_argtype_list is not actually a list but a single gdb.Type
472 object. */
473 struct type *arg_type = type_object_to_type (py_argtype_list);
474
475 if (arg_type == NULL)
476 {
477 PyErr_SetString (PyExc_TypeError,
478 _("Arg type returned by the get_arg_types method "
479 "of an xmethod worker object is not a gdb.Type "
480 "object."));
481 }
482 else
483 {
484 type_array[i] = arg_type;
485 i++;
486 }
487 }
488 if (PyErr_Occurred ())
489 {
490 gdbpy_print_stack ();
491 do_cleanups (cleanups);
492 xfree (type_array);
493
494 return EXT_LANG_RC_ERROR;
495 }
496
497 /* Add the type of 'this' as the first argument. The 'this' pointer should
498 be a 'const' value. Hence, create a 'const' variant of the 'this' pointer
499 type. */
500 obj_type = type_object_to_type (worker_data->this_type);
501 type_array[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type), NULL);
502 *nargs = i;
503 *arg_types = type_array;
504 do_cleanups (cleanups);
505
506 return EXT_LANG_RC_OK;
507 }
508
509 /* Implementation of get_xmethod_result_type for Python. */
510
511 enum ext_lang_rc
512 gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
513 struct xmethod_worker *worker,
514 struct value *obj,
515 struct value **args, int nargs,
516 struct type **result_type_ptr)
517 {
518 struct gdbpy_worker_data *worker_data
519 = (struct gdbpy_worker_data *) worker->data;
520 PyObject *py_worker = worker_data->worker;
521 PyObject *py_value_obj, *py_arg_tuple, *py_result_type;
522 PyObject *get_result_type_method;
523 struct type *obj_type, *this_type;
524 struct cleanup *cleanups;
525 int i;
526
527 cleanups = ensure_python_env (get_current_arch (), current_language);
528
529 /* First see if there is a get_result_type method.
530 If not this could be an old xmethod (pre 7.9.1). */
531 get_result_type_method
532 = PyObject_GetAttrString (py_worker, get_result_type_method_name);
533 if (get_result_type_method == NULL)
534 {
535 PyErr_Clear ();
536 do_cleanups (cleanups);
537 *result_type_ptr = NULL;
538 return EXT_LANG_RC_OK;
539 }
540 make_cleanup_py_decref (get_result_type_method);
541
542 obj_type = check_typedef (value_type (obj));
543 this_type = check_typedef (type_object_to_type (worker_data->this_type));
544 if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
545 {
546 struct type *this_ptr = lookup_pointer_type (this_type);
547
548 if (!types_equal (obj_type, this_ptr))
549 obj = value_cast (this_ptr, obj);
550 }
551 else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
552 {
553 struct type *this_ref = lookup_reference_type (this_type);
554
555 if (!types_equal (obj_type, this_ref))
556 obj = value_cast (this_ref, obj);
557 }
558 else
559 {
560 if (!types_equal (obj_type, this_type))
561 obj = value_cast (this_type, obj);
562 }
563 py_value_obj = value_to_value_object (obj);
564 if (py_value_obj == NULL)
565 goto Fail;
566 make_cleanup_py_decref (py_value_obj);
567
568 py_arg_tuple = PyTuple_New (nargs + 1);
569 if (py_arg_tuple == NULL)
570 goto Fail;
571 make_cleanup_py_decref (py_arg_tuple);
572
573 /* PyTuple_SET_ITEM steals the reference of the element. Hence INCREF the
574 reference to the 'this' object as we have a cleanup to DECREF it. */
575 Py_INCREF (py_value_obj);
576 PyTuple_SET_ITEM (py_arg_tuple, 0, py_value_obj);
577
578 for (i = 0; i < nargs; i++)
579 {
580 PyObject *py_value_arg = value_to_value_object (args[i]);
581
582 if (py_value_arg == NULL)
583 goto Fail;
584 PyTuple_SET_ITEM (py_arg_tuple, i + 1, py_value_arg);
585 }
586
587 py_result_type = PyObject_CallObject (get_result_type_method, py_arg_tuple);
588 if (py_result_type == NULL)
589 goto Fail;
590 make_cleanup_py_decref (py_result_type);
591
592 *result_type_ptr = type_object_to_type (py_result_type);
593 if (*result_type_ptr == NULL)
594 {
595 PyErr_SetString (PyExc_TypeError,
596 _("Type returned by the get_result_type method of an"
597 " xmethod worker object is not a gdb.Type object."));
598 goto Fail;
599 }
600
601 do_cleanups (cleanups);
602 return EXT_LANG_RC_OK;
603
604 Fail:
605 gdbpy_print_stack ();
606 do_cleanups (cleanups);
607 return EXT_LANG_RC_ERROR;
608 }
609
610 /* Implementation of invoke_xmethod for Python. */
611
612 struct value *
613 gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
614 struct xmethod_worker *worker,
615 struct value *obj, struct value **args, int nargs)
616 {
617 int i;
618 struct cleanup *cleanups;
619 PyObject *py_value_obj, *py_arg_tuple, *py_result;
620 struct type *obj_type, *this_type;
621 struct value *res = NULL;
622 struct gdbpy_worker_data *worker_data
623 = (struct gdbpy_worker_data *) worker->data;
624 PyObject *xmethod_worker = worker_data->worker;
625
626 cleanups = ensure_python_env (get_current_arch (), current_language);
627
628 obj_type = check_typedef (value_type (obj));
629 this_type = check_typedef (type_object_to_type (worker_data->this_type));
630 if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
631 {
632 struct type *this_ptr = lookup_pointer_type (this_type);
633
634 if (!types_equal (obj_type, this_ptr))
635 obj = value_cast (this_ptr, obj);
636 }
637 else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
638 {
639 struct type *this_ref = lookup_reference_type (this_type);
640
641 if (!types_equal (obj_type, this_ref))
642 obj = value_cast (this_ref, obj);
643 }
644 else
645 {
646 if (!types_equal (obj_type, this_type))
647 obj = value_cast (this_type, obj);
648 }
649 py_value_obj = value_to_value_object (obj);
650 if (py_value_obj == NULL)
651 {
652 gdbpy_print_stack ();
653 error (_("Error while executing Python code."));
654 }
655 make_cleanup_py_decref (py_value_obj);
656
657 py_arg_tuple = PyTuple_New (nargs + 1);
658 if (py_arg_tuple == NULL)
659 {
660 gdbpy_print_stack ();
661 error (_("Error while executing Python code."));
662 }
663 make_cleanup_py_decref (py_arg_tuple);
664
665 /* PyTuple_SET_ITEM steals the reference of the element. Hence INCREF the
666 reference to the 'this' object as we have a cleanup to DECREF it. */
667 Py_INCREF (py_value_obj);
668 PyTuple_SET_ITEM (py_arg_tuple, 0, py_value_obj);
669
670 for (i = 0; i < nargs; i++)
671 {
672 PyObject *py_value_arg = value_to_value_object (args[i]);
673
674 if (py_value_arg == NULL)
675 {
676 gdbpy_print_stack ();
677 error (_("Error while executing Python code."));
678 }
679
680 PyTuple_SET_ITEM (py_arg_tuple, i + 1, py_value_arg);
681 }
682
683 py_result = PyObject_CallObject (xmethod_worker, py_arg_tuple);
684 if (py_result == NULL)
685 {
686 gdbpy_print_stack ();
687 error (_("Error while executing Python code."));
688 }
689 make_cleanup_py_decref (py_result);
690
691 if (py_result != Py_None)
692 {
693 res = convert_value_from_python (py_result);
694 if (res == NULL)
695 {
696 gdbpy_print_stack ();
697 error (_("Error while executing Python code."));
698 }
699 }
700 else
701 {
702 res = allocate_value (lookup_typename (python_language, python_gdbarch,
703 "void", NULL, 0));
704 }
705
706 do_cleanups (cleanups);
707
708 return res;
709 }
710
711 /* Creates a new Python xmethod_worker object.
712 The new object has data of type 'struct gdbpy_worker_data' composed
713 with the components PY_WORKER and THIS_TYPE. */
714
715 static struct xmethod_worker *
716 new_python_xmethod_worker (PyObject *py_worker, PyObject *this_type)
717 {
718 struct gdbpy_worker_data *data;
719
720 gdb_assert (py_worker != NULL && this_type != NULL);
721
722 data = XCNEW (struct gdbpy_worker_data);
723 data->worker = py_worker;
724 data->this_type = this_type;
725 Py_INCREF (py_worker);
726 Py_INCREF (this_type);
727
728 return new_xmethod_worker (&extension_language_python, data);
729 }
730
731 int
732 gdbpy_initialize_xmethods (void)
733 {
734 py_match_method_name = PyString_FromString (match_method_name);
735 if (py_match_method_name == NULL)
736 return -1;
737
738 py_invoke_method_name = PyString_FromString (invoke_method_name);
739 if (py_invoke_method_name == NULL)
740 return -1;
741
742 py_get_arg_types_method_name
743 = PyString_FromString (get_arg_types_method_name);
744 if (py_get_arg_types_method_name == NULL)
745 return -1;
746
747 py_get_result_type_method_name
748 = PyString_FromString (get_result_type_method_name);
749 if (py_get_result_type_method_name == NULL)
750 return -1;
751
752 return 1;
753 }
This page took 0.052236 seconds and 4 git commands to generate.