aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2020-12-01 16:18:25 +0000
committerPhilip Herron <herron.philip@googlemail.com>2020-12-01 17:50:50 +0000
commit8993741f97ca3426e22a740070b9a413dcb2fe04 (patch)
tree5d7fb01e8c3a3bbb350653fb3f71e7e1584012c2 /gcc
parent3f491614f6e4e2dea93b534c063c142e8de55bb3 (diff)
downloadgcc-8993741f97ca3426e22a740070b9a413dcb2fe04.zip
gcc-8993741f97ca3426e22a740070b9a413dcb2fe04.tar.gz
gcc-8993741f97ca3426e22a740070b9a413dcb2fe04.tar.bz2
GIMPLE coversions for ArrayIndexExpr and Arrays with values
This compiles the ArrayIndexExpressions and Arrays such as: let x = [1,2,3]; let a = x[0]; Addresses: #55
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/analysis/rust-type-resolution.cc10
-rw-r--r--gcc/rust/ast/rust-expr.h7
-rw-r--r--gcc/rust/ast/rust-type.h4
-rw-r--r--gcc/rust/backend/rust-compile.cc118
-rw-r--r--gcc/rust/backend/rust-compile.h3
-rw-r--r--gcc/testsuite/rust.test/compilable/arrays1.rs7
6 files changed, 143 insertions, 6 deletions
diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc
index 5500faf..541acd0 100644
--- a/gcc/rust/analysis/rust-type-resolution.cc
+++ b/gcc/rust/analysis/rust-type-resolution.cc
@@ -466,7 +466,17 @@ void
TypeResolution::visit (AST::ArrayExpr &expr)
{
auto elements = expr.get_internal_elements ();
+
+ auto before = typeBuffer.size ();
elements->accept_vis (*this);
+ if (typeBuffer.size () <= before)
+ {
+ rust_error_at (expr.get_locus_slow (),
+ "unable to determine type for ArrayExpr");
+ return;
+ }
+
+ expr.set_inferred_type (typeBuffer.back ());
}
void
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index d3e7cbd..4971041 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -1000,6 +1000,10 @@ class ArrayExpr : public ExprWithoutBlock
Location locus;
+ // this is a reference to what the inferred type is based on
+ // this init expression
+ Type *inferredType;
+
public:
std::string as_string () const override;
@@ -1050,6 +1054,9 @@ public:
ArrayElems *get_internal_elements () { return internal_elements.get (); };
+ Type *get_inferred_type () { return inferredType; }
+ void set_inferred_type (Type *type) { inferredType = type; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 301b664..089aaeb 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -576,6 +576,10 @@ public:
Type *get_element_type () { return elem_type.get (); }
+ Expr *get_size_expr () { return size.get (); }
+
+ Location &get_locus () { return locus; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 0b632b7..2dbce16 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -503,19 +503,102 @@ Compilation::visit (AST::CompoundAssignmentExpr &expr)
void
Compilation::visit (AST::GroupedExpr &expr)
{}
-// void Compilation::visit(ArrayElems& elems) {}
+
void
Compilation::visit (AST::ArrayElemsValues &elems)
-{}
+{
+ std::vector< ::Bexpression *> elements;
+
+ bool failed = false;
+ elems.iterate ([&] (AST::Expr *expr) mutable -> bool {
+ Bexpression *value = nullptr;
+ VISIT_POP (expr.get_locus_slow (), expr, value, exprs);
+ if (value == nullptr)
+ {
+ rust_fatal_error (expr->get_locus_slow (),
+ "failed to compile value to array initialiser");
+ return false;
+ }
+ elements.push_back (value);
+ return true;
+ });
+
+ // nothing to do when its failed
+ if (failed)
+ return;
+
+ arrayConsStack.push_back (elements);
+}
+
void
Compilation::visit (AST::ArrayElemsCopied &elems)
{}
+
void
Compilation::visit (AST::ArrayExpr &expr)
-{}
+{
+ translatedType = nullptr;
+ expr.get_inferred_type ()->accept_vis (*this);
+ if (translatedType == nullptr)
+ {
+ rust_error_at (expr.get_locus_slow (),
+ "failed to compile array type for ArrayExpr");
+ return;
+ }
+
+ ::Btype *compiledType = translatedType;
+ translatedType = nullptr;
+
+ auto before = arrayConsStack.size ();
+ expr.get_internal_elements ()->accept_vis (*this);
+ if (arrayConsStack.size () <= before)
+ {
+ rust_error_at (expr.get_locus_slow (),
+ "failed to compile the array constructor");
+ return;
+ }
+ std::vector< ::Bexpression *> initializer = arrayConsStack.back ();
+ arrayConsStack.pop_back ();
+
+ std::vector<unsigned long> indexes;
+ for (unsigned long i = 0; i < initializer.size (); ++i)
+ indexes.push_back (i);
+
+ Bexpression *cons
+ = backend->array_constructor_expression (compiledType, indexes, initializer,
+ expr.get_locus_slow ());
+ exprs.push_back (cons);
+}
+
void
Compilation::visit (AST::ArrayIndexExpr &expr)
-{}
+{
+ Bexpression *arrayExpr = nullptr;
+ VISIT_POP (expr.get_array_expr ()->get_locus_slow (), expr.get_array_expr (),
+ arrayExpr, exprs);
+ if (arrayExpr == nullptr)
+ {
+ rust_error_at (expr.get_locus_slow (),
+ "failed to compile value to array expression reference");
+ return;
+ }
+
+ Bexpression *indexExpr = nullptr;
+ VISIT_POP (expr.get_index_expr ()->get_locus_slow (), expr.get_index_expr (),
+ indexExpr, exprs);
+ if (indexExpr == nullptr)
+ {
+ rust_error_at (expr.get_locus_slow (),
+ "failed to compile value to array index expression");
+ return;
+ }
+
+ Bexpression *indexExpression
+ = backend->array_index_expression (arrayExpr, indexExpr,
+ expr.get_locus_slow ());
+ exprs.push_back (indexExpression);
+}
+
void
Compilation::visit (AST::TupleExpr &expr)
{}
@@ -1376,9 +1459,34 @@ Compilation::visit (AST::RawPointerType &type)
void
Compilation::visit (AST::ReferenceType &type)
{}
+
void
Compilation::visit (AST::ArrayType &type)
-{}
+{
+ Btype *elementType;
+ translatedType = nullptr;
+ type.get_element_type ()->accept_vis (*this);
+ if (translatedType == nullptr)
+ {
+ rust_error_at (type.get_locus (),
+ "Failed to compile element type for array");
+ return;
+ }
+ elementType = translatedType;
+
+ Bexpression *length = nullptr;
+ VISIT_POP (type.get_size_expr ()->get_locus_slow (), type.get_size_expr (),
+ length, exprs);
+ if (length == nullptr)
+ {
+ rust_error_at (type.get_size_expr ()->get_locus_slow (),
+ "failed to size for array type");
+ return;
+ }
+
+ translatedType = backend->array_type (elementType, length);
+}
+
void
Compilation::visit (AST::SliceType &type)
{}
diff --git a/gcc/rust/backend/rust-compile.h b/gcc/rust/backend/rust-compile.h
index ba03483..88c8318 100644
--- a/gcc/rust/backend/rust-compile.h
+++ b/gcc/rust/backend/rust-compile.h
@@ -243,7 +243,8 @@ private:
std::vector< ::Bexpression *> exprs;
std::vector< ::Bstatement *> stmts;
std::vector< ::Bvariable *> varBuffer;
- std::vector<AST::StructStruct*> structBuffer;
+ std::vector<AST::StructStruct *> structBuffer;
+ std::vector<std::vector< ::Bexpression *> > arrayConsStack;
// careful these are the vectors we pass into the GCC middle-end
std::vector< ::Btype *> type_decls;
diff --git a/gcc/testsuite/rust.test/compilable/arrays1.rs b/gcc/testsuite/rust.test/compilable/arrays1.rs
new file mode 100644
index 0000000..f7e66af
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/arrays1.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let xs: [i32; 5] = [1, 2, 3, 4, 5];
+ let xy = [6, 7, 8];
+
+ let a = xs[0];
+ let b = xy[2];
+}