aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2020-07-21 21:40:22 +0100
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 21:13:19 +0000
commitffb8dbc16a003a0f00662ded052de3a3b7dcb964 (patch)
tree48597394d7b0f2bc76dd52696081bf62aed9cf58
parentaac6645c2204837ec30ff720e6087e6cf588cec7 (diff)
downloadgcc-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}; }
-rw-r--r--gcc/rust/backend/cscope.h13
-rw-r--r--gcc/rust/backend/rust-compile.cc110
-rw-r--r--gcc/rust/backend/rust-compile.h2
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;