compiler: use temporary variable for stack allocation
[official-gcc.git] / gcc / go / gofrontend / names.cc
blob5feea1244435f2643505638fcacfd790b8d2ba98
1 // names.cc -- Names used by gofrontend generated code.
3 // Copyright 2017 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.
7 #include "go-system.h"
9 #include "gogo.h"
10 #include "go-encode-id.h"
11 #include "types.h"
12 #include "expressions.h"
14 // This file contains functions that generate names that appear in the
15 // assembly code. This is not used for names that appear only in the
16 // debug info.
18 // Return the assembler name to use for an exported function, a
19 // method, or a function/method declaration. This is not called if
20 // the function has been given an explicit name via a magic //extern
21 // or //go:linkname comment. GO_NAME is the name that appears in the
22 // Go code. PACKAGE is the package where the function is defined, and
23 // is NULL for the package being compiled. For a method, RTYPE is
24 // the method's receiver type; for a function, RTYPE is NULL.
26 std::string
27 Gogo::function_asm_name(const std::string& go_name, const Package* package,
28 const Type* rtype)
30 std::string ret = (package == NULL
31 ? this->pkgpath_symbol()
32 : package->pkgpath_symbol());
34 if (rtype != NULL
35 && Gogo::is_hidden_name(go_name)
36 && Gogo::hidden_name_pkgpath(go_name) != this->pkgpath())
38 // This is a method created for an unexported method of an
39 // imported embedded type. Use the pkgpath of the imported
40 // package.
41 std::string p = Gogo::hidden_name_pkgpath(go_name);
42 ret = this->pkgpath_symbol_for_package(p);
45 ret.append(1, '.');
46 ret.append(Gogo::unpack_hidden_name(go_name));
48 if (rtype != NULL)
50 ret.append(1, '.');
51 ret.append(rtype->mangled_name(this));
54 return go_encode_id(ret);
57 // Return the name to use for a function descriptor. These symbols
58 // are globally visible.
60 std::string
61 Gogo::function_descriptor_name(Named_object* no)
63 std::string var_name;
64 if (no->is_function_declaration()
65 && !no->func_declaration_value()->asm_name().empty()
66 && Linemap::is_predeclared_location(no->location()))
68 if (no->func_declaration_value()->asm_name().substr(0, 8) != "runtime.")
69 var_name = no->func_declaration_value()->asm_name() + "_descriptor";
70 else
71 var_name = no->func_declaration_value()->asm_name() + "$descriptor";
73 else
75 if (no->package() == NULL)
76 var_name = this->pkgpath_symbol();
77 else
78 var_name = no->package()->pkgpath_symbol();
79 var_name.push_back('.');
80 var_name.append(Gogo::unpack_hidden_name(no->name()));
81 var_name.append("$descriptor");
83 return var_name;
86 // Return the name to use for a generated stub method. MNAME is the
87 // method name. These functions are globally visible. Note that this
88 // is the function name that corresponds to the name used for the
89 // method in Go source code, if this stub method were written in Go.
90 // The assembler name will be generated by Gogo::function_asm_name,
91 // and because this is a method that name will include the receiver
92 // type.
94 std::string
95 Gogo::stub_method_name(const std::string& mname)
97 return mname + "$stub";
100 // Return the names of the hash and equality functions for TYPE. If
101 // NAME is not NULL it is the name of the type. Set *HASH_NAME and
102 // *EQUAL_NAME.
104 void
105 Gogo::specific_type_function_names(const Type* type, const Named_type* name,
106 std::string *hash_name,
107 std::string *equal_name)
109 std::string base_name;
110 if (name == NULL)
112 // Mangled names can have '.' if they happen to refer to named
113 // types in some way. That's fine if this is simply a named
114 // type, but otherwise it will confuse the code that builds
115 // function identifiers. Remove '.' when necessary.
116 base_name = type->mangled_name(this);
117 size_t i;
118 while ((i = base_name.find('.')) != std::string::npos)
119 base_name[i] = '$';
120 base_name = this->pack_hidden_name(base_name, false);
122 else
124 // This name is already hidden or not as appropriate.
125 base_name = name->name();
126 unsigned int index;
127 const Named_object* in_function = name->in_function(&index);
128 if (in_function != NULL)
130 base_name.append(1, '$');
131 const Typed_identifier* rcvr =
132 in_function->func_value()->type()->receiver();
133 if (rcvr != NULL)
135 Named_type* rcvr_type = rcvr->type()->deref()->named_type();
136 base_name.append(Gogo::unpack_hidden_name(rcvr_type->name()));
137 base_name.append(1, '$');
139 base_name.append(Gogo::unpack_hidden_name(in_function->name()));
140 if (index > 0)
142 char buf[30];
143 snprintf(buf, sizeof buf, "%u", index);
144 base_name += '$';
145 base_name += buf;
149 *hash_name = base_name + "$hash";
150 *equal_name = base_name + "$equal";
153 // Return the assembler name to use for a global variable. GO_NAME is
154 // the name that appears in the Go code. PACKAGE is the package where
155 // the variable is defined, and is NULL for the package being
156 // compiled.
158 std::string
159 Gogo::global_var_asm_name(const std::string& go_name, const Package* package)
161 std::string ret = (package != NULL
162 ? package->pkgpath_symbol()
163 : this->pkgpath_symbol());
164 ret.push_back('.');
165 ret.append(Gogo::unpack_hidden_name(go_name));
166 return go_encode_id(ret);
169 // Return an erroneous name that indicates that an error has already
170 // been reported.
172 std::string
173 Gogo::erroneous_name()
175 static int erroneous_count;
176 char name[50];
177 snprintf(name, sizeof name, "$erroneous%d", erroneous_count);
178 ++erroneous_count;
179 return name;
182 // Return whether a name is an erroneous name.
184 bool
185 Gogo::is_erroneous_name(const std::string& name)
187 return name.compare(0, 10, "$erroneous") == 0;
190 // Return a name for a thunk object.
192 std::string
193 Gogo::thunk_name()
195 static int thunk_count;
196 char thunk_name[50];
197 snprintf(thunk_name, sizeof thunk_name, "$thunk%d", thunk_count);
198 ++thunk_count;
199 return thunk_name;
202 // Return whether a function is a thunk.
204 bool
205 Gogo::is_thunk(const Named_object* no)
207 return no->name().compare(0, 6, "$thunk") == 0;
210 // Return the name to use for an init function. There can be multiple
211 // functions named "init" so each one needs a different name.
213 std::string
214 Gogo::init_function_name()
216 static int init_count;
217 char buf[30];
218 snprintf(buf, sizeof buf, ".$init%d", init_count);
219 ++init_count;
220 return buf;
223 // Return the name to use for a nested function.
225 std::string
226 Gogo::nested_function_name()
228 static int nested_count;
229 char buf[30];
230 snprintf(buf, sizeof buf, ".$nested%d", nested_count);
231 ++nested_count;
232 return buf;
235 // Return the name to use for a sink function, a function whose name
236 // is simply underscore. We don't really need these functions but we
237 // do have to generate them for error checking.
239 std::string
240 Gogo::sink_function_name()
242 static int sink_count;
243 char buf[30];
244 snprintf(buf, sizeof buf, ".$sink%d", sink_count);
245 ++sink_count;
246 return buf;
249 // Return the name to use for a redefined function. These functions
250 // are erroneous but we still generate them for further error
251 // checking.
253 std::string
254 Gogo::redefined_function_name()
256 static int redefinition_count;
257 char buf[30];
258 snprintf(buf, sizeof buf, ".$redefined%d", redefinition_count);
259 ++redefinition_count;
260 return buf;
263 // Return the name to use for a recover thunk for the function NAME.
264 // If the function is a method, RTYPE is the receiver type.
266 std::string
267 Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
269 std::string ret(name);
270 if (rtype != NULL)
272 ret.push_back('$');
273 ret.append(rtype->mangled_name(this));
275 ret.append("$recover");
276 return ret;
279 // Return the name to use for a GC root variable. The GC root
280 // variable is a composite literal that is passed to
281 // runtime.registerGCRoots. There is at most one of these variables
282 // per compilation.
284 std::string
285 Gogo::gc_root_name()
287 return "gc0";
290 // Return the name to use for a composite literal or string
291 // initializer. This is a local name never referenced outside of this
292 // file.
294 std::string
295 Gogo::initializer_name()
297 static unsigned int counter;
298 char buf[30];
299 snprintf(buf, sizeof buf, "C%u", counter);
300 ++counter;
301 return buf;
304 // Return the name of the variable used to represent the zero value of
305 // a map. This is a globally visible common symbol.
307 std::string
308 Gogo::map_zero_value_name()
310 return "go$zerovalue";
313 // Return the name to use for the import control function.
315 const std::string&
316 Gogo::get_init_fn_name()
318 if (this->init_fn_name_.empty())
320 go_assert(this->package_ != NULL);
321 if (this->is_main_package())
323 // Use a name that the runtime knows.
324 this->init_fn_name_ = "__go_init_main";
326 else
328 std::string s = this->pkgpath_symbol();
329 s.append("..import");
330 this->init_fn_name_ = s;
334 return this->init_fn_name_;
337 // Return a mangled name for a type. These names appear in symbol
338 // names in the assembler file for things like type descriptors and
339 // methods.
341 std::string
342 Type::mangled_name(Gogo* gogo) const
344 std::string ret;
346 // The do_mangled_name virtual function should set RET to the
347 // mangled name. For a composite type it should append a code for
348 // the composition and then call do_mangled_name on the components.
349 this->do_mangled_name(gogo, &ret);
351 return ret;
354 // The mangled name is implemented as a method on each instance of
355 // Type.
357 void
358 Error_type::do_mangled_name(Gogo*, std::string* ret) const
360 ret->push_back('E');
363 void
364 Void_type::do_mangled_name(Gogo*, std::string* ret) const
366 ret->push_back('v');
369 void
370 Boolean_type::do_mangled_name(Gogo*, std::string* ret) const
372 ret->push_back('b');
375 void
376 Integer_type::do_mangled_name(Gogo*, std::string* ret) const
378 char buf[100];
379 snprintf(buf, sizeof buf, "i%s%s%de",
380 this->is_abstract_ ? "a" : "",
381 this->is_unsigned_ ? "u" : "",
382 this->bits_);
383 ret->append(buf);
386 void
387 Float_type::do_mangled_name(Gogo*, std::string* ret) const
389 char buf[100];
390 snprintf(buf, sizeof buf, "f%s%de",
391 this->is_abstract_ ? "a" : "",
392 this->bits_);
393 ret->append(buf);
396 void
397 Complex_type::do_mangled_name(Gogo*, std::string* ret) const
399 char buf[100];
400 snprintf(buf, sizeof buf, "c%s%de",
401 this->is_abstract_ ? "a" : "",
402 this->bits_);
403 ret->append(buf);
406 void
407 String_type::do_mangled_name(Gogo*, std::string* ret) const
409 ret->push_back('z');
412 void
413 Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const
415 ret->push_back('F');
417 if (this->receiver_ != NULL)
419 ret->push_back('m');
420 this->append_mangled_name(this->receiver_->type(), gogo, ret);
423 const Typed_identifier_list* params = this->parameters();
424 if (params != NULL)
426 ret->push_back('p');
427 for (Typed_identifier_list::const_iterator p = params->begin();
428 p != params->end();
429 ++p)
430 this->append_mangled_name(p->type(), gogo, ret);
431 if (this->is_varargs_)
432 ret->push_back('V');
433 ret->push_back('e');
436 const Typed_identifier_list* results = this->results();
437 if (results != NULL)
439 ret->push_back('r');
440 for (Typed_identifier_list::const_iterator p = results->begin();
441 p != results->end();
442 ++p)
443 this->append_mangled_name(p->type(), gogo, ret);
444 ret->push_back('e');
447 ret->push_back('e');
450 void
451 Pointer_type::do_mangled_name(Gogo* gogo, std::string* ret) const
453 ret->push_back('p');
454 this->append_mangled_name(this->to_type_, gogo, ret);
457 void
458 Nil_type::do_mangled_name(Gogo*, std::string* ret) const
460 ret->push_back('n');
463 void
464 Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
466 ret->push_back('S');
468 const Struct_field_list* fields = this->fields_;
469 if (fields != NULL)
471 for (Struct_field_list::const_iterator p = fields->begin();
472 p != fields->end();
473 ++p)
475 if (p->is_anonymous())
476 ret->append("0_");
477 else
480 std::string n(Gogo::mangle_possibly_hidden_name(p->field_name()));
481 char buf[20];
482 snprintf(buf, sizeof buf, "%u_",
483 static_cast<unsigned int>(n.length()));
484 ret->append(buf);
485 ret->append(n);
488 // For an anonymous field with an alias type, the field name
489 // is the alias name.
490 if (p->is_anonymous()
491 && p->type()->named_type() != NULL
492 && p->type()->named_type()->is_alias())
493 p->type()->named_type()->append_mangled_type_name(gogo, true, ret);
494 else
495 this->append_mangled_name(p->type(), gogo, ret);
496 if (p->has_tag())
498 const std::string& tag(p->tag());
499 std::string out;
500 for (std::string::const_iterator p = tag.begin();
501 p != tag.end();
502 ++p)
504 if (ISALNUM(*p) || *p == '_')
505 out.push_back(*p);
506 else
508 char buf[20];
509 snprintf(buf, sizeof buf, ".%x.",
510 static_cast<unsigned int>(*p));
511 out.append(buf);
514 char buf[20];
515 snprintf(buf, sizeof buf, "T%u_",
516 static_cast<unsigned int>(out.length()));
517 ret->append(buf);
518 ret->append(out);
523 if (this->is_struct_incomparable_)
524 ret->push_back('x');
526 ret->push_back('e');
529 void
530 Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const
532 ret->push_back('A');
533 this->append_mangled_name(this->element_type_, gogo, ret);
534 if (this->length_ != NULL)
536 Numeric_constant nc;
537 if (!this->length_->numeric_constant_value(&nc))
539 go_assert(saw_errors());
540 return;
542 mpz_t val;
543 if (!nc.to_int(&val))
545 go_assert(saw_errors());
546 return;
548 char *s = mpz_get_str(NULL, 10, val);
549 ret->append(s);
550 free(s);
551 mpz_clear(val);
552 if (this->is_array_incomparable_)
553 ret->push_back('x');
555 ret->push_back('e');
558 void
559 Map_type::do_mangled_name(Gogo* gogo, std::string* ret) const
561 ret->push_back('M');
562 this->append_mangled_name(this->key_type_, gogo, ret);
563 ret->append("__");
564 this->append_mangled_name(this->val_type_, gogo, ret);
567 void
568 Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const
570 ret->push_back('C');
571 this->append_mangled_name(this->element_type_, gogo, ret);
572 if (this->may_send_)
573 ret->push_back('s');
574 if (this->may_receive_)
575 ret->push_back('r');
576 ret->push_back('e');
579 void
580 Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const
582 go_assert(this->methods_are_finalized_);
584 ret->push_back('I');
586 const Typed_identifier_list* methods = this->all_methods_;
587 if (methods != NULL && !this->seen_)
589 this->seen_ = true;
590 for (Typed_identifier_list::const_iterator p = methods->begin();
591 p != methods->end();
592 ++p)
594 if (!p->name().empty())
596 std::string n(Gogo::mangle_possibly_hidden_name(p->name()));
597 char buf[20];
598 snprintf(buf, sizeof buf, "%u_",
599 static_cast<unsigned int>(n.length()));
600 ret->append(buf);
601 ret->append(n);
603 this->append_mangled_name(p->type(), gogo, ret);
605 this->seen_ = false;
608 ret->push_back('e');
611 void
612 Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
614 this->append_mangled_type_name(gogo, false, ret);
617 void
618 Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const
620 if (this->is_defined())
621 this->append_mangled_name(this->real_type(), gogo, ret);
622 else
624 const Named_object* no = this->named_object();
625 std::string name;
626 if (no->package() == NULL)
627 name = gogo->pkgpath_symbol();
628 else
629 name = no->package()->pkgpath_symbol();
630 name += '.';
631 name += Gogo::unpack_hidden_name(no->name());
632 char buf[20];
633 snprintf(buf, sizeof buf, "N%u_",
634 static_cast<unsigned int>(name.length()));
635 ret->append(buf);
636 ret->append(name);
640 // Append the mangled name for a named type to RET. For an alias we
641 // normally use the real name, but if USE_ALIAS is true we use the
642 // alias name itself.
644 void
645 Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias,
646 std::string* ret) const
648 if (this->is_error_)
649 return;
650 if (this->is_alias_ && !use_alias)
652 if (this->seen_alias_)
653 return;
654 this->seen_alias_ = true;
655 this->append_mangled_name(this->type_, gogo, ret);
656 this->seen_alias_ = false;
657 return;
659 Named_object* no = this->named_object_;
660 std::string name;
661 if (this->is_builtin())
662 go_assert(this->in_function_ == NULL);
663 else
665 const std::string& pkgpath(no->package() == NULL
666 ? gogo->pkgpath_symbol()
667 : no->package()->pkgpath_symbol());
668 name = pkgpath;
669 name.append(1, '.');
670 if (this->in_function_ != NULL)
672 const Typed_identifier* rcvr =
673 this->in_function_->func_value()->type()->receiver();
674 if (rcvr != NULL)
676 Named_type* rcvr_type = rcvr->type()->deref()->named_type();
677 name.append(Gogo::unpack_hidden_name(rcvr_type->name()));
678 name.append(1, '.');
680 name.append(Gogo::unpack_hidden_name(this->in_function_->name()));
681 name.append(1, '$');
682 if (this->in_function_index_ > 0)
684 char buf[30];
685 snprintf(buf, sizeof buf, "%u", this->in_function_index_);
686 name.append(buf);
687 name.append(1, '$');
691 name.append(Gogo::unpack_hidden_name(no->name()));
692 char buf[20];
693 snprintf(buf, sizeof buf, "N%u_", static_cast<unsigned int>(name.length()));
694 ret->append(buf);
695 ret->append(name);
698 // Return the name for the type descriptor symbol for TYPE. This can
699 // be a global, common, or local symbol, depending. NT is not NULL if
700 // it is the name to use.
702 std::string
703 Gogo::type_descriptor_name(Type* type, Named_type* nt)
705 // The type descriptor symbol for the unsafe.Pointer type is defined
706 // in libgo/runtime/go-unsafe-pointer.c, so just use a reference to
707 // that symbol.
708 if (type->is_unsafe_pointer_type())
709 return "__go_tdn_unsafe.Pointer";
711 if (nt == NULL)
712 return "__go_td_" + type->mangled_name(this);
714 Named_object* no = nt->named_object();
715 unsigned int index;
716 const Named_object* in_function = nt->in_function(&index);
717 std::string ret = "__go_tdn_";
718 if (nt->is_builtin())
719 go_assert(in_function == NULL);
720 else
722 const std::string& pkgpath(no->package() == NULL
723 ? this->pkgpath_symbol()
724 : no->package()->pkgpath_symbol());
725 ret.append(pkgpath);
726 ret.append(1, '.');
727 if (in_function != NULL)
729 const Typed_identifier* rcvr =
730 in_function->func_value()->type()->receiver();
731 if (rcvr != NULL)
733 Named_type* rcvr_type = rcvr->type()->deref()->named_type();
734 ret.append(Gogo::unpack_hidden_name(rcvr_type->name()));
735 ret.append(1, '.');
737 ret.append(Gogo::unpack_hidden_name(in_function->name()));
738 ret.append(1, '.');
739 if (index > 0)
741 char buf[30];
742 snprintf(buf, sizeof buf, "%u", index);
743 ret.append(buf);
744 ret.append(1, '.');
749 std::string mname(Gogo::mangle_possibly_hidden_name(no->name()));
750 ret.append(mname);
752 return ret;
755 // Return the name for the GC symbol for a type. This is used to
756 // initialize the gcdata field of a type descriptor. This is a local
757 // name never referenced outside of this assembly file. (Note that
758 // some type descriptors will initialize the gcdata field with a name
759 // generated by ptrmask_symbol_name rather than this method.)
761 std::string
762 Gogo::gc_symbol_name(Type* type)
764 return this->type_descriptor_name(type, type->named_type()) + "$gc";
767 // Return the name for a ptrmask variable. PTRMASK_SYM_NAME is a
768 // base64 string encoding the ptrmask (as returned by Ptrmask::symname
769 // in types.cc). This name is used to intialize the gcdata field of a
770 // type descriptor. These names are globally visible. (Note that
771 // some type descriptors will initialize the gcdata field with a name
772 // generated by gc_symbol_name rather than this method.)
774 std::string
775 Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
777 return "runtime.gcbits." + ptrmask_sym_name;
780 // Return the name to use for an interface method table used for the
781 // ordinary type TYPE converted to the interface type ITYPE.
782 // IS_POINTER is true if this is for the method set for a pointer
783 // receiver.
785 std::string
786 Gogo::interface_method_table_name(Interface_type* itype, Type* type,
787 bool is_pointer)
789 return ((is_pointer ? "__go_pimt__" : "__go_imt_")
790 + itype->mangled_name(this)
791 + "__"
792 + type->mangled_name(this));