diff options
author | Chris Manghane <cmang@google.com> | 2013-10-14 22:52:55 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-10-14 22:52:55 +0000 |
commit | b93e0cfdd185098c4b5bb059afb92e0cbe8f235c (patch) | |
tree | 41f23c7bb9722e4a5193e9ae568a92f62eb6da05 /gcc/go | |
parent | be66a22638ada47b4fdf0b42be1d44e6cd4fe104 (diff) | |
download | gcc-b93e0cfdd185098c4b5bb059afb92e0cbe8f235c.zip gcc-b93e0cfdd185098c4b5bb059afb92e0cbe8f235c.tar.gz gcc-b93e0cfdd185098c4b5bb059afb92e0cbe8f235c.tar.bz2 |
runtime: Don't clobber saved context when catching signal.
* go-gcc.cc (Gcc_backend::address_expression): New function.
From-SVN: r203579
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 16 | ||||
-rw-r--r-- | gcc/go/gofrontend/backend.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 45 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo-tree.cc | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 17 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 4 |
7 files changed, 66 insertions, 30 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 4d0dd11..70f3496 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -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> * go-gcc.cc (Gcc_backend::function_code_expression): New diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 81e9ad1..5ff529f 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -235,6 +235,9 @@ class Gcc_backend : public Backend Bexpression* function_code_expression(Bfunction*, Location); + Bexpression* + address_expression(Bexpression*, Location); + // Statements. Bstatement* @@ -997,6 +1000,19 @@ Gcc_backend::function_code_expression(Bfunction* bfunc, Location location) 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. Bstatement* diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h index ca997f0..6f2c321 100644 --- a/gcc/go/gofrontend/backend.h +++ b/gcc/go/gofrontend/backend.h @@ -271,6 +271,10 @@ class Backend virtual Bexpression* function_code_expression(Bfunction*, Location) = 0; + // Create an expression that takes the address of an expression. + virtual Bexpression* + address_expression(Bexpression*, Location) = 0; + // Statements. // Create an error statement. This is used for cases which should diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 6ba351e..f46c37f 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -286,7 +286,11 @@ Expression::convert_type_to_interface(Translate_context* context, // Otherwise it is the interface method table for RHS_TYPE. tree first_field_value; 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 { // 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) { // A type assertion fails when converting a nil interface. - tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo, - location); + Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo, + location); + tree lhs_type_descriptor = expr_to_tree(lhs_type_expr); static tree assert_interface_decl; tree call = Gogo::call_builtin(&assert_interface_decl, location, @@ -491,8 +496,10 @@ Expression::convert_interface_to_interface(Translate_context* context, // type assertion converting nil will always succeed. go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__methods") == 0); - tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo, - location); + Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo, + location); + tree lhs_type_descriptor = expr_to_tree(lhs_type_expr); + static tree convert_interface_decl; tree call = Gogo::call_builtin(&convert_interface_decl, 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 // will panic with an appropriate runtime type error if the type is // not valid. - - tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo, location); + Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo, + location); + tree lhs_type_descriptor = expr_to_tree(lhs_type_expr); if (!DECL_P(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, location); - tree rhs_inter_descriptor = rhs_type->type_descriptor_pointer(gogo, - location); + Bexpression* rhs_inter_expr = rhs_type->type_descriptor_pointer(gogo, + location); + tree rhs_inter_descriptor = expr_to_tree(rhs_inter_expr); static tree 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); - tree descriptor = right_type->type_descriptor_pointer(context->gogo(), - location); + Bexpression* descriptor_bexpr = + right_type->type_descriptor_pointer(context->gogo(), location); + tree descriptor = expr_to_tree(descriptor_bexpr); 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); } - 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)); if (type_tree == error_mark_node) @@ -14312,8 +14323,9 @@ class Type_descriptor_expression : public Expression tree do_get_tree(Translate_context* context) { - return this->type_->type_descriptor_pointer(context->gogo(), - this->location()); + Bexpression* ret = this->type_->type_descriptor_pointer(context->gogo(), + this->location()); + return expr_to_tree(ret); } void @@ -14568,8 +14580,9 @@ class Map_descriptor_expression : public Expression tree do_get_tree(Translate_context* context) { - return this->type_->map_descriptor_pointer(context->gogo(), - this->location()); + Bexpression* ret = this->type_->map_descriptor_pointer(context->gogo(), + this->location()); + return expr_to_tree(ret); } void diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index ca80869..3793b83 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -2107,8 +2107,10 @@ Gogo::interface_method_table_for_type(const Interface_type* interface, td_type = type; else 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); Named_type* nt = type->named_type(); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 40b62f4..7d808ca 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -1204,7 +1204,7 @@ Type::finish_backend(Gogo* gogo, Btype *placeholder) // Return a pointer to the type descriptor for this type. -tree +Bexpression* Type::type_descriptor_pointer(Gogo* gogo, Location location) { Type* t = this->forwarded(); @@ -1215,10 +1215,9 @@ Type::type_descriptor_pointer(Gogo* gogo, Location location) t->make_type_descriptor_var(gogo); go_assert(t->type_descriptor_var_ != NULL); } - tree var_tree = var_to_tree(t->type_descriptor_var_); - if (var_tree == error_mark_node) - return error_mark_node; - return build_fold_addr_expr_loc(location.gcc_location(), var_tree); + Bexpression* var_expr = + gogo->backend()->var_expression(t->type_descriptor_var_, location); + return gogo->backend()->address_expression(var_expr, location); } // 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. -tree +Bexpression* Map_type::map_descriptor_pointer(Gogo* gogo, Location location) { Bvariable* bvar = this->map_descriptor(gogo); - tree var_tree = var_to_tree(bvar); - if (var_tree == error_mark_node) - return error_mark_node; - return build_fold_addr_expr_loc(location.gcc_location(), var_tree); + Bexpression* var_expr = gogo->backend()->var_expression(bvar, location); + return gogo->backend()->address_expression(var_expr, location); } // Build a map descriptor for this type. diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 928c593..131c9de 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -901,7 +901,7 @@ class Type // Build a type descriptor entry for this type. Return a pointer to // it. The location is the location which causes us to need the // entry. - tree + Bexpression* type_descriptor_pointer(Gogo* gogo, Location); // 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. // The location is the location which causes us to need the // descriptor. - tree + Bexpression* map_descriptor_pointer(Gogo* gogo, Location); protected: |