mirror of git://gcc.gnu.org/git/gcc.git
runtime: Don't clobber saved context when catching signal.
* go-gcc.cc (Gcc_backend::address_expression): New function. From-SVN: r203579
This commit is contained in:
parent
be66a22638
commit
b93e0cfdd1
|
|
@ -1,3 +1,7 @@
|
||||||
|
2013-10-14 Chris Manghane <cmang@google.com>
|
||||||
|
|
||||||
|
* go-gcc.cc (Gcc_backend::address_expression): New function.
|
||||||
|
|
||||||
2013-10-11 Chris Manghane <cmang@google.com>
|
2013-10-11 Chris Manghane <cmang@google.com>
|
||||||
|
|
||||||
* go-gcc.cc (Gcc_backend::function_code_expression): New
|
* go-gcc.cc (Gcc_backend::function_code_expression): New
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,9 @@ class Gcc_backend : public Backend
|
||||||
Bexpression*
|
Bexpression*
|
||||||
function_code_expression(Bfunction*, Location);
|
function_code_expression(Bfunction*, Location);
|
||||||
|
|
||||||
|
Bexpression*
|
||||||
|
address_expression(Bexpression*, Location);
|
||||||
|
|
||||||
// Statements.
|
// Statements.
|
||||||
|
|
||||||
Bstatement*
|
Bstatement*
|
||||||
|
|
@ -997,6 +1000,19 @@ Gcc_backend::function_code_expression(Bfunction* bfunc, Location location)
|
||||||
return this->make_expression(ret);
|
return this->make_expression(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the address of an expression.
|
||||||
|
|
||||||
|
Bexpression*
|
||||||
|
Gcc_backend::address_expression(Bexpression* bexpr, Location location)
|
||||||
|
{
|
||||||
|
tree expr = bexpr->get_tree();
|
||||||
|
if (expr == error_mark_node)
|
||||||
|
return this->error_expression();
|
||||||
|
|
||||||
|
tree ret = build_fold_addr_expr_loc(location.gcc_location(), expr);
|
||||||
|
return this->make_expression(ret);
|
||||||
|
}
|
||||||
|
|
||||||
// An expression as a statement.
|
// An expression as a statement.
|
||||||
|
|
||||||
Bstatement*
|
Bstatement*
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,10 @@ class Backend
|
||||||
virtual Bexpression*
|
virtual Bexpression*
|
||||||
function_code_expression(Bfunction*, Location) = 0;
|
function_code_expression(Bfunction*, Location) = 0;
|
||||||
|
|
||||||
|
// Create an expression that takes the address of an expression.
|
||||||
|
virtual Bexpression*
|
||||||
|
address_expression(Bexpression*, Location) = 0;
|
||||||
|
|
||||||
// Statements.
|
// Statements.
|
||||||
|
|
||||||
// Create an error statement. This is used for cases which should
|
// Create an error statement. This is used for cases which should
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,11 @@ Expression::convert_type_to_interface(Translate_context* context,
|
||||||
// Otherwise it is the interface method table for RHS_TYPE.
|
// Otherwise it is the interface method table for RHS_TYPE.
|
||||||
tree first_field_value;
|
tree first_field_value;
|
||||||
if (lhs_is_empty)
|
if (lhs_is_empty)
|
||||||
first_field_value = rhs_type->type_descriptor_pointer(gogo, location);
|
{
|
||||||
|
Bexpression* rhs_bexpr =
|
||||||
|
rhs_type->type_descriptor_pointer(gogo, location);
|
||||||
|
first_field_value = expr_to_tree(rhs_bexpr);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Build the interface method table for this interface and this
|
// Build the interface method table for this interface and this
|
||||||
|
|
@ -457,8 +461,9 @@ Expression::convert_interface_to_interface(Translate_context* context,
|
||||||
if (for_type_guard)
|
if (for_type_guard)
|
||||||
{
|
{
|
||||||
// A type assertion fails when converting a nil interface.
|
// A type assertion fails when converting a nil interface.
|
||||||
tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo,
|
Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo,
|
||||||
location);
|
location);
|
||||||
|
tree lhs_type_descriptor = expr_to_tree(lhs_type_expr);
|
||||||
static tree assert_interface_decl;
|
static tree assert_interface_decl;
|
||||||
tree call = Gogo::call_builtin(&assert_interface_decl,
|
tree call = Gogo::call_builtin(&assert_interface_decl,
|
||||||
location,
|
location,
|
||||||
|
|
@ -491,8 +496,10 @@ Expression::convert_interface_to_interface(Translate_context* context,
|
||||||
// type assertion converting nil will always succeed.
|
// type assertion converting nil will always succeed.
|
||||||
go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__methods")
|
go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__methods")
|
||||||
== 0);
|
== 0);
|
||||||
tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo,
|
Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo,
|
||||||
location);
|
location);
|
||||||
|
tree lhs_type_descriptor = expr_to_tree(lhs_type_expr);
|
||||||
|
|
||||||
static tree convert_interface_decl;
|
static tree convert_interface_decl;
|
||||||
tree call = Gogo::call_builtin(&convert_interface_decl,
|
tree call = Gogo::call_builtin(&convert_interface_decl,
|
||||||
location,
|
location,
|
||||||
|
|
@ -546,8 +553,9 @@ Expression::convert_interface_to_type(Translate_context* context,
|
||||||
// Call a function to check that the type is valid. The function
|
// Call a function to check that the type is valid. The function
|
||||||
// will panic with an appropriate runtime type error if the type is
|
// will panic with an appropriate runtime type error if the type is
|
||||||
// not valid.
|
// not valid.
|
||||||
|
Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo,
|
||||||
tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo, location);
|
location);
|
||||||
|
tree lhs_type_descriptor = expr_to_tree(lhs_type_expr);
|
||||||
|
|
||||||
if (!DECL_P(rhs_tree))
|
if (!DECL_P(rhs_tree))
|
||||||
rhs_tree = save_expr(rhs_tree);
|
rhs_tree = save_expr(rhs_tree);
|
||||||
|
|
@ -556,8 +564,9 @@ Expression::convert_interface_to_type(Translate_context* context,
|
||||||
Expression::get_interface_type_descriptor(context, rhs_type, rhs_tree,
|
Expression::get_interface_type_descriptor(context, rhs_type, rhs_tree,
|
||||||
location);
|
location);
|
||||||
|
|
||||||
tree rhs_inter_descriptor = rhs_type->type_descriptor_pointer(gogo,
|
Bexpression* rhs_inter_expr = rhs_type->type_descriptor_pointer(gogo,
|
||||||
location);
|
location);
|
||||||
|
tree rhs_inter_descriptor = expr_to_tree(rhs_inter_expr);
|
||||||
|
|
||||||
static tree check_interface_type_decl;
|
static tree check_interface_type_decl;
|
||||||
tree call = Gogo::call_builtin(&check_interface_type_decl,
|
tree call = Gogo::call_builtin(&check_interface_type_decl,
|
||||||
|
|
@ -6500,8 +6509,9 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||||
}
|
}
|
||||||
arg = fold_convert_loc(location.gcc_location(), ptr_type_node, arg);
|
arg = fold_convert_loc(location.gcc_location(), ptr_type_node, arg);
|
||||||
|
|
||||||
tree descriptor = right_type->type_descriptor_pointer(context->gogo(),
|
Bexpression* descriptor_bexpr =
|
||||||
location);
|
right_type->type_descriptor_pointer(context->gogo(), location);
|
||||||
|
tree descriptor = expr_to_tree(descriptor_bexpr);
|
||||||
|
|
||||||
if (left_type->interface_type()->is_empty())
|
if (left_type->interface_type()->is_empty())
|
||||||
{
|
{
|
||||||
|
|
@ -13256,7 +13266,8 @@ Map_construction_expression::do_get_tree(Translate_context* context)
|
||||||
valaddr = build_fold_addr_expr(tmp);
|
valaddr = build_fold_addr_expr(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree descriptor = mt->map_descriptor_pointer(gogo, loc);
|
Bexpression* bdescriptor = mt->map_descriptor_pointer(gogo, loc);
|
||||||
|
tree descriptor = expr_to_tree(bdescriptor);
|
||||||
|
|
||||||
tree type_tree = type_to_tree(this->type_->get_backend(gogo));
|
tree type_tree = type_to_tree(this->type_->get_backend(gogo));
|
||||||
if (type_tree == error_mark_node)
|
if (type_tree == error_mark_node)
|
||||||
|
|
@ -14312,8 +14323,9 @@ class Type_descriptor_expression : public Expression
|
||||||
tree
|
tree
|
||||||
do_get_tree(Translate_context* context)
|
do_get_tree(Translate_context* context)
|
||||||
{
|
{
|
||||||
return this->type_->type_descriptor_pointer(context->gogo(),
|
Bexpression* ret = this->type_->type_descriptor_pointer(context->gogo(),
|
||||||
this->location());
|
this->location());
|
||||||
|
return expr_to_tree(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -14568,8 +14580,9 @@ class Map_descriptor_expression : public Expression
|
||||||
tree
|
tree
|
||||||
do_get_tree(Translate_context* context)
|
do_get_tree(Translate_context* context)
|
||||||
{
|
{
|
||||||
return this->type_->map_descriptor_pointer(context->gogo(),
|
Bexpression* ret = this->type_->map_descriptor_pointer(context->gogo(),
|
||||||
this->location());
|
this->location());
|
||||||
|
return expr_to_tree(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -2107,8 +2107,10 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
|
||||||
td_type = type;
|
td_type = type;
|
||||||
else
|
else
|
||||||
td_type = Type::make_pointer_type(type);
|
td_type = Type::make_pointer_type(type);
|
||||||
tree tdp = td_type->type_descriptor_pointer(this,
|
|
||||||
Linemap::predeclared_location());
|
Location loc = Linemap::predeclared_location();
|
||||||
|
Bexpression* tdp_bexpr = td_type->type_descriptor_pointer(this, loc);
|
||||||
|
tree tdp = expr_to_tree(tdp_bexpr);
|
||||||
elt->value = fold_convert(const_ptr_type_node, tdp);
|
elt->value = fold_convert(const_ptr_type_node, tdp);
|
||||||
|
|
||||||
Named_type* nt = type->named_type();
|
Named_type* nt = type->named_type();
|
||||||
|
|
|
||||||
|
|
@ -1204,7 +1204,7 @@ Type::finish_backend(Gogo* gogo, Btype *placeholder)
|
||||||
|
|
||||||
// Return a pointer to the type descriptor for this type.
|
// Return a pointer to the type descriptor for this type.
|
||||||
|
|
||||||
tree
|
Bexpression*
|
||||||
Type::type_descriptor_pointer(Gogo* gogo, Location location)
|
Type::type_descriptor_pointer(Gogo* gogo, Location location)
|
||||||
{
|
{
|
||||||
Type* t = this->forwarded();
|
Type* t = this->forwarded();
|
||||||
|
|
@ -1215,10 +1215,9 @@ Type::type_descriptor_pointer(Gogo* gogo, Location location)
|
||||||
t->make_type_descriptor_var(gogo);
|
t->make_type_descriptor_var(gogo);
|
||||||
go_assert(t->type_descriptor_var_ != NULL);
|
go_assert(t->type_descriptor_var_ != NULL);
|
||||||
}
|
}
|
||||||
tree var_tree = var_to_tree(t->type_descriptor_var_);
|
Bexpression* var_expr =
|
||||||
if (var_tree == error_mark_node)
|
gogo->backend()->var_expression(t->type_descriptor_var_, location);
|
||||||
return error_mark_node;
|
return gogo->backend()->address_expression(var_expr, location);
|
||||||
return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A mapping from unnamed types to type descriptor variables.
|
// A mapping from unnamed types to type descriptor variables.
|
||||||
|
|
@ -6250,14 +6249,12 @@ Map_type::Map_descriptors Map_type::map_descriptors;
|
||||||
|
|
||||||
// Build a map descriptor for this type. Return a pointer to it.
|
// Build a map descriptor for this type. Return a pointer to it.
|
||||||
|
|
||||||
tree
|
Bexpression*
|
||||||
Map_type::map_descriptor_pointer(Gogo* gogo, Location location)
|
Map_type::map_descriptor_pointer(Gogo* gogo, Location location)
|
||||||
{
|
{
|
||||||
Bvariable* bvar = this->map_descriptor(gogo);
|
Bvariable* bvar = this->map_descriptor(gogo);
|
||||||
tree var_tree = var_to_tree(bvar);
|
Bexpression* var_expr = gogo->backend()->var_expression(bvar, location);
|
||||||
if (var_tree == error_mark_node)
|
return gogo->backend()->address_expression(var_expr, location);
|
||||||
return error_mark_node;
|
|
||||||
return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a map descriptor for this type.
|
// Build a map descriptor for this type.
|
||||||
|
|
|
||||||
|
|
@ -901,7 +901,7 @@ class Type
|
||||||
// Build a type descriptor entry for this type. Return a pointer to
|
// Build a type descriptor entry for this type. Return a pointer to
|
||||||
// it. The location is the location which causes us to need the
|
// it. The location is the location which causes us to need the
|
||||||
// entry.
|
// entry.
|
||||||
tree
|
Bexpression*
|
||||||
type_descriptor_pointer(Gogo* gogo, Location);
|
type_descriptor_pointer(Gogo* gogo, Location);
|
||||||
|
|
||||||
// Return the type reflection string for this type.
|
// Return the type reflection string for this type.
|
||||||
|
|
@ -2401,7 +2401,7 @@ class Map_type : public Type
|
||||||
// Build a map descriptor for this type. Return a pointer to it.
|
// Build a map descriptor for this type. Return a pointer to it.
|
||||||
// The location is the location which causes us to need the
|
// The location is the location which causes us to need the
|
||||||
// descriptor.
|
// descriptor.
|
||||||
tree
|
Bexpression*
|
||||||
map_descriptor_pointer(Gogo* gogo, Location);
|
map_descriptor_pointer(Gogo* gogo, Location);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue