diff options
author | Philip Herron <herron.philip@googlemail.com> | 2020-05-18 23:25:16 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-28 21:13:14 +0000 |
commit | 1acf8eba36b06ab816866821542d189935ba360e (patch) | |
tree | 43446a57ac5ba7fbf43058181d5bbfb2a5cc8340 /gcc | |
parent | 2be82f24b4150c0c71ae45c17e11a7a159c2dcc4 (diff) | |
download | gcc-1acf8eba36b06ab816866821542d189935ba360e.zip gcc-1acf8eba36b06ab816866821542d189935ba360e.tar.gz gcc-1acf8eba36b06ab816866821542d189935ba360e.tar.bz2 |
Add type resolution to CallExpr
More work will be added here but there is enough to start working
on the initial AST -> Gimple transformations now.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/analysis/rust-resolution.h | 1 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-scan.cc | 24 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-scan.h | 4 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.cc | 94 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.h | 3 |
5 files changed, 120 insertions, 6 deletions
diff --git a/gcc/rust/analysis/rust-resolution.h b/gcc/rust/analysis/rust-resolution.h index ee1c692..0105a8b 100644 --- a/gcc/rust/analysis/rust-resolution.h +++ b/gcc/rust/analysis/rust-resolution.h @@ -238,6 +238,7 @@ protected: std::vector<AST::IdentifierPattern> letPatternBuffer; std::vector<AST::Type *> typeBuffer; std::vector<std::string> typeComparisonBuffer; + std::vector<AST::Function *> functionLookup; }; } // namespace Analysis diff --git a/gcc/rust/analysis/rust-scan.cc b/gcc/rust/analysis/rust-scan.cc index d579f0d..4c032b0 100644 --- a/gcc/rust/analysis/rust-scan.cc +++ b/gcc/rust/analysis/rust-scan.cc @@ -12,6 +12,20 @@ TopLevelScan::TopLevelScan (AST::Crate &crate) : crate (crate) TopLevelScan::~TopLevelScan () {} +AST::Function * +TopLevelScan::lookupFunction (AST::Expr *expr) +{ + auto before = fnLookup.size (); + expr->accept_vis (*this); + if (fnLookup.size () > before) + { + AST::Function *fndecl = fnLookup.back (); + fnLookup.pop_back (); + return fndecl; + } + return NULL; +} + void TopLevelScan::visit (AST::Token &tok) {} @@ -43,7 +57,15 @@ TopLevelScan::visit (AST::MacroInvocationSemi ¯o) // rust-path.h void TopLevelScan::visit (AST::PathInExpression &path) -{} +{ + auto it = functions.find (path.as_string ()); + bool foundFndecl = it != functions.end (); + if (foundFndecl) + { + fnLookup.push_back (it->second); + return; + } +} void TopLevelScan::visit (AST::TypePathSegment &segment) diff --git a/gcc/rust/analysis/rust-scan.h b/gcc/rust/analysis/rust-scan.h index ccd41fe..e898d41 100644 --- a/gcc/rust/analysis/rust-scan.h +++ b/gcc/rust/analysis/rust-scan.h @@ -15,6 +15,8 @@ public: ~TopLevelScan (); + AST::Function *lookupFunction (AST::Expr *expr); + // visitor impl // rust-ast.h // virtual void visit(AttrInput& attr_input); @@ -223,6 +225,8 @@ public: private: std::map<std::string, AST::Function *> functions; AST::Crate &crate; + + std::vector<AST::Function *> fnLookup; }; } // namespace Analysis diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc index f56a9eb..0045420 100644 --- a/gcc/rust/analysis/rust-type-resolution.cc +++ b/gcc/rust/analysis/rust-type-resolution.cc @@ -22,6 +22,8 @@ namespace Analysis { TypeResolution::TypeResolution (AST::Crate &crate, TopLevelScan &toplevel) : Resolution (crate, toplevel) { + functionScope.Push (); + // push all builtin types - this is probably too basic for future needs ADD_BUILTIN_TYPE ("u8", typeScope); ADD_BUILTIN_TYPE ("u16", typeScope); @@ -43,6 +45,7 @@ TypeResolution::TypeResolution (AST::Crate &crate, TopLevelScan &toplevel) TypeResolution::~TypeResolution () { + functionScope.Pop (); typeScope.Pop (); scope.Pop (); } @@ -67,13 +70,26 @@ bool TypeResolution::typesAreCompatible (AST::Type *lhs, AST::Type *rhs, Location locus) { + auto before = typeComparisonBuffer.size (); lhs->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (locus, "failed to understand type for lhs"); + return false; + } + + auto lhsTypeStr = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + rhs->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (locus, "failed to understand type for rhs"); + return false; + } auto rhsTypeStr = typeComparisonBuffer.back (); typeComparisonBuffer.pop_back (); - auto lhsTypeStr = typeComparisonBuffer.back (); - typeComparisonBuffer.pop_back (); // FIXME this needs to handle the cases of an i8 going into an i32 which is // compatible @@ -87,6 +103,22 @@ TypeResolution::typesAreCompatible (AST::Type *lhs, AST::Type *rhs, return true; } +AST::Function * +TypeResolution::lookupFndecl (AST::Expr *expr) +{ + size_t before = functionLookup.size (); + expr->accept_vis (*this); + if (functionLookup.size () > before) + { + auto fndecl = functionLookup.back (); + functionLookup.pop_back (); + return fndecl; + } + + rust_error_at (expr->get_locus_slow (), "failed to lookup function"); + return NULL; +} + void TypeResolution::visit (AST::Token &tok) {} @@ -129,7 +161,20 @@ TypeResolution::visit (AST::MacroInvocationSemi ¯o) void TypeResolution::visit (AST::PathInExpression &path) { - printf ("PathInExpression: %s\n", path.as_string ().c_str ()); + // look up in the functionScope else lookup in the toplevel scan + AST::Function *fndecl = NULL; + if (functionScope.Lookup (path.as_string (), &fndecl)) + { + functionLookup.push_back (fndecl); + return; + } + + fndecl = toplevel.lookupFunction (&path); + if (fndecl != NULL) + { + functionLookup.push_back (fndecl); + return; + } } void @@ -394,7 +439,35 @@ TypeResolution::visit (AST::EnumExprFieldless &expr) void TypeResolution::visit (AST::CallExpr &expr) { - printf ("CallExpr: %s\n", expr.as_string ().c_str ()); + auto fndecl = lookupFndecl (expr.function.get ()); + if (fndecl == NULL) + return; + + typeBuffer.push_back (fndecl->return_type.get ()); + + auto before = typeBuffer.size (); + for (auto &item : expr.params) + item->accept_vis (*this); + + auto numInferedParams = typeBuffer.size () - before; + if (numInferedParams != expr.params.size ()) + { + rust_error_at (expr.locus, "Failed to infer all parameters"); + return; + } + + auto offs = numInferedParams - 1; + for (auto it = fndecl->function_params.rbegin (); + it != fndecl->function_params.rend (); ++it) + { + AST::Type *argument = typeBuffer.back (); + typeBuffer.pop_back (); + + if (!typesAreCompatible (it->type.get (), argument, + expr.params[offs]->get_locus_slow ())) + return; + offs--; + } } void @@ -538,7 +611,9 @@ 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.Push (); for (auto ¶m : function.function_params) { @@ -562,6 +637,7 @@ TypeResolution::visit (AST::Function &function) } scope.Pop (); + functionScope.Pop (); } void @@ -758,9 +834,10 @@ TypeResolution::visit (AST::LetStmt &stmt) AST::Type *inferedType = NULL; if (stmt.has_init_expr ()) { + auto before = typeBuffer.size (); stmt.init_expr->accept_vis (*this); - if (typeBuffer.empty ()) + if (typeBuffer.size () <= before) { rust_error_at ( stmt.init_expr->get_locus_slow (), @@ -770,6 +847,13 @@ TypeResolution::visit (AST::LetStmt &stmt) inferedType = typeBuffer.back (); typeBuffer.pop_back (); + + if (inferedType == NULL) + { + rust_error_at (stmt.init_expr->get_locus_slow (), + "void type found for statement initialisation"); + return; + } } if (stmt.has_type () && stmt.has_init_expr ()) diff --git a/gcc/rust/analysis/rust-type-resolution.h b/gcc/rust/analysis/rust-type-resolution.h index 5f8120c..58d36db 100644 --- a/gcc/rust/analysis/rust-type-resolution.h +++ b/gcc/rust/analysis/rust-type-resolution.h @@ -220,6 +220,9 @@ private: TypeResolution (AST::Crate &crate, TopLevelScan &toplevel); bool go () override; bool typesAreCompatible (AST::Type *lhs, AST::Type *rhs, Location locus); + AST::Function *lookupFndecl (AST::Expr *expr); + + Scope<AST::Function *> functionScope; }; } // namespace Analysis |