diff options
author | Philip Herron <philip.herron@embecosm.com> | 2020-12-01 16:18:25 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2020-12-01 17:50:50 +0000 |
commit | 8993741f97ca3426e22a740070b9a413dcb2fe04 (patch) | |
tree | 5d7fb01e8c3a3bbb350653fb3f71e7e1584012c2 /gcc | |
parent | 3f491614f6e4e2dea93b534c063c142e8de55bb3 (diff) | |
download | gcc-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.cc | 10 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 7 | ||||
-rw-r--r-- | gcc/rust/ast/rust-type.h | 4 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 118 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/arrays1.rs | 7 |
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]; +} |