-// Return the name to use for a type descriptor decl for TYPE. This
-// is used when TYPE does not have a name.
-
-std::string
-Gogo::unnamed_type_descriptor_decl_name(const Type* type)
-{
- return "__go_td_" + type->mangled_name(this);
-}
-
-// Return the name to use for a type descriptor decl for a type named
-// NAME, defined in the function IN_FUNCTION. IN_FUNCTION will
-// normally be NULL.
-
-std::string
-Gogo::type_descriptor_decl_name(const Named_object* no,
- const Named_object* in_function)
-{
- std::string ret = "__go_tdn_";
- if (no->type_value()->is_builtin())
- go_assert(in_function == NULL);
- else
- {
- const std::string& unique_prefix(no->package() == NULL
- ? this->unique_prefix()
- : no->package()->unique_prefix());
- const std::string& package_name(no->package() == NULL
- ? this->package_name()
- : no->package()->name());
- ret.append(unique_prefix);
- ret.append(1, '.');
- ret.append(package_name);
- ret.append(1, '.');
- if (in_function != NULL)
- {
- ret.append(Gogo::unpack_hidden_name(in_function->name()));
- ret.append(1, '.');
- }
- }
- ret.append(no->name());
- return ret;
-}
-
-// Where a type descriptor decl should be defined.
-
-Gogo::Type_descriptor_location
-Gogo::type_descriptor_location(const Type* type)
-{
- const Named_type* name = type->named_type();
- if (name != NULL)
- {
- if (name->named_object()->package() != NULL)
- {
- // This is a named type defined in a different package. The
- // descriptor should be defined in that package.
- return TYPE_DESCRIPTOR_UNDEFINED;
- }
- else if (name->is_builtin())
- {
- // We create the descriptor for a builtin type whenever we
- // need it.
- return TYPE_DESCRIPTOR_COMMON;
- }
- else
- {
- // This is a named type defined in this package. The
- // descriptor should be defined here.
- return TYPE_DESCRIPTOR_DEFINED;
- }
- }
- else
- {
- if (type->points_to() != NULL
- && type->points_to()->named_type() != NULL
- && type->points_to()->named_type()->named_object()->package() != NULL)
- {
- // This is an unnamed pointer to a named type defined in a
- // different package. The descriptor should be defined in
- // that package.
- return TYPE_DESCRIPTOR_UNDEFINED;
- }
- else
- {
- // This is an unnamed type. The descriptor could be defined
- // in any package where it is needed, and the linker will
- // pick one descriptor to keep.
- return TYPE_DESCRIPTOR_COMMON;
- }
- }
-}
-
-// Build a type descriptor decl for TYPE. INITIALIZER is a struct
-// composite literal which initializers the type descriptor.
-
-void
-Gogo::build_type_descriptor_decl(const Type* type, Expression* initializer,
- tree* pdecl)
-{
- const Named_type* name = type->named_type();
-
- // We can have multiple instances of unnamed types, but we only want
- // to emit the type descriptor once. We use a hash table to handle
- // this. This is not necessary for named types, as they are unique,
- // and we store the type descriptor decl in the type itself.
- tree* phash = NULL;
- if (name == NULL)
- {
- if (this->type_descriptor_decls_ == NULL)
- this->type_descriptor_decls_ = new Type_descriptor_decls(10);
-
- std::pair<Type_descriptor_decls::iterator, bool> ins =
- this->type_descriptor_decls_->insert(std::make_pair(type, NULL_TREE));
- if (!ins.second)
- {
- // We've already built a type descriptor for this type.
- *pdecl = ins.first->second;
- return;
- }
- phash = &ins.first->second;
- }
-
- std::string decl_name;
- if (name == NULL)
- decl_name = this->unnamed_type_descriptor_decl_name(type);
- else
- decl_name = this->type_descriptor_decl_name(name->named_object(),
- name->in_function());
- tree id = get_identifier_from_string(decl_name);
- Type* init_type = initializer->type();
- tree descriptor_type_tree = type_to_tree(init_type->get_backend(this));
- if (descriptor_type_tree == error_mark_node)
- {
- *pdecl = error_mark_node;
- return;
- }
- tree decl = build_decl(name == NULL ? BUILTINS_LOCATION : name->location(),
- VAR_DECL, id,
- build_qualified_type(descriptor_type_tree,
- TYPE_QUAL_CONST));
- TREE_READONLY(decl) = 1;
- TREE_CONSTANT(decl) = 1;
- DECL_ARTIFICIAL(decl) = 1;
-
- go_preserve_from_gc(decl);
- if (phash != NULL)
- *phash = decl;
-
- // We store the new DECL now because we may need to refer to it when
- // expanding INITIALIZER.
- *pdecl = decl;
-
- // If appropriate, just refer to the exported type identifier.
- Gogo::Type_descriptor_location type_descriptor_location =
- this->type_descriptor_location(type);
- if (type_descriptor_location == TYPE_DESCRIPTOR_UNDEFINED)
- {
- TREE_PUBLIC(decl) = 1;
- DECL_EXTERNAL(decl) = 1;
- return;
- }
-
- TREE_STATIC(decl) = 1;
- TREE_USED(decl) = 1;
-
- Translate_context context(this, NULL, NULL, NULL);
- context.set_is_const();
- tree constructor = initializer->get_tree(&context);
-
- if (constructor == error_mark_node)
- go_assert(saw_errors());
-
- DECL_INITIAL(decl) = constructor;
-
- if (type_descriptor_location == TYPE_DESCRIPTOR_DEFINED)
- TREE_PUBLIC(decl) = 1;
- else
- {
- go_assert(type_descriptor_location == TYPE_DESCRIPTOR_COMMON);
- make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
- resolve_unique_section(decl, 1, 0);
- }
-
- rest_of_decl_compilation(decl, 1, 0);
-}
-