aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-06-10 21:34:12 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-06-10 21:34:12 +0000
commite898243c23c82247ec01b32f551402ca52f32927 (patch)
treeb0d9c35dc562318a0568ad5a47888711864bc4c1 /gcc
parent35c19de69645b18eeef7dbecfcd98b19f9948c84 (diff)
downloadgcc-e898243c23c82247ec01b32f551402ca52f32927.zip
gcc-e898243c23c82247ec01b32f551402ca52f32927.tar.gz
gcc-e898243c23c82247ec01b32f551402ca52f32927.tar.bz2
compiler: support inlining functions that use index expressions
Also move the determine_types pass on an inlined function body to one place, rather than doing it ad hoc as needed. This adds 79 new inlinable functions in the standard library, such as bytes.HasPrefix and bytes.LastIndexByte. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/181261 From-SVN: r272133
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc105
-rw-r--r--gcc/go/gofrontend/expressions.h21
-rw-r--r--gcc/go/gofrontend/gogo.cc1
-rw-r--r--gcc/go/gofrontend/import.cc2
-rw-r--r--gcc/go/gofrontend/statements.cc9
6 files changed, 129 insertions, 11 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 84c00ae..d89e8e3 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-764fe6702f2bb8650622d4102de31058e484ecb5
+b1ae35965cadac235d7d218e689944286cccdd90
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index d82eebd..740daec 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -7110,6 +7110,12 @@ Binary_expression::do_import(Import_expression* imp, Location loc)
op = OPERATOR_BITCLEAR;
imp->advance(4);
}
+ else if (imp->match_c_string(")"))
+ {
+ // Not a binary operator after all.
+ imp->advance(1);
+ return left;
+ }
else
{
go_error_at(imp->location(), "unrecognized binary operator");
@@ -12808,6 +12814,38 @@ Array_index_expression::do_get_backend(Translate_context* context)
return ret;
}
+// Export an array index expression.
+
+void
+Array_index_expression::do_export(Export_function_body* efb) const
+{
+ efb->write_c_string("(");
+ this->array_->export_expression(efb);
+ efb->write_c_string(")[");
+
+ Type* old_context = efb->type_context();
+ efb->set_type_context(Type::lookup_integer_type("int"));
+
+ this->start_->export_expression(efb);
+ if (this->end_ == NULL)
+ go_assert(this->cap_ == NULL);
+ else
+ {
+ efb->write_c_string(":");
+ if (!this->end_->is_nil_expression())
+ this->end_->export_expression(efb);
+ if (this->cap_ != NULL)
+ {
+ efb->write_c_string(":");
+ this->cap_->export_expression(efb);
+ }
+ }
+
+ efb->set_type_context(old_context);
+
+ efb->write_c_string("]");
+}
+
// Dump ast representation for an array index expression.
void
@@ -13068,6 +13106,31 @@ String_index_expression::do_get_backend(Translate_context* context)
crash, bstrslice, loc);
}
+// Export a string index expression.
+
+void
+String_index_expression::do_export(Export_function_body* efb) const
+{
+ efb->write_c_string("(");
+ this->string_->export_expression(efb);
+ efb->write_c_string(")[");
+
+ Type* old_context = efb->type_context();
+ efb->set_type_context(Type::lookup_integer_type("int"));
+
+ this->start_->export_expression(efb);
+ if (this->end_ != NULL)
+ {
+ efb->write_c_string(":");
+ if (!this->end_->is_nil_expression())
+ this->end_->export_expression(efb);
+ }
+
+ efb->set_type_context(old_context);
+
+ efb->write_c_string("]");
+}
+
// Dump ast representation for a string index expression.
void
@@ -13338,6 +13401,25 @@ Map_index_expression::get_value_pointer(Gogo* gogo)
return this->value_pointer_;
}
+// Export a map index expression.
+
+void
+Map_index_expression::do_export(Export_function_body* efb) const
+{
+ efb->write_c_string("(");
+ this->map_->export_expression(efb);
+ efb->write_c_string(")[");
+
+ Type* old_context = efb->type_context();
+ efb->set_type_context(this->get_map_type()->key_type());
+
+ this->index_->export_expression(efb);
+
+ efb->set_type_context(old_context);
+
+ efb->write_c_string("]");
+}
+
// Dump ast representation for a map index expression
void
@@ -17974,6 +18056,29 @@ Expression::import_expression(Import_expression* imp, Location loc)
imp->require_c_string(")");
expr = Expression::make_call(expr, args, is_varargs, loc);
}
+ else if (imp->match_c_string("["))
+ {
+ imp->advance(1);
+ Expression* start = Expression::import_expression(imp, loc);
+ Expression* end = NULL;
+ Expression* cap = NULL;
+ if (imp->match_c_string(":"))
+ {
+ imp->advance(1);
+ int c = imp->peek_char();
+ if (c == ':' || c == ']')
+ end = Expression::make_nil(loc);
+ else
+ end = Expression::import_expression(imp, loc);
+ if (imp->match_c_string(":"))
+ {
+ imp->advance(1);
+ cap = Expression::import_expression(imp, loc);
+ }
+ }
+ imp->require_c_string("]");
+ expr = Expression::make_index(expr, start, end, cap, loc);
+ }
else
break;
}
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 22dd2fc..1595eb1 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -3089,6 +3089,13 @@ class Array_index_expression : public Expression
Bexpression*
do_get_backend(Translate_context*);
+ int
+ do_inlining_cost() const
+ { return this->end_ != NULL ? 2 : 1; }
+
+ void
+ do_export(Export_function_body*) const;
+
void
do_dump_expression(Ast_dump_context*) const;
@@ -3161,6 +3168,13 @@ class String_index_expression : public Expression
Bexpression*
do_get_backend(Translate_context*);
+ int
+ do_inlining_cost() const
+ { return this->end_ != NULL ? 2 : 1; }
+
+ void
+ do_export(Export_function_body*) const;
+
void
do_dump_expression(Ast_dump_context*) const;
@@ -3247,6 +3261,13 @@ class Map_index_expression : public Expression
Bexpression*
do_get_backend(Translate_context*);
+ int
+ do_inlining_cost() const
+ { return 5; }
+
+ void
+ do_export(Export_function_body*) const;
+
void
do_dump_expression(Ast_dump_context*) const;
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 62d6870..42a7674 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -7282,6 +7282,7 @@ Function_declaration::import_function_body(Gogo* gogo, Named_object* no)
return;
gogo->lower_block(no, outer);
+ outer->determine_types();
gogo->add_imported_inline_function(no);
}
diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc
index 02c1c48..2d76f75 100644
--- a/gcc/go/gofrontend/import.cc
+++ b/gcc/go/gofrontend/import.cc
@@ -1238,7 +1238,7 @@ Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
// characters that stop an identifier, without worrying about
// characters that are permitted in an identifier. That lets us skip
// UTF-8 parsing.
-static const char * const identifier_stop = " \n;,()[]";
+static const char * const identifier_stop = " \n;:,()[]";
// Read an identifier from the stream.
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 9ab1172..7f424fd 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -465,8 +465,6 @@ Variable_declaration_statement::do_import(Import_function_body* ifb,
{
ifb->advance(3);
init = Expression::import_expression(ifb, loc);
- Type_context context(type, false);
- init->determine_type(&context);
}
Variable* var = new Variable(type, init, false, false, false, loc);
var->set_is_used();
@@ -753,11 +751,6 @@ Temporary_statement::do_import(Import_function_body* ifb, Location loc)
{
ifb->advance(3);
init = Expression::import_expression(ifb, loc);
- if (type != NULL)
- {
- Type_context context(type, false);
- init->determine_type(&context);
- }
}
if (type == NULL && init == NULL)
{
@@ -3730,8 +3723,6 @@ If_statement::do_import(Import_function_body* ifb, Location loc)
ifb->require_c_string("if ");
Expression* cond = Expression::import_expression(ifb, loc);
- Type_context context(Type::lookup_bool_type(), false);
- cond->determine_type(&context);
ifb->require_c_string(" ");
if (!ifb->match_c_string("{"))