mirror of git://gcc.gnu.org/git/gcc.git
compiler: Use backend interface for type sizes and alignments.
* go-gcc.cc (Gcc_backend::type_size): New function. (Gcc_backend::type_alignment): New function. (Gcc_backend::type_field_alignment): New function. (Gcc_backend::type_field_offset): New function. * go-backend.c (go_type_alignment): Remove. * go-c.h (go_type_alignment): Don't declare. From-SVN: r183089
This commit is contained in:
parent
5313d330b2
commit
ef1ed13d9a
|
@ -1,3 +1,12 @@
|
||||||
|
2012-01-10 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
* go-gcc.cc (Gcc_backend::type_size): New function.
|
||||||
|
(Gcc_backend::type_alignment): New function.
|
||||||
|
(Gcc_backend::type_field_alignment): New function.
|
||||||
|
(Gcc_backend::type_field_offset): New function.
|
||||||
|
* go-backend.c (go_type_alignment): Remove.
|
||||||
|
* go-c.h (go_type_alignment): Don't declare.
|
||||||
|
|
||||||
2011-12-27 Ian Lance Taylor <iant@google.com>
|
2011-12-27 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* go-gcc.cc (Gcc_backend::set_placeholder_struct_type): Use
|
* go-gcc.cc (Gcc_backend::set_placeholder_struct_type): Use
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* go-backend.c -- Go frontend interface to gcc backend.
|
/* go-backend.c -- Go frontend interface to gcc backend.
|
||||||
Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GCC.
|
This file is part of GCC.
|
||||||
|
|
||||||
|
@ -48,14 +48,6 @@ along with GCC; see the file COPYING3. If not see
|
||||||
/* This file holds all the cases where the Go frontend needs
|
/* This file holds all the cases where the Go frontend needs
|
||||||
information from gcc's backend. */
|
information from gcc's backend. */
|
||||||
|
|
||||||
/* Return the alignment in bytes of a value of type T. */
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
go_type_alignment (tree t)
|
|
||||||
{
|
|
||||||
return TYPE_ALIGN_UNIT (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the alignment in bytes of a struct field of type T. */
|
/* Return the alignment in bytes of a struct field of type T. */
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* go-c.h -- Header file for go frontend gcc C interface.
|
/* go-c.h -- Header file for go frontend gcc C interface.
|
||||||
Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
|
Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GCC.
|
This file is part of GCC.
|
||||||
|
|
||||||
|
@ -59,8 +59,6 @@ extern void go_preserve_from_gc (tree);
|
||||||
|
|
||||||
extern const char *go_localize_identifier (const char*);
|
extern const char *go_localize_identifier (const char*);
|
||||||
|
|
||||||
extern unsigned int go_type_alignment (tree);
|
|
||||||
|
|
||||||
extern unsigned int go_field_alignment (tree);
|
extern unsigned int go_field_alignment (tree);
|
||||||
|
|
||||||
extern void go_trampoline_info (unsigned int *size, unsigned int *alignment);
|
extern void go_trampoline_info (unsigned int *size, unsigned int *alignment);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// go-gcc.cc -- Go frontend to gcc IR.
|
// go-gcc.cc -- Go frontend to gcc IR.
|
||||||
// Copyright (C) 2011 Free Software Foundation, Inc.
|
// Copyright (C) 2011, 2012 Free Software Foundation, Inc.
|
||||||
// Contributed by Ian Lance Taylor, Google.
|
// Contributed by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
// This file is part of GCC.
|
// This file is part of GCC.
|
||||||
|
@ -195,6 +195,18 @@ class Gcc_backend : public Backend
|
||||||
bool
|
bool
|
||||||
is_circular_pointer_type(Btype*);
|
is_circular_pointer_type(Btype*);
|
||||||
|
|
||||||
|
size_t
|
||||||
|
type_size(Btype*);
|
||||||
|
|
||||||
|
size_t
|
||||||
|
type_alignment(Btype*);
|
||||||
|
|
||||||
|
size_t
|
||||||
|
type_field_alignment(Btype*);
|
||||||
|
|
||||||
|
size_t
|
||||||
|
type_field_offset(Btype*, size_t index);
|
||||||
|
|
||||||
// Expressions.
|
// Expressions.
|
||||||
|
|
||||||
Bexpression*
|
Bexpression*
|
||||||
|
@ -755,6 +767,56 @@ Gcc_backend::is_circular_pointer_type(Btype* btype)
|
||||||
return btype->get_tree() == ptr_type_node;
|
return btype->get_tree() == ptr_type_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the size of a type.
|
||||||
|
|
||||||
|
size_t
|
||||||
|
Gcc_backend::type_size(Btype* btype)
|
||||||
|
{
|
||||||
|
tree t = TYPE_SIZE_UNIT(btype->get_tree());
|
||||||
|
gcc_assert(TREE_CODE(t) == INTEGER_CST);
|
||||||
|
gcc_assert(TREE_INT_CST_HIGH(t) == 0);
|
||||||
|
unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
|
||||||
|
size_t ret = static_cast<size_t>(val_wide);
|
||||||
|
gcc_assert(ret == val_wide);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the alignment of a type.
|
||||||
|
|
||||||
|
size_t
|
||||||
|
Gcc_backend::type_alignment(Btype* btype)
|
||||||
|
{
|
||||||
|
return TYPE_ALIGN_UNIT(btype->get_tree());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the alignment of a struct field of type BTYPE.
|
||||||
|
|
||||||
|
size_t
|
||||||
|
Gcc_backend::type_field_alignment(Btype* btype)
|
||||||
|
{
|
||||||
|
return go_field_alignment(btype->get_tree());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the offset of a field in a struct.
|
||||||
|
|
||||||
|
size_t
|
||||||
|
Gcc_backend::type_field_offset(Btype* btype, size_t index)
|
||||||
|
{
|
||||||
|
tree struct_tree = btype->get_tree();
|
||||||
|
gcc_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
|
||||||
|
tree field = TYPE_FIELDS(struct_tree);
|
||||||
|
for (; index > 0; --index)
|
||||||
|
{
|
||||||
|
field = DECL_CHAIN(field);
|
||||||
|
gcc_assert(field != NULL_TREE);
|
||||||
|
}
|
||||||
|
HOST_WIDE_INT offset_wide = int_byte_position(field);
|
||||||
|
gcc_assert(offset_wide >= 0);
|
||||||
|
size_t ret = static_cast<size_t>(offset_wide);
|
||||||
|
gcc_assert(ret == static_cast<unsigned HOST_WIDE_INT>(offset_wide));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the zero value for a type.
|
// Return the zero value for a type.
|
||||||
|
|
||||||
Bexpression*
|
Bexpression*
|
||||||
|
|
|
@ -198,6 +198,25 @@ class Backend
|
||||||
virtual bool
|
virtual bool
|
||||||
is_circular_pointer_type(Btype*) = 0;
|
is_circular_pointer_type(Btype*) = 0;
|
||||||
|
|
||||||
|
// Return the size of a type.
|
||||||
|
virtual size_t
|
||||||
|
type_size(Btype*) = 0;
|
||||||
|
|
||||||
|
// Return the alignment of a type.
|
||||||
|
virtual size_t
|
||||||
|
type_alignment(Btype*) = 0;
|
||||||
|
|
||||||
|
// Return the alignment of a struct field of this type. This is
|
||||||
|
// normally the same as type_alignment, but not always.
|
||||||
|
virtual size_t
|
||||||
|
type_field_alignment(Btype*) = 0;
|
||||||
|
|
||||||
|
// Return the offset of field INDEX in a struct type. INDEX is the
|
||||||
|
// entry in the FIELDS std::vector parameter of struct_type or
|
||||||
|
// set_placeholder_struct_type.
|
||||||
|
virtual size_t
|
||||||
|
type_field_offset(Btype*, size_t index) = 0;
|
||||||
|
|
||||||
// Expressions.
|
// Expressions.
|
||||||
|
|
||||||
// Return an expression for a zero value of the given type. This is
|
// Return an expression for a zero value of the given type. This is
|
||||||
|
|
|
@ -7979,35 +7979,32 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
|
||||||
return false;
|
return false;
|
||||||
if (arg_type->named_type() != NULL)
|
if (arg_type->named_type() != NULL)
|
||||||
arg_type->named_type()->convert(this->gogo_);
|
arg_type->named_type()->convert(this->gogo_);
|
||||||
tree arg_type_tree = type_to_tree(arg_type->get_backend(this->gogo_));
|
|
||||||
if (arg_type_tree == error_mark_node)
|
unsigned int ret;
|
||||||
return false;
|
|
||||||
unsigned long val_long;
|
|
||||||
if (this->code_ == BUILTIN_SIZEOF)
|
if (this->code_ == BUILTIN_SIZEOF)
|
||||||
{
|
{
|
||||||
tree type_size = TYPE_SIZE_UNIT(arg_type_tree);
|
if (!arg_type->backend_type_size(this->gogo_, &ret))
|
||||||
go_assert(TREE_CODE(type_size) == INTEGER_CST);
|
|
||||||
if (TREE_INT_CST_HIGH(type_size) != 0)
|
|
||||||
return false;
|
|
||||||
unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(type_size);
|
|
||||||
val_long = static_cast<unsigned long>(val_wide);
|
|
||||||
if (val_long != val_wide)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (this->code_ == BUILTIN_ALIGNOF)
|
else if (this->code_ == BUILTIN_ALIGNOF)
|
||||||
{
|
{
|
||||||
if (arg->field_reference_expression() == NULL)
|
if (arg->field_reference_expression() == NULL)
|
||||||
val_long = go_type_alignment(arg_type_tree);
|
{
|
||||||
|
if (!arg_type->backend_type_align(this->gogo_, &ret))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Calling unsafe.Alignof(s.f) returns the alignment of
|
// Calling unsafe.Alignof(s.f) returns the alignment of
|
||||||
// the type of f when it is used as a field in a struct.
|
// the type of f when it is used as a field in a struct.
|
||||||
val_long = go_field_alignment(arg_type_tree);
|
if (!arg_type->backend_type_field_align(this->gogo_, &ret))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
go_unreachable();
|
go_unreachable();
|
||||||
mpz_set_ui(val, val_long);
|
|
||||||
|
mpz_set_ui(val, ret);
|
||||||
*ptype = NULL;
|
*ptype = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -8025,21 +8022,12 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
|
||||||
return false;
|
return false;
|
||||||
if (st->named_type() != NULL)
|
if (st->named_type() != NULL)
|
||||||
st->named_type()->convert(this->gogo_);
|
st->named_type()->convert(this->gogo_);
|
||||||
tree struct_tree = type_to_tree(st->get_backend(this->gogo_));
|
unsigned int offset;
|
||||||
go_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
|
if (!st->struct_type()->backend_field_offset(this->gogo_,
|
||||||
tree field = TYPE_FIELDS(struct_tree);
|
farg->field_index(),
|
||||||
for (unsigned int index = farg->field_index(); index > 0; --index)
|
&offset))
|
||||||
{
|
|
||||||
field = DECL_CHAIN(field);
|
|
||||||
go_assert(field != NULL_TREE);
|
|
||||||
}
|
|
||||||
HOST_WIDE_INT offset_wide = int_byte_position (field);
|
|
||||||
if (offset_wide < 0)
|
|
||||||
return false;
|
return false;
|
||||||
unsigned long offset_long = static_cast<unsigned long>(offset_wide);
|
mpz_set_ui(val, offset);
|
||||||
if (offset_long != static_cast<unsigned HOST_WIDE_INT>(offset_wide))
|
|
||||||
return false;
|
|
||||||
mpz_set_ui(val, offset_long);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -13939,25 +13927,26 @@ Type_info_expression::do_type()
|
||||||
tree
|
tree
|
||||||
Type_info_expression::do_get_tree(Translate_context* context)
|
Type_info_expression::do_get_tree(Translate_context* context)
|
||||||
{
|
{
|
||||||
tree type_tree = type_to_tree(this->type_->get_backend(context->gogo()));
|
Btype* btype = this->type_->get_backend(context->gogo());
|
||||||
if (type_tree == error_mark_node)
|
Gogo* gogo = context->gogo();
|
||||||
return error_mark_node;
|
size_t val;
|
||||||
|
switch (this->type_info_)
|
||||||
tree val_type_tree = type_to_tree(this->type()->get_backend(context->gogo()));
|
|
||||||
go_assert(val_type_tree != error_mark_node);
|
|
||||||
|
|
||||||
if (this->type_info_ == TYPE_INFO_SIZE)
|
|
||||||
return fold_convert_loc(BUILTINS_LOCATION, val_type_tree,
|
|
||||||
TYPE_SIZE_UNIT(type_tree));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
unsigned int val;
|
case TYPE_INFO_SIZE:
|
||||||
if (this->type_info_ == TYPE_INFO_ALIGNMENT)
|
val = gogo->backend()->type_size(btype);
|
||||||
val = go_type_alignment(type_tree);
|
break;
|
||||||
else
|
case TYPE_INFO_ALIGNMENT:
|
||||||
val = go_field_alignment(type_tree);
|
val = gogo->backend()->type_alignment(btype);
|
||||||
return build_int_cstu(val_type_tree, val);
|
break;
|
||||||
|
case TYPE_INFO_FIELD_ALIGNMENT:
|
||||||
|
val = gogo->backend()->type_field_alignment(btype);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
go_unreachable();
|
||||||
}
|
}
|
||||||
|
tree val_type_tree = type_to_tree(this->type()->get_backend(gogo));
|
||||||
|
go_assert(val_type_tree != error_mark_node);
|
||||||
|
return build_int_cstu(val_type_tree, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump ast representation for a type info expression.
|
// Dump ast representation for a type info expression.
|
||||||
|
|
|
@ -1950,6 +1950,126 @@ Type::mangled_name(Gogo* gogo) const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return whether the backend size of the type is known.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Type::is_backend_type_size_known(Gogo* gogo) const
|
||||||
|
{
|
||||||
|
switch (this->classification_)
|
||||||
|
{
|
||||||
|
case TYPE_ERROR:
|
||||||
|
case TYPE_VOID:
|
||||||
|
case TYPE_BOOLEAN:
|
||||||
|
case TYPE_INTEGER:
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
case TYPE_COMPLEX:
|
||||||
|
case TYPE_STRING:
|
||||||
|
case TYPE_FUNCTION:
|
||||||
|
case TYPE_POINTER:
|
||||||
|
case TYPE_NIL:
|
||||||
|
case TYPE_MAP:
|
||||||
|
case TYPE_CHANNEL:
|
||||||
|
case TYPE_INTERFACE:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
{
|
||||||
|
const Struct_field_list* fields = this->struct_type()->fields();
|
||||||
|
for (Struct_field_list::const_iterator pf = fields->begin();
|
||||||
|
pf != fields->end();
|
||||||
|
++pf)
|
||||||
|
if (!pf->type()->is_backend_type_size_known(gogo))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
{
|
||||||
|
const Array_type* at = this->array_type();
|
||||||
|
if (at->length() == NULL)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpz_t ival;
|
||||||
|
mpz_init(ival);
|
||||||
|
Type* dummy;
|
||||||
|
bool length_known = at->length()->integer_constant_value(true,
|
||||||
|
ival,
|
||||||
|
&dummy);
|
||||||
|
mpz_clear(ival);
|
||||||
|
if (!length_known)
|
||||||
|
return false;
|
||||||
|
return at->element_type()->is_backend_type_size_known(gogo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_NAMED:
|
||||||
|
return this->named_type()->is_named_backend_type_size_known();
|
||||||
|
|
||||||
|
case TYPE_FORWARD:
|
||||||
|
{
|
||||||
|
const Forward_declaration_type* fdt = this->forward_declaration_type();
|
||||||
|
return fdt->real_type()->is_backend_type_size_known(gogo);
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_SINK:
|
||||||
|
case TYPE_CALL_MULTIPLE_RESULT:
|
||||||
|
go_unreachable();
|
||||||
|
|
||||||
|
default:
|
||||||
|
go_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the size of the type can be determined, set *PSIZE to the size
|
||||||
|
// in bytes and return true. Otherwise, return false. This queries
|
||||||
|
// the backend.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Type::backend_type_size(Gogo* gogo, unsigned int *psize)
|
||||||
|
{
|
||||||
|
Btype* btype = this->get_backend(gogo);
|
||||||
|
if (!this->is_backend_type_size_known(gogo))
|
||||||
|
return false;
|
||||||
|
size_t size = gogo->backend()->type_size(btype);
|
||||||
|
*psize = static_cast<unsigned int>(size);
|
||||||
|
if (*psize != size)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the alignment of the type can be determined, set *PALIGN to
|
||||||
|
// the alignment in bytes and return true. Otherwise, return false.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Type::backend_type_align(Gogo* gogo, unsigned int *palign)
|
||||||
|
{
|
||||||
|
Btype* btype = this->get_backend(gogo);
|
||||||
|
if (!this->is_backend_type_size_known(gogo))
|
||||||
|
return false;
|
||||||
|
size_t align = gogo->backend()->type_alignment(btype);
|
||||||
|
*palign = static_cast<unsigned int>(align);
|
||||||
|
if (*palign != align)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Like backend_type_align, but return the alignment when used as a
|
||||||
|
// field.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Type::backend_type_field_align(Gogo* gogo, unsigned int *palign)
|
||||||
|
{
|
||||||
|
Btype* btype = this->get_backend(gogo);
|
||||||
|
if (!this->is_backend_type_size_known(gogo))
|
||||||
|
return false;
|
||||||
|
size_t a = gogo->backend()->type_field_alignment(btype);
|
||||||
|
*palign = static_cast<unsigned int>(a);
|
||||||
|
if (*palign != a)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Default function to export a type.
|
// Default function to export a type.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -4589,6 +4709,24 @@ Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
|
||||||
ret->push_back('e');
|
ret->push_back('e');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the offset of field INDEX in the backend implementation can be
|
||||||
|
// determined, set *POFFSET to the offset in bytes and return true.
|
||||||
|
// Otherwise, return false.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Struct_type::backend_field_offset(Gogo* gogo, unsigned int index,
|
||||||
|
unsigned int* poffset)
|
||||||
|
{
|
||||||
|
Btype* btype = this->get_backend(gogo);
|
||||||
|
if (!this->is_backend_type_size_known(gogo))
|
||||||
|
return false;
|
||||||
|
size_t offset = gogo->backend()->type_field_offset(btype, index);
|
||||||
|
*poffset = static_cast<unsigned int>(offset);
|
||||||
|
if (*poffset != offset)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Export.
|
// Export.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -7518,6 +7656,7 @@ Named_type::convert(Gogo* gogo)
|
||||||
|
|
||||||
this->named_btype_ = bt;
|
this->named_btype_ = bt;
|
||||||
this->is_converted_ = true;
|
this->is_converted_ = true;
|
||||||
|
this->is_placeholder_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the placeholder for a named type. This is the first step in
|
// Create the placeholder for a named type. This is the first step in
|
||||||
|
@ -7578,6 +7717,7 @@ Named_type::create_placeholder(Gogo* gogo)
|
||||||
case TYPE_STRUCT:
|
case TYPE_STRUCT:
|
||||||
bt = gogo->backend()->placeholder_struct_type(this->name(),
|
bt = gogo->backend()->placeholder_struct_type(this->name(),
|
||||||
this->location_);
|
this->location_);
|
||||||
|
this->is_placeholder_ = true;
|
||||||
set_name = false;
|
set_name = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7586,8 +7726,11 @@ Named_type::create_placeholder(Gogo* gogo)
|
||||||
bt = gogo->backend()->placeholder_struct_type(this->name(),
|
bt = gogo->backend()->placeholder_struct_type(this->name(),
|
||||||
this->location_);
|
this->location_);
|
||||||
else
|
else
|
||||||
bt = gogo->backend()->placeholder_array_type(this->name(),
|
{
|
||||||
this->location_);
|
bt = gogo->backend()->placeholder_array_type(this->name(),
|
||||||
|
this->location_);
|
||||||
|
this->is_placeholder_ = true;
|
||||||
|
}
|
||||||
set_name = false;
|
set_name = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -861,6 +861,27 @@ class Type
|
||||||
std::string
|
std::string
|
||||||
mangled_name(Gogo*) const;
|
mangled_name(Gogo*) const;
|
||||||
|
|
||||||
|
// If the size of the type can be determined, set *PSIZE to the size
|
||||||
|
// in bytes and return true. Otherwise, return false. This queries
|
||||||
|
// the backend.
|
||||||
|
bool
|
||||||
|
backend_type_size(Gogo*, unsigned int* psize);
|
||||||
|
|
||||||
|
// If the alignment of the type can be determined, set *PALIGN to
|
||||||
|
// the alignment in bytes and return true. Otherwise, return false.
|
||||||
|
bool
|
||||||
|
backend_type_align(Gogo*, unsigned int* palign);
|
||||||
|
|
||||||
|
// If the alignment of a struct field of this type can be
|
||||||
|
// determined, set *PALIGN to the alignment in bytes and return
|
||||||
|
// true. Otherwise, return false.
|
||||||
|
bool
|
||||||
|
backend_type_field_align(Gogo*, unsigned int* palign);
|
||||||
|
|
||||||
|
// Whether the backend size is known.
|
||||||
|
bool
|
||||||
|
is_backend_type_size_known(Gogo*) const;
|
||||||
|
|
||||||
// Get the hash and equality functions for a type.
|
// Get the hash and equality functions for a type.
|
||||||
void
|
void
|
||||||
type_functions(Gogo*, Named_type* name, Function_type* hash_fntype,
|
type_functions(Gogo*, Named_type* name, Function_type* hash_fntype,
|
||||||
|
@ -2013,6 +2034,12 @@ class Struct_type : public Type
|
||||||
traverse_field_types(Traverse* traverse)
|
traverse_field_types(Traverse* traverse)
|
||||||
{ return this->do_traverse(traverse); }
|
{ return this->do_traverse(traverse); }
|
||||||
|
|
||||||
|
// If the offset of field INDEX in the backend implementation can be
|
||||||
|
// determined, set *POFFSET to the offset in bytes and return true.
|
||||||
|
// Otherwise, return false.
|
||||||
|
bool
|
||||||
|
backend_field_offset(Gogo*, unsigned int index, unsigned int* poffset);
|
||||||
|
|
||||||
// Import a struct type.
|
// Import a struct type.
|
||||||
static Struct_type*
|
static Struct_type*
|
||||||
do_import(Import*);
|
do_import(Import*);
|
||||||
|
@ -2507,8 +2534,9 @@ class Named_type : public Type
|
||||||
local_methods_(NULL), all_methods_(NULL),
|
local_methods_(NULL), all_methods_(NULL),
|
||||||
interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
|
interface_method_tables_(NULL), pointer_interface_method_tables_(NULL),
|
||||||
location_(location), named_btype_(NULL), dependencies_(),
|
location_(location), named_btype_(NULL), dependencies_(),
|
||||||
is_visible_(true), is_error_(false), is_converted_(false),
|
is_visible_(true), is_error_(false), is_placeholder_(false),
|
||||||
is_circular_(false), seen_(false), seen_in_get_backend_(false)
|
is_converted_(false), is_circular_(false), seen_(false),
|
||||||
|
seen_in_get_backend_(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Return the associated Named_object. This holds the actual name.
|
// Return the associated Named_object. This holds the actual name.
|
||||||
|
@ -2672,6 +2700,13 @@ class Named_type : public Type
|
||||||
add_dependency(Named_type* nt)
|
add_dependency(Named_type* nt)
|
||||||
{ this->dependencies_.push_back(nt); }
|
{ this->dependencies_.push_back(nt); }
|
||||||
|
|
||||||
|
// Return true if the size and alignment of the backend
|
||||||
|
// representation of this type is known. This is always true after
|
||||||
|
// types have been converted, but may be false beforehand.
|
||||||
|
bool
|
||||||
|
is_named_backend_type_size_known() const
|
||||||
|
{ return this->named_btype_ != NULL && !this->is_placeholder_; }
|
||||||
|
|
||||||
// Export the type.
|
// Export the type.
|
||||||
void
|
void
|
||||||
export_named_type(Export*, const std::string& name) const;
|
export_named_type(Export*, const std::string& name) const;
|
||||||
|
@ -2766,8 +2801,11 @@ class Named_type : public Type
|
||||||
bool is_visible_;
|
bool is_visible_;
|
||||||
// Whether this type is erroneous.
|
// Whether this type is erroneous.
|
||||||
bool is_error_;
|
bool is_error_;
|
||||||
|
// Whether the current value of named_btype_ is a placeholder for
|
||||||
|
// which the final size of the type is not known.
|
||||||
|
bool is_placeholder_;
|
||||||
// Whether this type has been converted to the backend
|
// Whether this type has been converted to the backend
|
||||||
// representation.
|
// representation. Implies that is_placeholder_ is false.
|
||||||
bool is_converted_;
|
bool is_converted_;
|
||||||
// Whether this is a pointer or function type which refers to the
|
// Whether this is a pointer or function type which refers to the
|
||||||
// type itself.
|
// type itself.
|
||||||
|
|
Loading…
Reference in New Issue