diff options
author | Philip Herron <herron.philip@googlemail.com> | 2020-07-21 21:40:22 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-28 21:13:19 +0000 |
commit | ffb8dbc16a003a0f00662ded052de3a3b7dcb964 (patch) | |
tree | 48597394d7b0f2bc76dd52696081bf62aed9cf58 /gcc | |
parent | aac6645c2204837ec30ff720e6087e6cf588cec7 (diff) | |
download | gcc-ffb8dbc16a003a0f00662ded052de3a3b7dcb964.zip gcc-ffb8dbc16a003a0f00662ded052de3a3b7dcb964.tar.gz gcc-ffb8dbc16a003a0f00662ded052de3a3b7dcb964.tar.bz2 |
Compile AST::StructExprStructFields into a constructor tree.
This still requires more type resolution work to ensure field ordering
on the initilizer and defaults if required.
struct Foo struct_test;
try
{
struct_test.one = 1;
struct_test.two = 2;
}
finally
{
struct_test = {CLOBBER};
}
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/cscope.h | 13 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 110 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.h | 2 |
3 files changed, 113 insertions, 12 deletions
diff --git a/gcc/rust/backend/cscope.h b/gcc/rust/backend/cscope.h index d759ffc..ee4f955 100644 --- a/gcc/rust/backend/cscope.h +++ b/gcc/rust/backend/cscope.h @@ -19,6 +19,7 @@ public: fndecls.Push (); vars.Push (); types.Push (); + structDecls.Push (); } void Pop () @@ -26,6 +27,7 @@ public: fndecls.Pop (); vars.Pop (); types.Pop (); + structDecls.Pop (); } void PushCurrentFunction (std::string name, Bfunction *fn, Btype *retType, @@ -85,6 +87,16 @@ public: void AddStatement (Bstatement *stmt) { context.back ().push_back (stmt); } + void InsertStructDecl (std::string name, AST::StructStruct *decl) + { + structDecls.Insert (name, decl); + } + + bool LookupStructDecl (std::string name, AST::StructStruct **decl) + { + return structDecls.Lookup (name, decl); + } + void InsertFunction (std::string name, Bfunction *fn, Btype *retType) { fndecls.Insert (name, fn); @@ -123,6 +135,7 @@ private: Analysis::Scope<Bfunction *> fndecls; Analysis::Scope<Bvariable *> vars; Analysis::Scope<Btype *> types; + Analysis::Scope<AST::StructStruct *> structDecls; }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 3435f8f..2b9b5bb 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -529,15 +529,95 @@ Compilation::visit (AST::StructExprStruct &expr) void Compilation::visit (AST::StructExprFieldIdentifier &field) {} + void Compilation::visit (AST::StructExprFieldIdentifierValue &field) -{} +{ + AST::StructStruct *decl = structBuffer.back (); + size_t index = 0; + bool found = false; + for (auto &df : decl->fields) + { + if (field.field_name.compare (df.field_name) == 0) + { + found = true; + break; + } + } + if (!found) + { + rust_fatal_error (field.value->get_locus_slow (), + "failed to lookup field index"); + return; + } + + Bexpression *value = NULL; + VISIT_POP (field.value->get_locus_slow (), field.value.get (), value, exprs); + if (value == NULL) + { + rust_fatal_error (field.value->get_locus_slow (), + "failed to compile value to struct"); + return; + } + exprs.push_back (value); +} + void Compilation::visit (AST::StructExprFieldIndexValue &field) -{} +{ + Bexpression *value = NULL; + VISIT_POP (field.value->get_locus_slow (), field.value.get (), value, exprs); + if (value == NULL) + { + rust_fatal_error (field.value->get_locus_slow (), + "failed to compile value to struct"); + return; + } + exprs.push_back (value); +} + void Compilation::visit (AST::StructExprStructFields &expr) -{} +{ + AST::StructStruct *decl = NULL; + if (!scope.LookupStructDecl (expr.get_struct_name ().as_string (), &decl)) + { + rust_error_at (expr.get_locus_slow (), "unknown type"); + return; + } + + Btype *structType = NULL; + if (!scope.LookupType (expr.get_struct_name ().as_string (), &structType)) + { + rust_fatal_error (expr.get_locus_slow (), "unknown type"); + return; + } + + structBuffer.push_back (decl); + std::vector<Bexpression *> constructor; + + // FIXME type resolution pass should ensures these are in correct order + // and have defaults if required + for (auto &field : expr.fields) + { + Bexpression *value = NULL; + VISIT_POP (expr.get_locus_slow (), field, value, exprs); + if (value == NULL) + { + rust_fatal_error (expr.get_locus_slow (), + "failed to compile value to struct"); + return; + } + + constructor.push_back (value); + } + + structBuffer.pop_back (); + auto cons = backend->constructor_expression (structType, constructor, + expr.get_locus_slow ()); + exprs.push_back (cons); +} + void Compilation::visit (AST::StructExprStructBase &expr) {} @@ -1038,6 +1118,7 @@ Compilation::visit (AST::StructStruct &struct_item) type_decls.push_back (compiledStruct); scope.InsertType (struct_item.struct_name, compiledStruct); + scope.InsertStructDecl (struct_item.struct_name, &struct_item); } void @@ -1217,15 +1298,6 @@ Compilation::visit (AST::LetStmt &stmt) if (!stmt.has_init_expr ()) return; - Bexpression *init = NULL; - VISIT_POP (stmt.init_expr->get_locus_slow (), stmt.init_expr, init, exprs); - if (init == NULL) - { - rust_error_at (stmt.init_expr->get_locus_slow (), - "failed to compile init statement"); - return; - } - stmt.variables_pattern->accept_vis (*this); for (auto &pattern : patternBuffer) { @@ -1237,8 +1309,22 @@ Compilation::visit (AST::LetStmt &stmt) return; } + varBuffer.push_back (var); + + Bexpression *init = NULL; + VISIT_POP (stmt.init_expr->get_locus_slow (), stmt.init_expr, init, + exprs); + if (init == NULL) + { + rust_error_at (stmt.init_expr->get_locus_slow (), + "failed to compile init statement"); + return; + } + auto s = backend->init_statement (scope.GetCurrentFndecl (), var, init); scope.AddStatement (s); + + varBuffer.pop_back (); } patternBuffer.clear (); } diff --git a/gcc/rust/backend/rust-compile.h b/gcc/rust/backend/rust-compile.h index ec39236..b28f0ee 100644 --- a/gcc/rust/backend/rust-compile.h +++ b/gcc/rust/backend/rust-compile.h @@ -242,6 +242,8 @@ private: std::vector<AST::IdentifierPattern> patternBuffer; std::vector< ::Bexpression *> exprs; std::vector< ::Bstatement *> stmts; + std::vector< ::Bvariable *> varBuffer; + std::vector<AST::StructStruct*> structBuffer; // careful these are the vectors we pass into the GCC middle-end std::vector< ::Btype *> type_decls; |