OSDN Git Service

log/syslog: Fix name of C function syslog_c.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-can-convert-interface.c
1 /* go-can-convert-interface.c -- can we convert to an interface?
2
3    Copyright 2009 The Go Authors. All rights reserved.
4    Use of this source code is governed by a BSD-style
5    license that can be found in the LICENSE file.  */
6
7 #include "go-assert.h"
8 #include "go-type.h"
9 #include "interface.h"
10
11 /* Return whether we can convert from the type in FROM_DESCRIPTOR to
12    the interface in TO_DESCRIPTOR.  This is used for type
13    switches.  */
14
15 _Bool
16 __go_can_convert_to_interface (
17     const struct __go_type_descriptor *to_descriptor,
18     const struct __go_type_descriptor *from_descriptor)
19 {
20   const struct __go_interface_type *to_interface;
21   int to_method_count;
22   const struct __go_interface_method *to_method;
23   const struct __go_uncommon_type *from_uncommon;
24   int from_method_count;
25   const struct __go_method *from_method;
26   int i;
27
28   /* In a type switch FROM_DESCRIPTOR can be NULL.  */
29   if (from_descriptor == NULL)
30     return 0;
31
32   __go_assert (to_descriptor->__code == GO_INTERFACE);
33   to_interface = (const struct __go_interface_type *) to_descriptor;
34   to_method_count = to_interface->__methods.__count;
35   to_method = ((const struct __go_interface_method *)
36                to_interface->__methods.__values);
37
38   from_uncommon = from_descriptor->__uncommon;
39   if (from_uncommon == NULL)
40     {
41       from_method_count = 0;
42       from_method = NULL;
43     }
44   else
45     {
46       from_method_count = from_uncommon->__methods.__count;
47       from_method = ((const struct __go_method *)
48                      from_uncommon->__methods.__values);
49     }
50
51   for (i = 0; i < to_method_count; ++i)
52     {
53       while (from_method_count > 0
54              && (!__go_ptr_strings_equal (from_method->__name,
55                                           to_method->__name)
56                  || !__go_ptr_strings_equal (from_method->__pkg_path,
57                                              to_method->__pkg_path)))
58         {
59           ++from_method;
60           --from_method_count;
61         }
62
63       if (from_method_count == 0)
64         return 0;
65
66       if (!__go_type_descriptors_equal (from_method->__mtype,
67                                         to_method->__type))
68         return 0;
69
70       ++to_method;
71       ++from_method;
72       --from_method_count;
73     }
74
75   return 1;
76 }