xref: /dflybsd-src/contrib/gdb-7/gdb/go-lang.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1*ef5ccd6cSJohn Marino /* Go language support routines for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino 
3*ef5ccd6cSJohn Marino    Copyright (C) 2012-2013 Free Software Foundation, Inc.
4*ef5ccd6cSJohn Marino 
5*ef5ccd6cSJohn Marino    This file is part of GDB.
6*ef5ccd6cSJohn Marino 
7*ef5ccd6cSJohn Marino    This program is free software; you can redistribute it and/or modify
8*ef5ccd6cSJohn Marino    it under the terms of the GNU General Public License as published by
9*ef5ccd6cSJohn Marino    the Free Software Foundation; either version 3 of the License, or
10*ef5ccd6cSJohn Marino    (at your option) any later version.
11*ef5ccd6cSJohn Marino 
12*ef5ccd6cSJohn Marino    This program is distributed in the hope that it will be useful,
13*ef5ccd6cSJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*ef5ccd6cSJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*ef5ccd6cSJohn Marino    GNU General Public License for more details.
16*ef5ccd6cSJohn Marino 
17*ef5ccd6cSJohn Marino    You should have received a copy of the GNU General Public License
18*ef5ccd6cSJohn Marino    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19*ef5ccd6cSJohn Marino 
20*ef5ccd6cSJohn Marino /* TODO:
21*ef5ccd6cSJohn Marino    - split stacks
22*ef5ccd6cSJohn Marino    - printing of native types
23*ef5ccd6cSJohn Marino    - goroutines
24*ef5ccd6cSJohn Marino    - lots more
25*ef5ccd6cSJohn Marino    - gccgo mangling needs redoing
26*ef5ccd6cSJohn Marino      It's too hard, for example, to know whether one is looking at a mangled
27*ef5ccd6cSJohn Marino      Go symbol or not, and their are ambiguities, e.g., the demangler may
28*ef5ccd6cSJohn Marino      get passed *any* symbol, including symbols from other languages
29*ef5ccd6cSJohn Marino      and including symbols that are already demangled.
30*ef5ccd6cSJohn Marino      One thought is to at least add an _G prefix.
31*ef5ccd6cSJohn Marino    - 6g mangling isn't supported yet
32*ef5ccd6cSJohn Marino */
33*ef5ccd6cSJohn Marino 
34*ef5ccd6cSJohn Marino #include "defs.h"
35*ef5ccd6cSJohn Marino #include "gdb_assert.h"
36*ef5ccd6cSJohn Marino #include "gdb_obstack.h"
37*ef5ccd6cSJohn Marino #include "gdb_string.h"
38*ef5ccd6cSJohn Marino #include "block.h"
39*ef5ccd6cSJohn Marino #include "symtab.h"
40*ef5ccd6cSJohn Marino #include "language.h"
41*ef5ccd6cSJohn Marino #include "go-lang.h"
42*ef5ccd6cSJohn Marino #include "c-lang.h"
43*ef5ccd6cSJohn Marino #include "parser-defs.h"
44*ef5ccd6cSJohn Marino 
45*ef5ccd6cSJohn Marino #include <ctype.h>
46*ef5ccd6cSJohn Marino 
47*ef5ccd6cSJohn Marino /* The main function in the main package.  */
48*ef5ccd6cSJohn Marino static const char GO_MAIN_MAIN[] = "main.main";
49*ef5ccd6cSJohn Marino 
50*ef5ccd6cSJohn Marino /* Function returning the special symbol name used by Go for the main
51*ef5ccd6cSJohn Marino    procedure in the main program if it is found in minimal symbol list.
52*ef5ccd6cSJohn Marino    This function tries to find minimal symbols so that it finds them even
53*ef5ccd6cSJohn Marino    if the program was compiled without debugging information.  */
54*ef5ccd6cSJohn Marino 
55*ef5ccd6cSJohn Marino const char *
go_main_name(void)56*ef5ccd6cSJohn Marino go_main_name (void)
57*ef5ccd6cSJohn Marino {
58*ef5ccd6cSJohn Marino   struct minimal_symbol *msym;
59*ef5ccd6cSJohn Marino 
60*ef5ccd6cSJohn Marino   msym = lookup_minimal_symbol (GO_MAIN_MAIN, NULL, NULL);
61*ef5ccd6cSJohn Marino   if (msym != NULL)
62*ef5ccd6cSJohn Marino     return GO_MAIN_MAIN;
63*ef5ccd6cSJohn Marino 
64*ef5ccd6cSJohn Marino   /* No known entry procedure found, the main program is probably not Go.  */
65*ef5ccd6cSJohn Marino   return NULL;
66*ef5ccd6cSJohn Marino }
67*ef5ccd6cSJohn Marino 
68*ef5ccd6cSJohn Marino /* Return non-zero if TYPE is a gccgo string.
69*ef5ccd6cSJohn Marino    We assume CHECK_TYPEDEF has already been done.  */
70*ef5ccd6cSJohn Marino 
71*ef5ccd6cSJohn Marino static int
gccgo_string_p(struct type * type)72*ef5ccd6cSJohn Marino gccgo_string_p (struct type *type)
73*ef5ccd6cSJohn Marino {
74*ef5ccd6cSJohn Marino   /* gccgo strings don't necessarily have a name we can use.  */
75*ef5ccd6cSJohn Marino 
76*ef5ccd6cSJohn Marino   if (TYPE_NFIELDS (type) == 2)
77*ef5ccd6cSJohn Marino     {
78*ef5ccd6cSJohn Marino       struct type *type0 = TYPE_FIELD_TYPE (type, 0);
79*ef5ccd6cSJohn Marino       struct type *type1 = TYPE_FIELD_TYPE (type, 1);
80*ef5ccd6cSJohn Marino 
81*ef5ccd6cSJohn Marino       CHECK_TYPEDEF (type0);
82*ef5ccd6cSJohn Marino       CHECK_TYPEDEF (type1);
83*ef5ccd6cSJohn Marino 
84*ef5ccd6cSJohn Marino       if (TYPE_CODE (type0) == TYPE_CODE_PTR
85*ef5ccd6cSJohn Marino 	  && strcmp (TYPE_FIELD_NAME (type, 0), "__data") == 0
86*ef5ccd6cSJohn Marino 	  && TYPE_CODE (type1) == TYPE_CODE_INT
87*ef5ccd6cSJohn Marino 	  && strcmp (TYPE_FIELD_NAME (type, 1), "__length") == 0)
88*ef5ccd6cSJohn Marino 	{
89*ef5ccd6cSJohn Marino 	  struct type *target_type = TYPE_TARGET_TYPE (type0);
90*ef5ccd6cSJohn Marino 
91*ef5ccd6cSJohn Marino 	  CHECK_TYPEDEF (target_type);
92*ef5ccd6cSJohn Marino 
93*ef5ccd6cSJohn Marino 	  if (TYPE_CODE (target_type) == TYPE_CODE_INT
94*ef5ccd6cSJohn Marino 	      && TYPE_LENGTH (target_type) == 1
95*ef5ccd6cSJohn Marino 	      && strcmp (TYPE_NAME (target_type), "uint8") == 0)
96*ef5ccd6cSJohn Marino 	    return 1;
97*ef5ccd6cSJohn Marino 	}
98*ef5ccd6cSJohn Marino     }
99*ef5ccd6cSJohn Marino 
100*ef5ccd6cSJohn Marino   return 0;
101*ef5ccd6cSJohn Marino }
102*ef5ccd6cSJohn Marino 
103*ef5ccd6cSJohn Marino /* Return non-zero if TYPE is a 6g string.
104*ef5ccd6cSJohn Marino    We assume CHECK_TYPEDEF has already been done.  */
105*ef5ccd6cSJohn Marino 
106*ef5ccd6cSJohn Marino static int
sixg_string_p(struct type * type)107*ef5ccd6cSJohn Marino sixg_string_p (struct type *type)
108*ef5ccd6cSJohn Marino {
109*ef5ccd6cSJohn Marino   if (TYPE_NFIELDS (type) == 2
110*ef5ccd6cSJohn Marino       && TYPE_TAG_NAME (type) != NULL
111*ef5ccd6cSJohn Marino       && strcmp (TYPE_TAG_NAME (type), "string") == 0)
112*ef5ccd6cSJohn Marino     return 1;
113*ef5ccd6cSJohn Marino 
114*ef5ccd6cSJohn Marino   return 0;
115*ef5ccd6cSJohn Marino }
116*ef5ccd6cSJohn Marino 
117*ef5ccd6cSJohn Marino /* Classify the kind of Go object that TYPE is.
118*ef5ccd6cSJohn Marino    TYPE is a TYPE_CODE_STRUCT, used to represent a Go object.  */
119*ef5ccd6cSJohn Marino 
120*ef5ccd6cSJohn Marino enum go_type
go_classify_struct_type(struct type * type)121*ef5ccd6cSJohn Marino go_classify_struct_type (struct type *type)
122*ef5ccd6cSJohn Marino {
123*ef5ccd6cSJohn Marino   CHECK_TYPEDEF (type);
124*ef5ccd6cSJohn Marino 
125*ef5ccd6cSJohn Marino   /* Recognize strings as they're useful to be able to print without
126*ef5ccd6cSJohn Marino      pretty-printers.  */
127*ef5ccd6cSJohn Marino   if (gccgo_string_p (type)
128*ef5ccd6cSJohn Marino       || sixg_string_p (type))
129*ef5ccd6cSJohn Marino     return GO_TYPE_STRING;
130*ef5ccd6cSJohn Marino 
131*ef5ccd6cSJohn Marino   return GO_TYPE_NONE;
132*ef5ccd6cSJohn Marino }
133*ef5ccd6cSJohn Marino 
134*ef5ccd6cSJohn Marino /* Subroutine of unpack_mangled_go_symbol to simplify it.
135*ef5ccd6cSJohn Marino    Given "[foo.]bar.baz", store "bar" in *PACKAGEP and "baz" in *OBJECTP.
136*ef5ccd6cSJohn Marino    We stomp on the last '.' to nul-terminate "bar".
137*ef5ccd6cSJohn Marino    The caller is responsible for memory management.  */
138*ef5ccd6cSJohn Marino 
139*ef5ccd6cSJohn Marino static void
unpack_package_and_object(char * buf,const char ** packagep,const char ** objectp)140*ef5ccd6cSJohn Marino unpack_package_and_object (char *buf,
141*ef5ccd6cSJohn Marino 			   const char **packagep, const char **objectp)
142*ef5ccd6cSJohn Marino {
143*ef5ccd6cSJohn Marino   char *last_dot;
144*ef5ccd6cSJohn Marino 
145*ef5ccd6cSJohn Marino   last_dot = strrchr (buf, '.');
146*ef5ccd6cSJohn Marino   gdb_assert (last_dot != NULL);
147*ef5ccd6cSJohn Marino   *objectp = last_dot + 1;
148*ef5ccd6cSJohn Marino   *last_dot = '\0';
149*ef5ccd6cSJohn Marino   last_dot = strrchr (buf, '.');
150*ef5ccd6cSJohn Marino   if (last_dot != NULL)
151*ef5ccd6cSJohn Marino     *packagep = last_dot + 1;
152*ef5ccd6cSJohn Marino   else
153*ef5ccd6cSJohn Marino     *packagep = buf;
154*ef5ccd6cSJohn Marino }
155*ef5ccd6cSJohn Marino 
156*ef5ccd6cSJohn Marino /* Given a mangled Go symbol, find its package name, object name, and
157*ef5ccd6cSJohn Marino    method type (if present).
158*ef5ccd6cSJohn Marino    E.g., for "libgo_net.textproto.String.N33_libgo_net.textproto.ProtocolError"
159*ef5ccd6cSJohn Marino    *PACKAGEP = "textproto"
160*ef5ccd6cSJohn Marino    *OBJECTP = "String"
161*ef5ccd6cSJohn Marino    *METHOD_TYPE_PACKAGEP = "textproto"
162*ef5ccd6cSJohn Marino    *METHOD_TYPE_OBJECTP = "ProtocolError"
163*ef5ccd6cSJohn Marino 
164*ef5ccd6cSJohn Marino    Space for the resulting strings is malloc'd in one buffer.
165*ef5ccd6cSJohn Marino    PACKAGEP,OBJECTP,METHOD_TYPE* will (typically) point into this buffer.
166*ef5ccd6cSJohn Marino    [There are a few exceptions, but the caller is still responsible for
167*ef5ccd6cSJohn Marino    freeing the resulting pointer.]
168*ef5ccd6cSJohn Marino    A pointer to this buffer is returned, or NULL if symbol isn't a
169*ef5ccd6cSJohn Marino    mangled Go symbol.
170*ef5ccd6cSJohn Marino    The caller is responsible for freeing the result.
171*ef5ccd6cSJohn Marino 
172*ef5ccd6cSJohn Marino    *METHOD_TYPE_IS_POINTERP is set to a boolean indicating if
173*ef5ccd6cSJohn Marino    the method type is a pointer.
174*ef5ccd6cSJohn Marino 
175*ef5ccd6cSJohn Marino    There may be value in returning the outer container,
176*ef5ccd6cSJohn Marino    i.e., "net" in the above example, but for now it's not needed.
177*ef5ccd6cSJohn Marino    Plus it's currently not straightforward to compute,
178*ef5ccd6cSJohn Marino    it comes from -fgo-prefix, and there's no algorithm to compute it.
179*ef5ccd6cSJohn Marino 
180*ef5ccd6cSJohn Marino    If we ever need to unpack the method type, this routine should work
181*ef5ccd6cSJohn Marino    for that too.  */
182*ef5ccd6cSJohn Marino 
183*ef5ccd6cSJohn Marino static char *
unpack_mangled_go_symbol(const char * mangled_name,const char ** packagep,const char ** objectp,const char ** method_type_packagep,const char ** method_type_objectp,int * method_type_is_pointerp)184*ef5ccd6cSJohn Marino unpack_mangled_go_symbol (const char *mangled_name,
185*ef5ccd6cSJohn Marino 			  const char **packagep,
186*ef5ccd6cSJohn Marino 			  const char **objectp,
187*ef5ccd6cSJohn Marino 			  const char **method_type_packagep,
188*ef5ccd6cSJohn Marino 			  const char **method_type_objectp,
189*ef5ccd6cSJohn Marino 			  int *method_type_is_pointerp)
190*ef5ccd6cSJohn Marino {
191*ef5ccd6cSJohn Marino   char *buf;
192*ef5ccd6cSJohn Marino   char *p;
193*ef5ccd6cSJohn Marino   int len = strlen (mangled_name);
194*ef5ccd6cSJohn Marino   /* Pointer to last digit in "N<digit(s)>_".  */
195*ef5ccd6cSJohn Marino   char *saw_digit;
196*ef5ccd6cSJohn Marino   /* Pointer to "N" if valid "N<digit(s)>_" found.  */
197*ef5ccd6cSJohn Marino   char *method_type;
198*ef5ccd6cSJohn Marino   /* Pointer to the first '.'.  */
199*ef5ccd6cSJohn Marino   char *first_dot;
200*ef5ccd6cSJohn Marino   /* Pointer to the last '.'.  */
201*ef5ccd6cSJohn Marino   char *last_dot;
202*ef5ccd6cSJohn Marino   /* Non-zero if we saw a pointer indicator.  */
203*ef5ccd6cSJohn Marino   int saw_pointer;
204*ef5ccd6cSJohn Marino 
205*ef5ccd6cSJohn Marino   *packagep = *objectp = NULL;
206*ef5ccd6cSJohn Marino   *method_type_packagep = *method_type_objectp = NULL;
207*ef5ccd6cSJohn Marino   *method_type_is_pointerp = 0;
208*ef5ccd6cSJohn Marino 
209*ef5ccd6cSJohn Marino   /* main.init is mangled specially.  */
210*ef5ccd6cSJohn Marino   if (strcmp (mangled_name, "__go_init_main") == 0)
211*ef5ccd6cSJohn Marino     {
212*ef5ccd6cSJohn Marino       char *package = xstrdup ("main");
213*ef5ccd6cSJohn Marino 
214*ef5ccd6cSJohn Marino       *packagep = package;
215*ef5ccd6cSJohn Marino       *objectp = "init";
216*ef5ccd6cSJohn Marino       return package;
217*ef5ccd6cSJohn Marino     }
218*ef5ccd6cSJohn Marino 
219*ef5ccd6cSJohn Marino   /* main.main is mangled specially (missing prefix).  */
220*ef5ccd6cSJohn Marino   if (strcmp (mangled_name, "main.main") == 0)
221*ef5ccd6cSJohn Marino     {
222*ef5ccd6cSJohn Marino       char *package = xstrdup ("main");
223*ef5ccd6cSJohn Marino 
224*ef5ccd6cSJohn Marino       *packagep = package;
225*ef5ccd6cSJohn Marino       *objectp = "main";
226*ef5ccd6cSJohn Marino       return package;
227*ef5ccd6cSJohn Marino     }
228*ef5ccd6cSJohn Marino 
229*ef5ccd6cSJohn Marino   /* We may get passed, e.g., "main.T.Foo", which is *not* mangled.
230*ef5ccd6cSJohn Marino      Alas it looks exactly like "prefix.package.object."
231*ef5ccd6cSJohn Marino      To cope for now we only recognize the following prefixes:
232*ef5ccd6cSJohn Marino 
233*ef5ccd6cSJohn Marino      go: the default
234*ef5ccd6cSJohn Marino      libgo_.*: used by gccgo's runtime
235*ef5ccd6cSJohn Marino 
236*ef5ccd6cSJohn Marino      Thus we don't support -fgo-prefix (except as used by the runtime).  */
237*ef5ccd6cSJohn Marino   if (strncmp (mangled_name, "go.", 3) != 0
238*ef5ccd6cSJohn Marino       && strncmp (mangled_name, "libgo_", 6) != 0)
239*ef5ccd6cSJohn Marino     return NULL;
240*ef5ccd6cSJohn Marino 
241*ef5ccd6cSJohn Marino   /* Quick check for whether a search may be fruitful.  */
242*ef5ccd6cSJohn Marino   /* Ignore anything with @plt, etc. in it.  */
243*ef5ccd6cSJohn Marino   if (strchr (mangled_name, '@') != NULL)
244*ef5ccd6cSJohn Marino     return NULL;
245*ef5ccd6cSJohn Marino   /* It must have at least two dots.  */
246*ef5ccd6cSJohn Marino   first_dot = strchr (mangled_name, '.');
247*ef5ccd6cSJohn Marino   if (first_dot == NULL)
248*ef5ccd6cSJohn Marino     return NULL;
249*ef5ccd6cSJohn Marino   /* Treat "foo.bar" as unmangled.  It can collide with lots of other
250*ef5ccd6cSJohn Marino      languages and it's not clear what the consequences are.
251*ef5ccd6cSJohn Marino      And except for main.main, all gccgo symbols are at least
252*ef5ccd6cSJohn Marino      prefix.package.object.  */
253*ef5ccd6cSJohn Marino   last_dot = strrchr (mangled_name, '.');
254*ef5ccd6cSJohn Marino   if (last_dot == first_dot)
255*ef5ccd6cSJohn Marino     return NULL;
256*ef5ccd6cSJohn Marino 
257*ef5ccd6cSJohn Marino   /* More quick checks.  */
258*ef5ccd6cSJohn Marino   if (last_dot[1] == '\0' /* foo. */
259*ef5ccd6cSJohn Marino       || last_dot[-1] == '.') /* foo..bar */
260*ef5ccd6cSJohn Marino     return NULL;
261*ef5ccd6cSJohn Marino 
262*ef5ccd6cSJohn Marino   /* At this point we've decided we have a mangled Go symbol.  */
263*ef5ccd6cSJohn Marino 
264*ef5ccd6cSJohn Marino   buf = xstrdup (mangled_name);
265*ef5ccd6cSJohn Marino 
266*ef5ccd6cSJohn Marino   /* Search backwards looking for "N<digit(s)>".  */
267*ef5ccd6cSJohn Marino   p = buf + len;
268*ef5ccd6cSJohn Marino   saw_digit = method_type = NULL;
269*ef5ccd6cSJohn Marino   saw_pointer = 0;
270*ef5ccd6cSJohn Marino   while (p > buf)
271*ef5ccd6cSJohn Marino     {
272*ef5ccd6cSJohn Marino       int current = *(const unsigned char *) --p;
273*ef5ccd6cSJohn Marino       int current_is_digit = isdigit (current);
274*ef5ccd6cSJohn Marino 
275*ef5ccd6cSJohn Marino       if (saw_digit)
276*ef5ccd6cSJohn Marino 	{
277*ef5ccd6cSJohn Marino 	  if (current_is_digit)
278*ef5ccd6cSJohn Marino 	    continue;
279*ef5ccd6cSJohn Marino 	  if (current == 'N'
280*ef5ccd6cSJohn Marino 	      && ((p > buf && p[-1] == '.')
281*ef5ccd6cSJohn Marino 		  || (p > buf + 1 && p[-1] == 'p' && p[-2] == '.')))
282*ef5ccd6cSJohn Marino 	    {
283*ef5ccd6cSJohn Marino 	      if (atoi (p + 1) == strlen (saw_digit + 2))
284*ef5ccd6cSJohn Marino 		{
285*ef5ccd6cSJohn Marino 		  if (p[-1] == '.')
286*ef5ccd6cSJohn Marino 		    method_type = p - 1;
287*ef5ccd6cSJohn Marino 		  else
288*ef5ccd6cSJohn Marino 		    {
289*ef5ccd6cSJohn Marino 		      gdb_assert (p[-1] == 'p');
290*ef5ccd6cSJohn Marino 		      saw_pointer = 1;
291*ef5ccd6cSJohn Marino 		      method_type = p - 2;
292*ef5ccd6cSJohn Marino 		    }
293*ef5ccd6cSJohn Marino 		  break;
294*ef5ccd6cSJohn Marino 		}
295*ef5ccd6cSJohn Marino 	    }
296*ef5ccd6cSJohn Marino 	  /* Not what we're looking for, reset and keep looking.  */
297*ef5ccd6cSJohn Marino 	  saw_digit = NULL;
298*ef5ccd6cSJohn Marino 	  saw_pointer = 0;
299*ef5ccd6cSJohn Marino 	  continue;
300*ef5ccd6cSJohn Marino 	}
301*ef5ccd6cSJohn Marino       if (current_is_digit && p[1] == '_')
302*ef5ccd6cSJohn Marino 	{
303*ef5ccd6cSJohn Marino 	  /* Possible start of method "this" [sic] type.  */
304*ef5ccd6cSJohn Marino 	  saw_digit = p;
305*ef5ccd6cSJohn Marino 	  continue;
306*ef5ccd6cSJohn Marino 	}
307*ef5ccd6cSJohn Marino     }
308*ef5ccd6cSJohn Marino 
309*ef5ccd6cSJohn Marino   if (method_type != NULL
310*ef5ccd6cSJohn Marino       /* Ensure not something like "..foo".  */
311*ef5ccd6cSJohn Marino       && (method_type > buf && method_type[-1] != '.'))
312*ef5ccd6cSJohn Marino     {
313*ef5ccd6cSJohn Marino       unpack_package_and_object (saw_digit + 2,
314*ef5ccd6cSJohn Marino 				 method_type_packagep, method_type_objectp);
315*ef5ccd6cSJohn Marino       *method_type = '\0';
316*ef5ccd6cSJohn Marino       *method_type_is_pointerp = saw_pointer;
317*ef5ccd6cSJohn Marino     }
318*ef5ccd6cSJohn Marino 
319*ef5ccd6cSJohn Marino   unpack_package_and_object (buf, packagep, objectp);
320*ef5ccd6cSJohn Marino   return buf;
321*ef5ccd6cSJohn Marino }
322*ef5ccd6cSJohn Marino 
323*ef5ccd6cSJohn Marino /* Implements the la_demangle language_defn routine for language Go.
324*ef5ccd6cSJohn Marino 
325*ef5ccd6cSJohn Marino    N.B. This may get passed *any* symbol, including symbols from other
326*ef5ccd6cSJohn Marino    languages and including symbols that are already demangled.
327*ef5ccd6cSJohn Marino    Both of these situations are kinda unfortunate, but that's how things
328*ef5ccd6cSJohn Marino    are today.
329*ef5ccd6cSJohn Marino 
330*ef5ccd6cSJohn Marino    N.B. This currently only supports gccgo's mangling.
331*ef5ccd6cSJohn Marino 
332*ef5ccd6cSJohn Marino    N.B. gccgo's mangling needs, I think, changing.
333*ef5ccd6cSJohn Marino    This demangler can't work in all situations,
334*ef5ccd6cSJohn Marino    thus not too much effort is currently put into it.  */
335*ef5ccd6cSJohn Marino 
336*ef5ccd6cSJohn Marino char *
go_demangle(const char * mangled_name,int options)337*ef5ccd6cSJohn Marino go_demangle (const char *mangled_name, int options)
338*ef5ccd6cSJohn Marino {
339*ef5ccd6cSJohn Marino   struct obstack tempbuf;
340*ef5ccd6cSJohn Marino   char *result;
341*ef5ccd6cSJohn Marino   char *name_buf;
342*ef5ccd6cSJohn Marino   const char *package_name;
343*ef5ccd6cSJohn Marino   const char *object_name;
344*ef5ccd6cSJohn Marino   const char *method_type_package_name;
345*ef5ccd6cSJohn Marino   const char *method_type_object_name;
346*ef5ccd6cSJohn Marino   int method_type_is_pointer;
347*ef5ccd6cSJohn Marino 
348*ef5ccd6cSJohn Marino   if (mangled_name == NULL)
349*ef5ccd6cSJohn Marino     return NULL;
350*ef5ccd6cSJohn Marino 
351*ef5ccd6cSJohn Marino   name_buf = unpack_mangled_go_symbol (mangled_name,
352*ef5ccd6cSJohn Marino 				       &package_name, &object_name,
353*ef5ccd6cSJohn Marino 				       &method_type_package_name,
354*ef5ccd6cSJohn Marino 				       &method_type_object_name,
355*ef5ccd6cSJohn Marino 				       &method_type_is_pointer);
356*ef5ccd6cSJohn Marino   if (name_buf == NULL)
357*ef5ccd6cSJohn Marino     return NULL;
358*ef5ccd6cSJohn Marino 
359*ef5ccd6cSJohn Marino   obstack_init (&tempbuf);
360*ef5ccd6cSJohn Marino 
361*ef5ccd6cSJohn Marino   /* Print methods as they appear in "method expressions".  */
362*ef5ccd6cSJohn Marino   if (method_type_package_name != NULL)
363*ef5ccd6cSJohn Marino     {
364*ef5ccd6cSJohn Marino       /* FIXME: Seems like we should include package_name here somewhere.  */
365*ef5ccd6cSJohn Marino       if (method_type_is_pointer)
366*ef5ccd6cSJohn Marino 	  obstack_grow_str (&tempbuf, "(*");
367*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, method_type_package_name);
368*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, ".");
369*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, method_type_object_name);
370*ef5ccd6cSJohn Marino       if (method_type_is_pointer)
371*ef5ccd6cSJohn Marino 	obstack_grow_str (&tempbuf, ")");
372*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, ".");
373*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, object_name);
374*ef5ccd6cSJohn Marino     }
375*ef5ccd6cSJohn Marino   else
376*ef5ccd6cSJohn Marino     {
377*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, package_name);
378*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, ".");
379*ef5ccd6cSJohn Marino       obstack_grow_str (&tempbuf, object_name);
380*ef5ccd6cSJohn Marino     }
381*ef5ccd6cSJohn Marino   obstack_grow_str0 (&tempbuf, "");
382*ef5ccd6cSJohn Marino 
383*ef5ccd6cSJohn Marino   result = xstrdup (obstack_finish (&tempbuf));
384*ef5ccd6cSJohn Marino   obstack_free (&tempbuf, NULL);
385*ef5ccd6cSJohn Marino   xfree (name_buf);
386*ef5ccd6cSJohn Marino   return result;
387*ef5ccd6cSJohn Marino }
388*ef5ccd6cSJohn Marino 
389*ef5ccd6cSJohn Marino /* Given a Go symbol, return its package or NULL if unknown.
390*ef5ccd6cSJohn Marino    Space for the result is malloc'd, caller must free.  */
391*ef5ccd6cSJohn Marino 
392*ef5ccd6cSJohn Marino char *
go_symbol_package_name(const struct symbol * sym)393*ef5ccd6cSJohn Marino go_symbol_package_name (const struct symbol *sym)
394*ef5ccd6cSJohn Marino {
395*ef5ccd6cSJohn Marino   const char *mangled_name = SYMBOL_LINKAGE_NAME (sym);
396*ef5ccd6cSJohn Marino   const char *package_name;
397*ef5ccd6cSJohn Marino   const char *object_name;
398*ef5ccd6cSJohn Marino   const char *method_type_package_name;
399*ef5ccd6cSJohn Marino   const char *method_type_object_name;
400*ef5ccd6cSJohn Marino   int method_type_is_pointer;
401*ef5ccd6cSJohn Marino   char *name_buf;
402*ef5ccd6cSJohn Marino   char *result;
403*ef5ccd6cSJohn Marino 
404*ef5ccd6cSJohn Marino   gdb_assert (SYMBOL_LANGUAGE (sym) == language_go);
405*ef5ccd6cSJohn Marino   name_buf = unpack_mangled_go_symbol (mangled_name,
406*ef5ccd6cSJohn Marino 				       &package_name, &object_name,
407*ef5ccd6cSJohn Marino 				       &method_type_package_name,
408*ef5ccd6cSJohn Marino 				       &method_type_object_name,
409*ef5ccd6cSJohn Marino 				       &method_type_is_pointer);
410*ef5ccd6cSJohn Marino   /* Some Go symbols don't have mangled form we interpret (yet).  */
411*ef5ccd6cSJohn Marino   if (name_buf == NULL)
412*ef5ccd6cSJohn Marino     return NULL;
413*ef5ccd6cSJohn Marino   result = xstrdup (package_name);
414*ef5ccd6cSJohn Marino   xfree (name_buf);
415*ef5ccd6cSJohn Marino   return result;
416*ef5ccd6cSJohn Marino }
417*ef5ccd6cSJohn Marino 
418*ef5ccd6cSJohn Marino /* Return the package that BLOCK is in, or NULL if there isn't one.
419*ef5ccd6cSJohn Marino    Space for the result is malloc'd, caller must free.  */
420*ef5ccd6cSJohn Marino 
421*ef5ccd6cSJohn Marino char *
go_block_package_name(const struct block * block)422*ef5ccd6cSJohn Marino go_block_package_name (const struct block *block)
423*ef5ccd6cSJohn Marino {
424*ef5ccd6cSJohn Marino   while (block != NULL)
425*ef5ccd6cSJohn Marino     {
426*ef5ccd6cSJohn Marino       struct symbol *function = BLOCK_FUNCTION (block);
427*ef5ccd6cSJohn Marino 
428*ef5ccd6cSJohn Marino       if (function != NULL)
429*ef5ccd6cSJohn Marino 	{
430*ef5ccd6cSJohn Marino 	  char *package_name = go_symbol_package_name (function);
431*ef5ccd6cSJohn Marino 
432*ef5ccd6cSJohn Marino 	  if (package_name != NULL)
433*ef5ccd6cSJohn Marino 	    return package_name;
434*ef5ccd6cSJohn Marino 
435*ef5ccd6cSJohn Marino 	  /* Stop looking if we find a function without a package name.
436*ef5ccd6cSJohn Marino 	     We're most likely outside of Go and thus the concept of the
437*ef5ccd6cSJohn Marino 	     "current" package is gone.  */
438*ef5ccd6cSJohn Marino 	  return NULL;
439*ef5ccd6cSJohn Marino 	}
440*ef5ccd6cSJohn Marino 
441*ef5ccd6cSJohn Marino       block = BLOCK_SUPERBLOCK (block);
442*ef5ccd6cSJohn Marino     }
443*ef5ccd6cSJohn Marino 
444*ef5ccd6cSJohn Marino   return NULL;
445*ef5ccd6cSJohn Marino }
446*ef5ccd6cSJohn Marino 
447*ef5ccd6cSJohn Marino /* Table mapping opcodes into strings for printing operators
448*ef5ccd6cSJohn Marino    and precedences of the operators.
449*ef5ccd6cSJohn Marino    TODO(dje): &^ ?  */
450*ef5ccd6cSJohn Marino 
451*ef5ccd6cSJohn Marino static const struct op_print go_op_print_tab[] =
452*ef5ccd6cSJohn Marino {
453*ef5ccd6cSJohn Marino   {",", BINOP_COMMA, PREC_COMMA, 0},
454*ef5ccd6cSJohn Marino   {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
455*ef5ccd6cSJohn Marino   {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
456*ef5ccd6cSJohn Marino   {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
457*ef5ccd6cSJohn Marino   {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
458*ef5ccd6cSJohn Marino   {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
459*ef5ccd6cSJohn Marino   {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
460*ef5ccd6cSJohn Marino   {"==", BINOP_EQUAL, PREC_EQUAL, 0},
461*ef5ccd6cSJohn Marino   {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
462*ef5ccd6cSJohn Marino   {"<=", BINOP_LEQ, PREC_ORDER, 0},
463*ef5ccd6cSJohn Marino   {">=", BINOP_GEQ, PREC_ORDER, 0},
464*ef5ccd6cSJohn Marino   {">", BINOP_GTR, PREC_ORDER, 0},
465*ef5ccd6cSJohn Marino   {"<", BINOP_LESS, PREC_ORDER, 0},
466*ef5ccd6cSJohn Marino   {">>", BINOP_RSH, PREC_SHIFT, 0},
467*ef5ccd6cSJohn Marino   {"<<", BINOP_LSH, PREC_SHIFT, 0},
468*ef5ccd6cSJohn Marino   {"+", BINOP_ADD, PREC_ADD, 0},
469*ef5ccd6cSJohn Marino   {"-", BINOP_SUB, PREC_ADD, 0},
470*ef5ccd6cSJohn Marino   {"*", BINOP_MUL, PREC_MUL, 0},
471*ef5ccd6cSJohn Marino   {"/", BINOP_DIV, PREC_MUL, 0},
472*ef5ccd6cSJohn Marino   {"%", BINOP_REM, PREC_MUL, 0},
473*ef5ccd6cSJohn Marino   {"@", BINOP_REPEAT, PREC_REPEAT, 0},
474*ef5ccd6cSJohn Marino   {"-", UNOP_NEG, PREC_PREFIX, 0},
475*ef5ccd6cSJohn Marino   {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
476*ef5ccd6cSJohn Marino   {"^", UNOP_COMPLEMENT, PREC_PREFIX, 0},
477*ef5ccd6cSJohn Marino   {"*", UNOP_IND, PREC_PREFIX, 0},
478*ef5ccd6cSJohn Marino   {"&", UNOP_ADDR, PREC_PREFIX, 0},
479*ef5ccd6cSJohn Marino   {"unsafe.Sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
480*ef5ccd6cSJohn Marino   {"++", UNOP_POSTINCREMENT, PREC_SUFFIX, 0},
481*ef5ccd6cSJohn Marino   {"--", UNOP_POSTDECREMENT, PREC_SUFFIX, 0},
482*ef5ccd6cSJohn Marino   {NULL, 0, 0, 0}
483*ef5ccd6cSJohn Marino };
484*ef5ccd6cSJohn Marino 
485*ef5ccd6cSJohn Marino enum go_primitive_types {
486*ef5ccd6cSJohn Marino   go_primitive_type_void,
487*ef5ccd6cSJohn Marino   go_primitive_type_char,
488*ef5ccd6cSJohn Marino   go_primitive_type_bool,
489*ef5ccd6cSJohn Marino   go_primitive_type_int,
490*ef5ccd6cSJohn Marino   go_primitive_type_uint,
491*ef5ccd6cSJohn Marino   go_primitive_type_uintptr,
492*ef5ccd6cSJohn Marino   go_primitive_type_int8,
493*ef5ccd6cSJohn Marino   go_primitive_type_int16,
494*ef5ccd6cSJohn Marino   go_primitive_type_int32,
495*ef5ccd6cSJohn Marino   go_primitive_type_int64,
496*ef5ccd6cSJohn Marino   go_primitive_type_uint8,
497*ef5ccd6cSJohn Marino   go_primitive_type_uint16,
498*ef5ccd6cSJohn Marino   go_primitive_type_uint32,
499*ef5ccd6cSJohn Marino   go_primitive_type_uint64,
500*ef5ccd6cSJohn Marino   go_primitive_type_float32,
501*ef5ccd6cSJohn Marino   go_primitive_type_float64,
502*ef5ccd6cSJohn Marino   go_primitive_type_complex64,
503*ef5ccd6cSJohn Marino   go_primitive_type_complex128,
504*ef5ccd6cSJohn Marino   nr_go_primitive_types
505*ef5ccd6cSJohn Marino };
506*ef5ccd6cSJohn Marino 
507*ef5ccd6cSJohn Marino static void
go_language_arch_info(struct gdbarch * gdbarch,struct language_arch_info * lai)508*ef5ccd6cSJohn Marino go_language_arch_info (struct gdbarch *gdbarch,
509*ef5ccd6cSJohn Marino 		       struct language_arch_info *lai)
510*ef5ccd6cSJohn Marino {
511*ef5ccd6cSJohn Marino   const struct builtin_go_type *builtin = builtin_go_type (gdbarch);
512*ef5ccd6cSJohn Marino 
513*ef5ccd6cSJohn Marino   lai->string_char_type = builtin->builtin_char;
514*ef5ccd6cSJohn Marino 
515*ef5ccd6cSJohn Marino   lai->primitive_type_vector
516*ef5ccd6cSJohn Marino     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_go_primitive_types + 1,
517*ef5ccd6cSJohn Marino 			      struct type *);
518*ef5ccd6cSJohn Marino 
519*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_void]
520*ef5ccd6cSJohn Marino     = builtin->builtin_void;
521*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_char]
522*ef5ccd6cSJohn Marino     = builtin->builtin_char;
523*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_bool]
524*ef5ccd6cSJohn Marino     = builtin->builtin_bool;
525*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_int]
526*ef5ccd6cSJohn Marino     = builtin->builtin_int;
527*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_uint]
528*ef5ccd6cSJohn Marino     = builtin->builtin_uint;
529*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_uintptr]
530*ef5ccd6cSJohn Marino     = builtin->builtin_uintptr;
531*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_int8]
532*ef5ccd6cSJohn Marino     = builtin->builtin_int8;
533*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_int16]
534*ef5ccd6cSJohn Marino     = builtin->builtin_int16;
535*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_int32]
536*ef5ccd6cSJohn Marino     = builtin->builtin_int32;
537*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_int64]
538*ef5ccd6cSJohn Marino     = builtin->builtin_int64;
539*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_uint8]
540*ef5ccd6cSJohn Marino     = builtin->builtin_uint8;
541*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_uint16]
542*ef5ccd6cSJohn Marino     = builtin->builtin_uint16;
543*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_uint32]
544*ef5ccd6cSJohn Marino     = builtin->builtin_uint32;
545*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_uint64]
546*ef5ccd6cSJohn Marino     = builtin->builtin_uint64;
547*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_float32]
548*ef5ccd6cSJohn Marino     = builtin->builtin_float32;
549*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_float64]
550*ef5ccd6cSJohn Marino     = builtin->builtin_float64;
551*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_complex64]
552*ef5ccd6cSJohn Marino     = builtin->builtin_complex64;
553*ef5ccd6cSJohn Marino   lai->primitive_type_vector [go_primitive_type_complex128]
554*ef5ccd6cSJohn Marino     = builtin->builtin_complex128;
555*ef5ccd6cSJohn Marino 
556*ef5ccd6cSJohn Marino   lai->bool_type_symbol = "bool";
557*ef5ccd6cSJohn Marino   lai->bool_type_default = builtin->builtin_bool;
558*ef5ccd6cSJohn Marino }
559*ef5ccd6cSJohn Marino 
560*ef5ccd6cSJohn Marino static const struct language_defn go_language_defn =
561*ef5ccd6cSJohn Marino {
562*ef5ccd6cSJohn Marino   "go",
563*ef5ccd6cSJohn Marino   language_go,
564*ef5ccd6cSJohn Marino   range_check_off,
565*ef5ccd6cSJohn Marino   case_sensitive_on,
566*ef5ccd6cSJohn Marino   array_row_major,
567*ef5ccd6cSJohn Marino   macro_expansion_no,
568*ef5ccd6cSJohn Marino   &exp_descriptor_c,
569*ef5ccd6cSJohn Marino   go_parse,
570*ef5ccd6cSJohn Marino   go_error,
571*ef5ccd6cSJohn Marino   null_post_parser,
572*ef5ccd6cSJohn Marino   c_printchar,			/* Print a character constant.  */
573*ef5ccd6cSJohn Marino   c_printstr,			/* Function to print string constant.  */
574*ef5ccd6cSJohn Marino   c_emit_char,			/* Print a single char.  */
575*ef5ccd6cSJohn Marino   go_print_type,		/* Print a type using appropriate syntax.  */
576*ef5ccd6cSJohn Marino   c_print_typedef,		/* Print a typedef using appropriate
577*ef5ccd6cSJohn Marino 				   syntax.  */
578*ef5ccd6cSJohn Marino   go_val_print,			/* Print a value using appropriate syntax.  */
579*ef5ccd6cSJohn Marino   c_value_print,		/* Print a top-level value.  */
580*ef5ccd6cSJohn Marino   default_read_var_value,	/* la_read_var_value */
581*ef5ccd6cSJohn Marino   NULL,				/* Language specific skip_trampoline.  */
582*ef5ccd6cSJohn Marino   NULL,				/* name_of_this */
583*ef5ccd6cSJohn Marino   basic_lookup_symbol_nonlocal,
584*ef5ccd6cSJohn Marino   basic_lookup_transparent_type,
585*ef5ccd6cSJohn Marino   go_demangle,			/* Language specific symbol demangler.  */
586*ef5ccd6cSJohn Marino   NULL,				/* Language specific
587*ef5ccd6cSJohn Marino 				   class_name_from_physname.  */
588*ef5ccd6cSJohn Marino   go_op_print_tab,		/* Expression operators for printing.  */
589*ef5ccd6cSJohn Marino   1,				/* C-style arrays.  */
590*ef5ccd6cSJohn Marino   0,				/* String lower bound.  */
591*ef5ccd6cSJohn Marino   default_word_break_characters,
592*ef5ccd6cSJohn Marino   default_make_symbol_completion_list,
593*ef5ccd6cSJohn Marino   go_language_arch_info,
594*ef5ccd6cSJohn Marino   default_print_array_index,
595*ef5ccd6cSJohn Marino   default_pass_by_reference,
596*ef5ccd6cSJohn Marino   c_get_string,
597*ef5ccd6cSJohn Marino   NULL,
598*ef5ccd6cSJohn Marino   iterate_over_symbols,
599*ef5ccd6cSJohn Marino   LANG_MAGIC
600*ef5ccd6cSJohn Marino };
601*ef5ccd6cSJohn Marino 
602*ef5ccd6cSJohn Marino static void *
build_go_types(struct gdbarch * gdbarch)603*ef5ccd6cSJohn Marino build_go_types (struct gdbarch *gdbarch)
604*ef5ccd6cSJohn Marino {
605*ef5ccd6cSJohn Marino   struct builtin_go_type *builtin_go_type
606*ef5ccd6cSJohn Marino     = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_go_type);
607*ef5ccd6cSJohn Marino 
608*ef5ccd6cSJohn Marino   builtin_go_type->builtin_void
609*ef5ccd6cSJohn Marino     = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
610*ef5ccd6cSJohn Marino   builtin_go_type->builtin_char
611*ef5ccd6cSJohn Marino     = arch_character_type (gdbarch, 8, 1, "char");
612*ef5ccd6cSJohn Marino   builtin_go_type->builtin_bool
613*ef5ccd6cSJohn Marino     = arch_boolean_type (gdbarch, 8, 0, "bool");
614*ef5ccd6cSJohn Marino   builtin_go_type->builtin_int
615*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "int");
616*ef5ccd6cSJohn Marino   builtin_go_type->builtin_uint
617*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "uint");
618*ef5ccd6cSJohn Marino   builtin_go_type->builtin_uintptr
619*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr");
620*ef5ccd6cSJohn Marino   builtin_go_type->builtin_int8
621*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 8, 0, "int8");
622*ef5ccd6cSJohn Marino   builtin_go_type->builtin_int16
623*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 16, 0, "int16");
624*ef5ccd6cSJohn Marino   builtin_go_type->builtin_int32
625*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 32, 0, "int32");
626*ef5ccd6cSJohn Marino   builtin_go_type->builtin_int64
627*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 64, 0, "int64");
628*ef5ccd6cSJohn Marino   builtin_go_type->builtin_uint8
629*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 8, 1, "uint8");
630*ef5ccd6cSJohn Marino   builtin_go_type->builtin_uint16
631*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 16, 1, "uint16");
632*ef5ccd6cSJohn Marino   builtin_go_type->builtin_uint32
633*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 32, 1, "uint32");
634*ef5ccd6cSJohn Marino   builtin_go_type->builtin_uint64
635*ef5ccd6cSJohn Marino     = arch_integer_type (gdbarch, 64, 1, "uint64");
636*ef5ccd6cSJohn Marino   builtin_go_type->builtin_float32
637*ef5ccd6cSJohn Marino     = arch_float_type (gdbarch, 32, "float32", NULL);
638*ef5ccd6cSJohn Marino   builtin_go_type->builtin_float64
639*ef5ccd6cSJohn Marino     = arch_float_type (gdbarch, 64, "float64", NULL);
640*ef5ccd6cSJohn Marino   builtin_go_type->builtin_complex64
641*ef5ccd6cSJohn Marino     = arch_complex_type (gdbarch, "complex64",
642*ef5ccd6cSJohn Marino 			 builtin_go_type->builtin_float32);
643*ef5ccd6cSJohn Marino   builtin_go_type->builtin_complex128
644*ef5ccd6cSJohn Marino     = arch_complex_type (gdbarch, "complex128",
645*ef5ccd6cSJohn Marino 			 builtin_go_type->builtin_float64);
646*ef5ccd6cSJohn Marino 
647*ef5ccd6cSJohn Marino   return builtin_go_type;
648*ef5ccd6cSJohn Marino }
649*ef5ccd6cSJohn Marino 
650*ef5ccd6cSJohn Marino static struct gdbarch_data *go_type_data;
651*ef5ccd6cSJohn Marino 
652*ef5ccd6cSJohn Marino const struct builtin_go_type *
builtin_go_type(struct gdbarch * gdbarch)653*ef5ccd6cSJohn Marino builtin_go_type (struct gdbarch *gdbarch)
654*ef5ccd6cSJohn Marino {
655*ef5ccd6cSJohn Marino   return gdbarch_data (gdbarch, go_type_data);
656*ef5ccd6cSJohn Marino }
657*ef5ccd6cSJohn Marino 
658*ef5ccd6cSJohn Marino extern initialize_file_ftype _initialize_go_language;
659*ef5ccd6cSJohn Marino 
660*ef5ccd6cSJohn Marino void
_initialize_go_language(void)661*ef5ccd6cSJohn Marino _initialize_go_language (void)
662*ef5ccd6cSJohn Marino {
663*ef5ccd6cSJohn Marino   go_type_data = gdbarch_data_register_post_init (build_go_types);
664*ef5ccd6cSJohn Marino 
665*ef5ccd6cSJohn Marino   add_language (&go_language_defn);
666*ef5ccd6cSJohn Marino }
667