diff options
author | Philip Herron <herron.philip@googlemail.com> | 2020-07-05 15:39:40 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-28 21:13:18 +0000 |
commit | 8f0507ad9ebff18c7c2baacb981434018dad2600 (patch) | |
tree | 4d7a4d0c3d8d82af3ed0aacaac7accfc70d87b20 /gcc | |
parent | 1d7ab6b109a7654c283705d90ff4c96f1266178a (diff) | |
download | gcc-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.cc | 111 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.h | 2 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 13 |
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 (); } |