aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2020-07-05 15:39:40 +0100
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 21:13:18 +0000
commit8f0507ad9ebff18c7c2baacb981434018dad2600 (patch)
tree4d7a4d0c3d8d82af3ed0aacaac7accfc70d87b20 /gcc
parent1d7ab6b109a7654c283705d90ff4c96f1266178a (diff)
downloadgcc-8f0507ad9ebff18c7c2baacb981434018dad2600.zip
gcc-8f0507ad9ebff18c7c2baacb981434018dad2600.tar.gz
gcc-8f0507ad9ebff18c7c2baacb981434018dad2600.tar.bz2
Type Resolve Struct initializtion of their fields
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/analysis/rust-type-resolution.cc111
-rw-r--r--gcc/rust/analysis/rust-type-resolution.h2
-rw-r--r--gcc/rust/ast/rust-expr.h13
3 files changed, 113 insertions, 13 deletions
diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc
index 9d59d7c..8edebba 100644
--- a/gcc/rust/analysis/rust-type-resolution.cc
+++ b/gcc/rust/analysis/rust-type-resolution.cc
@@ -7,11 +7,12 @@
AST::PathIdentSegment seg (_X); \
auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( \
new AST::TypePathSegment (::std::move (seg), false, \
- Linemap::unknown_location ())); \
+ Linemap::predeclared_location ())); \
::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs; \
segs.push_back (::std::move (typePath)); \
- auto bType = new AST::TypePath (::std::move (segs), \
- Linemap::unknown_location (), false); \
+ auto bType \
+ = new AST::TypePath (::std::move (segs), \
+ Linemap::predeclared_location (), false); \
_S.InsertType (_X, bType); \
} \
while (0)
@@ -413,22 +414,120 @@ TypeResolution::visit (AST::TupleExpr &expr)
void
TypeResolution::visit (AST::TupleIndexExpr &expr)
{}
+
void
TypeResolution::visit (AST::StructExprStruct &expr)
{}
+
// void TypeResolution::visit(StructExprField& field) {}
void
TypeResolution::visit (AST::StructExprFieldIdentifier &field)
{}
+
void
TypeResolution::visit (AST::StructExprFieldIdentifierValue &field)
-{}
+{
+ identifierBuffer = &field.field_name;
+ field.value->accept_vis (*this);
+}
+
void
TypeResolution::visit (AST::StructExprFieldIndexValue &field)
-{}
+{
+ tupleIndexBuffer = &field.index;
+ field.value->accept_vis (*this);
+}
+
void
TypeResolution::visit (AST::StructExprStructFields &expr)
-{}
+{
+ AST::StructStruct *decl = NULL;
+ if (!scope.LookupStruct (expr.get_struct_name ().as_string (), &decl))
+ {
+ rust_error_at (expr.get_locus_slow (), "unknown type");
+ return;
+ }
+
+ for (auto &field : expr.fields)
+ {
+ identifierBuffer = NULL;
+ tupleIndexBuffer = NULL;
+
+ auto before = typeBuffer.size ();
+ field->accept_vis (*this);
+ if (typeBuffer.size () <= before)
+ {
+ rust_error_at (expr.get_locus_slow (),
+ "unable to determine type for field");
+ return;
+ }
+
+ auto inferedType = typeBuffer.back ();
+ typeBuffer.pop_back ();
+
+ // do we have a name for this
+ if (identifierBuffer != NULL)
+ {
+ AST::StructField *declField = NULL;
+ for (auto &df : decl->fields)
+ {
+ if (identifierBuffer->compare (df.field_name) == 0)
+ {
+ declField = &df;
+ break;
+ }
+ }
+ identifierBuffer = NULL;
+
+ if (declField == NULL)
+ {
+ rust_error_at (expr.get_locus_slow (), "unknown field");
+ return;
+ }
+
+ if (!typesAreCompatible (declField->field_type.get (), inferedType,
+ expr.get_locus_slow ()))
+ return;
+ }
+ // do we have an index for this
+ else if (tupleIndexBuffer != NULL)
+ {
+ AST::StructField *declField = NULL;
+ if (*tupleIndexBuffer < decl->fields.size ())
+ {
+ declField = &decl->fields[*tupleIndexBuffer];
+ }
+ tupleIndexBuffer = NULL;
+
+ if (declField == NULL)
+ {
+ rust_error_at (expr.get_locus_slow (), "unknown field at index");
+ return;
+ }
+
+ if (!typesAreCompatible (declField->field_type.get (), inferedType,
+ expr.get_locus_slow ()))
+ return;
+ }
+ else
+ {
+ rust_fatal_error (expr.get_locus_slow (), "unknown field initialise");
+ return;
+ }
+ }
+
+ // setup a path in type
+ AST::PathIdentSegment seg (expr.get_struct_name ().as_string ());
+ auto typePath = ::std::unique_ptr<AST::TypePathSegment> (
+ new AST::TypePathSegment (::std::move (seg), false,
+ expr.get_locus_slow ()));
+ ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs;
+ segs.push_back (::std::move (typePath));
+ auto bType
+ = new AST::TypePath (::std::move (segs), expr.get_locus_slow (), false);
+ typeBuffer.push_back (bType);
+}
+
void
TypeResolution::visit (AST::StructExprStructBase &expr)
{}
diff --git a/gcc/rust/analysis/rust-type-resolution.h b/gcc/rust/analysis/rust-type-resolution.h
index fede04f..6f74719 100644
--- a/gcc/rust/analysis/rust-type-resolution.h
+++ b/gcc/rust/analysis/rust-type-resolution.h
@@ -301,6 +301,8 @@ private:
bool isTypeInScope (AST::Type *type, Location locus);
TypeScoping scope;
+ std::string *identifierBuffer;
+ int *tupleIndexBuffer;
};
} // namespace Analysis
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 9531cf2..91e176f 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -1671,13 +1671,11 @@ protected:
// struct
struct StructBase
{
-private:
+public:
// Expr* base_struct;
::std::unique_ptr<Expr> base_struct;
// TODO: should this store location data?
-
-public:
StructBase (::std::unique_ptr<Expr> base_struct_ptr)
: base_struct (::std::move (base_struct_ptr))
{}
@@ -1749,11 +1747,11 @@ protected:
// Identifier-only variant of StructExprField AST node
class StructExprFieldIdentifier : public StructExprField
{
+public:
Identifier field_name;
// TODO: should this store location data?
-public:
StructExprFieldIdentifier (Identifier field_identifier)
: field_name (::std::move (field_identifier))
{}
@@ -1776,6 +1774,7 @@ protected:
// abstract
class StructExprFieldWithVal : public StructExprField
{
+public:
// Expr* value;
::std::unique_ptr<Expr> value;
@@ -1814,11 +1813,11 @@ public:
// Identifier and value variant of StructExprField AST node
class StructExprFieldIdentifierValue : public StructExprFieldWithVal
{
+public:
Identifier field_name;
// TODO: should this store location data?
-public:
StructExprFieldIdentifierValue (Identifier field_identifier,
::std::unique_ptr<Expr> field_value)
: StructExprFieldWithVal (::std::move (field_value)),
@@ -1845,11 +1844,11 @@ protected:
// Tuple index and value variant of StructExprField AST node
class StructExprFieldIndexValue : public StructExprFieldWithVal
{
+public:
TupleIndex index;
// TODO: should this store location data?
-public:
StructExprFieldIndexValue (TupleIndex tuple_index,
::std::unique_ptr<Expr> field_value)
: StructExprFieldWithVal (::std::move (field_value)), index (tuple_index)
@@ -1875,13 +1874,13 @@ protected:
// AST node of a struct creator with fields
class StructExprStructFields : public StructExprStruct
{
+public:
//::std::vector<StructExprField> fields;
::std::vector< ::std::unique_ptr<StructExprField> > fields;
// bool has_struct_base;
StructBase struct_base;
-public:
::std::string as_string () const;
inline bool has_struct_base () const { return !struct_base.is_invalid (); }