diff options
author | Philip Herron <herron.philip@googlemail.com> | 2020-06-13 21:14:17 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-28 21:13:16 +0000 |
commit | 821da3d3a2b5f710efcdc8600a69cd4677e84583 (patch) | |
tree | eccddc81a4f9a80b7bfc80f70d528e7f4de2f51e | |
parent | 15280699c13f799f25bfc95656415c0ec2c1b901 (diff) | |
download | gcc-821da3d3a2b5f710efcdc8600a69cd4677e84583.zip gcc-821da3d3a2b5f710efcdc8600a69cd4677e84583.tar.gz gcc-821da3d3a2b5f710efcdc8600a69cd4677e84583.tar.bz2 |
Refactor type resolution scoping to use a simple class akin to backend code
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.cc | 131 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.h | 81 | ||||
-rw-r--r-- | gcc/rust/analysis/scope.h | 2 |
3 files changed, 159 insertions, 55 deletions
diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc index b8baabb..9d59d7c 100644 --- a/gcc/rust/analysis/rust-type-resolution.cc +++ b/gcc/rust/analysis/rust-type-resolution.cc @@ -12,7 +12,7 @@ segs.push_back (::std::move (typePath)); \ auto bType = new AST::TypePath (::std::move (segs), \ Linemap::unknown_location (), false); \ - _S.Insert (_X, bType); \ + _S.InsertType (_X, bType); \ } \ while (0) @@ -22,28 +22,35 @@ namespace Analysis { TypeResolution::TypeResolution (AST::Crate &crate, TopLevelScan &toplevel) : Resolution (crate, toplevel) { - functionScope.Push (); + scope.Push (); // push all builtin types - this is probably too basic for future needs - ADD_BUILTIN_TYPE ("u8", typeScope); - ADD_BUILTIN_TYPE ("u16", typeScope); - ADD_BUILTIN_TYPE ("u32", typeScope); - ADD_BUILTIN_TYPE ("u64", typeScope); - - ADD_BUILTIN_TYPE ("i8", typeScope); - ADD_BUILTIN_TYPE ("i16", typeScope); - ADD_BUILTIN_TYPE ("i32", typeScope); - ADD_BUILTIN_TYPE ("i64", typeScope); - - ADD_BUILTIN_TYPE ("f32", typeScope); - ADD_BUILTIN_TYPE ("f64", typeScope); - - ADD_BUILTIN_TYPE ("char", typeScope); - ADD_BUILTIN_TYPE ("str", typeScope); - ADD_BUILTIN_TYPE ("bool", typeScope); + ADD_BUILTIN_TYPE ("u8", scope); + ADD_BUILTIN_TYPE ("u16", scope); + ADD_BUILTIN_TYPE ("u32", scope); + ADD_BUILTIN_TYPE ("u64", scope); + + ADD_BUILTIN_TYPE ("i8", scope); + ADD_BUILTIN_TYPE ("i16", scope); + ADD_BUILTIN_TYPE ("i32", scope); + ADD_BUILTIN_TYPE ("i64", scope); + + ADD_BUILTIN_TYPE ("f32", scope); + ADD_BUILTIN_TYPE ("f64", scope); + + ADD_BUILTIN_TYPE ("char", scope); + ADD_BUILTIN_TYPE ("str", scope); + ADD_BUILTIN_TYPE ("bool", scope); + + // now its the crate scope + scope.Push (); } -TypeResolution::~TypeResolution () { functionScope.Pop (); } +TypeResolution::~TypeResolution () +{ + scope.Pop (); // crate + scope.Pop (); // builtins +} bool TypeResolution::Resolve (AST::Crate &crate, TopLevelScan &toplevel) @@ -96,13 +103,7 @@ TypeResolution::typesAreCompatible (AST::Type *lhs, AST::Type *rhs, } AST::Type *val = NULL; - if (!typeScope.Lookup (lhsTypeStr, &val)) - { - rust_error_at (locus, "unknown type"); - return false; - } - - return true; + return scope.LookupType (lhsTypeStr, &val); } bool @@ -121,13 +122,7 @@ TypeResolution::isTypeInScope (AST::Type *type, Location locus) typeComparisonBuffer.pop_back (); AST::Type *val = NULL; - if (!typeScope.Lookup (t, &val)) - { - rust_error_at (locus, "unknown type"); - return false; - } - - return true; + return scope.LookupType (t, &val); } AST::Function * @@ -162,7 +157,7 @@ void TypeResolution::visit (AST::IdentifierExpr &ident_expr) { AST::Type *type = NULL; - bool ok = scope.Lookup (ident_expr.ident, &type); + bool ok = scope.LookupType (ident_expr.ident, &type); if (!ok) { rust_error_at (ident_expr.locus, "unknown identifier"); @@ -190,7 +185,7 @@ TypeResolution::visit (AST::PathInExpression &path) { // look up in the functionScope else lookup in the toplevel scan AST::Function *fndecl = NULL; - if (functionScope.Lookup (path.as_string (), &fndecl)) + if (scope.LookupFunction (path.as_string (), &fndecl)) { functionLookup.push_back (fndecl); return; @@ -282,7 +277,7 @@ TypeResolution::visit (AST::LiteralExpr &expr) } AST::Type *val = NULL; - bool ok = typeScope.Lookup (type, &val); + bool ok = scope.LookupType (type, &val); if (ok) typeBuffer.push_back (val); else @@ -516,9 +511,18 @@ TypeResolution::visit (AST::FieldAccessExpr &expr) void TypeResolution::visit (AST::ClosureExprInner &expr) {} + void TypeResolution::visit (AST::BlockExpr &expr) -{} +{ + scope.Push (); + for (auto &stmt : expr.statements) + { + stmt->accept_vis (*this); + } + scope.Pop (); +} + void TypeResolution::visit (AST::ClosureExprInnerTyped &expr) {} @@ -564,15 +568,27 @@ TypeResolution::visit (AST::WhileLetLoopExpr &expr) void TypeResolution::visit (AST::ForLoopExpr &expr) {} + void TypeResolution::visit (AST::IfExpr &expr) -{} +{ + expr.vis_if_block (*this); +} + void TypeResolution::visit (AST::IfExprConseqElse &expr) -{} +{ + expr.vis_if_block (*this); + expr.vis_else_block (*this); +} + void TypeResolution::visit (AST::IfExprConseqIf &expr) -{} +{ + expr.vis_if_block (*this); + expr.vis_conseq_if_expr (*this); +} + void TypeResolution::visit (AST::IfExprConseqIfLet &expr) {} @@ -647,11 +663,10 @@ TypeResolution::visit (AST::Function &function) { // always emit the function with return type in the event of nil return type // its a marker for a void function - scope.Insert (function.function_name, function.return_type.get ()); - functionScope.Insert (function.function_name, &function); - - functionScope.Push (); + scope.InsertType (function.function_name, function.return_type.get ()); + scope.InsertFunction (function.function_name, &function); scope.Push (); + for (auto ¶m : function.function_params) { if (!isTypeInScope (param.type.get (), param.locus)) @@ -667,7 +682,7 @@ TypeResolution::visit (AST::Function &function) auto paramName = letPatternBuffer.back (); letPatternBuffer.pop_back (); - scope.Insert (paramName.variable_ident, param.type.get ()); + scope.InsertType (paramName.variable_ident, param.type.get ()); } // ensure the return type is resolved @@ -683,8 +698,11 @@ TypeResolution::visit (AST::Function &function) stmt->accept_vis (*this); } + auto localMap = scope.PeekLocals (); + for (auto &[_, value] : localMap) + function.locals.push_back (value); + scope.Pop (); - functionScope.Pop (); } void @@ -705,7 +723,7 @@ TypeResolution::visit (AST::StructStruct &struct_item) } } - structsPerBlock.Insert (struct_item.struct_name, &struct_item); + scope.InsertStruct (struct_item.struct_name, &struct_item); } void @@ -886,6 +904,7 @@ TypeResolution::visit (AST::EmptyStmt &stmt) void TypeResolution::visit (AST::LetStmt &stmt) { + scope.InsertLocal (stmt.as_string (), &stmt); if (!stmt.has_init_expr () && !stmt.has_type ()) { rust_error_at (stmt.locus, @@ -942,10 +961,9 @@ TypeResolution::visit (AST::LetStmt &stmt) // get all the names part of this declaration and add the types to the scope stmt.variables_pattern->accept_vis (*this); - for (auto it = letPatternBuffer.begin (); it != letPatternBuffer.end (); it++) - { - scope.Insert (it->variable_ident, inferedType); - } + for (auto &pattern : letPatternBuffer) + scope.InsertType (pattern.variable_ident, inferedType); + letPatternBuffer.clear (); } @@ -957,7 +975,16 @@ TypeResolution::visit (AST::ExprStmtWithoutBlock &stmt) void TypeResolution::visit (AST::ExprStmtWithBlock &stmt) -{} +{ + scope.Push (); + stmt.expr->accept_vis (*this); + auto localMap = scope.PeekLocals (); + for (auto &[_, value] : localMap) + { + stmt.locals.push_back (value); + } + scope.Pop (); +} // rust-type.h void diff --git a/gcc/rust/analysis/rust-type-resolution.h b/gcc/rust/analysis/rust-type-resolution.h index e9fec83..fede04f 100644 --- a/gcc/rust/analysis/rust-type-resolution.h +++ b/gcc/rust/analysis/rust-type-resolution.h @@ -5,8 +5,85 @@ namespace Rust { namespace Analysis { +class TypeScoping +{ +public: + TypeScoping () {} + + ~TypeScoping () {} + + void Push () + { + functionScope.Push (); + localsPerBlock.Push (); + structsPerBlock.Push (); + typeScope.Push (); + } + + void Pop () + { + functionScope.Pop (); + localsPerBlock.Pop (); + structsPerBlock.Pop (); + typeScope.Pop (); + } + + void InsertFunction (std::string ident, AST::Function *fn) + { + functionScope.Insert (ident, fn); + } + + bool LookupFunction (std::string ident, AST::Function **fn) + { + return functionScope.Lookup (ident, fn); + } + + void InsertLocal (std::string ident, AST::LetStmt *let) + { + localsPerBlock.Insert (ident, let); + } + + bool LookupLocal (std::string ident, AST::LetStmt **let) + { + return localsPerBlock.Lookup (ident, let); + } + + std ::map<std::string, AST::LetStmt *> PeekLocals () + { + return localsPerBlock.Peek (); + } + + void InsertStruct (std::string ident, AST::StructStruct *s) + { + structsPerBlock.Insert (ident, s); + } + + bool LookupStruct (std::string ident, AST::StructStruct **s) + { + return structsPerBlock.Lookup (ident, s); + } + + void InsertType (std::string ident, AST::Type *s) + { + typeScope.Insert (ident, s); + } + + bool LookupType (std::string ident, AST::Type **s) + { + return typeScope.Lookup (ident, s); + } + +private: + Scope<AST::Function *> functionScope; + Scope<AST::LetStmt *> localsPerBlock; + Scope<AST::StructStruct *> structsPerBlock; + Scope<AST::Type *> typeScope; +}; + class TypeResolution : public Resolution { + friend class TypeScoping; + public: ~TypeResolution (); static bool Resolve (AST::Crate &crate, TopLevelScan &toplevel); @@ -223,9 +300,7 @@ private: AST::Function *lookupFndecl (AST::Expr *expr); bool isTypeInScope (AST::Type *type, Location locus); - Scope<AST::Function *> functionScope; - Scope<AST::LetStmt *> localsPerBlock; - Scope<AST::StructStruct *> structsPerBlock; + TypeScoping scope; }; } // namespace Analysis diff --git a/gcc/rust/analysis/scope.h b/gcc/rust/analysis/scope.h index 231e667..41bcee6 100644 --- a/gcc/rust/analysis/scope.h +++ b/gcc/rust/analysis/scope.h @@ -47,6 +47,8 @@ public: return toplevel; } + std ::map<std::string, T> Peek () { return scopeStack.back (); } + private: std::vector<std::map<std::string, T> > scopeStack; }; |