aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2020-05-18 23:25:16 +0100
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 21:13:14 +0000
commit1acf8eba36b06ab816866821542d189935ba360e (patch)
tree43446a57ac5ba7fbf43058181d5bbfb2a5cc8340 /gcc
parent2be82f24b4150c0c71ae45c17e11a7a159c2dcc4 (diff)
downloadgcc-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.h1
-rw-r--r--gcc/rust/analysis/rust-scan.cc24
-rw-r--r--gcc/rust/analysis/rust-scan.h4
-rw-r--r--gcc/rust/analysis/rust-type-resolution.cc94
-rw-r--r--gcc/rust/analysis/rust-type-resolution.h3
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 &macro)
// 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 &macro)
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 &param : 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