aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-02-04 19:59:59 -0800
committerIan Lance Taylor <iant@golang.org>2022-02-08 20:08:09 -0800
commit3ab49b1c822cf8c5748fa4de0ac970c948de6f8a (patch)
tree0696141de5cddb0755c91ff21befd313bf0b9e29 /gcc/go/gofrontend/expressions.cc
parente52a683170877d140eebc9782731eaf11897db71 (diff)
downloadgcc-3ab49b1c822cf8c5748fa4de0ac970c948de6f8a.zip
gcc-3ab49b1c822cf8c5748fa4de0ac970c948de6f8a.tar.gz
gcc-3ab49b1c822cf8c5748fa4de0ac970c948de6f8a.tar.bz2
compiler, internal/abi: implement FuncPCABI0, FuncPCABIInternal
The Go 1.18 standard library uses an internal/abi package with two functions that are implemented in the compiler. This patch implements them in the gofrontend, to support the upcoming update to 1.18. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/383514
Diffstat (limited to 'gcc/go/gofrontend/expressions.cc')
-rw-r--r--gcc/go/gofrontend/expressions.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 7970282..1e6890a 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -12177,6 +12177,50 @@ Call_expression::intrinsify(Gogo* gogo,
return Runtime::make_call(code, loc, 3, a1, a2, a3);
}
}
+ else if (package == "internal/abi")
+ {
+ if ((name == "FuncPCABI0" || name == "FuncPCABIInternal")
+ && this->args_ != NULL
+ && this->args_->size() == 1)
+ {
+ // We expect to see a conversion from the expression to "any".
+ Expression* expr = this->args_->front();
+ Type_conversion_expression* tce = expr->conversion_expression();
+ if (tce != NULL)
+ expr = tce->expr();
+ Func_expression* fe = expr->func_expression();
+ Interface_field_reference_expression* interface_method =
+ expr->interface_field_reference_expression();
+ if (fe != NULL)
+ {
+ Named_object* no = fe->named_object();
+ Expression* ref = Expression::make_func_code_reference(no, loc);
+ Type* uintptr_type = Type::lookup_integer_type("uintptr");
+ return Expression::make_cast(uintptr_type, ref, loc);
+ }
+ else if (interface_method != NULL)
+ return interface_method->get_function();
+ else
+ {
+ expr = this->args_->front();
+ go_assert(expr->type()->interface_type() != NULL
+ && expr->type()->interface_type()->is_empty());
+ expr = Expression::make_interface_info(expr,
+ INTERFACE_INFO_OBJECT,
+ loc);
+ // Trust that this is a function type, which means that
+ // it is a direct iface type and we can use EXPR
+ // directly. The backend representation of this
+ // function is a pointer to a struct whose first field
+ // is the actual function to call.
+ Type* pvoid = Type::make_pointer_type(Type::make_void_type());
+ Type* pfntype = Type::make_pointer_type(pvoid);
+ Expression* ref = make_unsafe_cast(pfntype, expr, loc);
+ return Expression::make_dereference(ref, NIL_CHECK_NOT_NEEDED,
+ loc);
+ }
+ }
+ }
return NULL;
}