aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2018-09-09 14:46:28 +0100
committergingerBill <bill@gingerbill.org>2018-09-09 14:46:28 +0100
commit4f3837f0e6dfcdb743f0d1399a4795088d15f664 (patch)
tree9bd9c2093b8fe9ebecb9e612eca8443bcb057291 /src/check_expr.cpp
parent76848e8807543cf1e3a6675dc404bbb0de392471 (diff)
Procedure inlining on call site
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index f608f1aa1..1225aec0a 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -85,6 +85,17 @@ Type * check_init_variable (CheckerContext *c, Entity *e, Operand *
+Entity *entity_from_expr(Ast *expr) {
+ expr = unparen_expr(expr);
+ switch (expr->kind) {
+ case Ast_Ident:
+ return expr->Ident.entity;
+ case Ast_SelectorExpr:
+ return entity_from_expr(expr->SelectorExpr.selector);
+ }
+ return nullptr;
+}
+
void error_operand_not_expression(Operand *o) {
if (o->mode == Addressing_Type) {
gbString err = expr_to_string(o->expr);
@@ -2862,6 +2873,10 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id) {
ast_node(ce, CallExpr, call);
+ if (ce->inlining != ProcInlining_none) {
+ error(call, "Inlining operators are not allowed on built-in procedures");
+ }
+
BuiltinProc *bp = &builtin_procs[id];
{
char *err = nullptr;
@@ -4807,6 +4822,9 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call) {
} else {
GB_PANIC("Unhandled #%.*s", LIT(name));
}
+ if (ce->inlining != ProcInlining_none) {
+ error(call, "Inlining operators are not allowed on built-in procedures");
+ }
} else {
check_expr_or_type(c, operand, ce->proc);
}
@@ -4964,6 +4982,25 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call) {
}
}
+ switch (ce->inlining) {
+ case ProcInlining_inline: {
+ Entity *e = entity_from_expr(ce->proc);
+ if (e != nullptr && e->kind == Entity_Procedure) {
+ DeclInfo *decl = e->decl_info;
+ if (decl->proc_lit) {
+ ast_node(pl, ProcLit, decl->proc_lit);
+ if (pl->inlining == ProcInlining_no_inline) {
+ error(call, "'inline' cannot be applied to a procedure that has be marked as 'no_inline'");
+ }
+ }
+ }
+ break;
+ }
+
+ case ProcInlining_no_inline:
+ break;
+ }
+
operand->expr = call;
return Expr_Expr;
}
@@ -6511,6 +6548,15 @@ gbString write_expr_to_string(gbString str, Ast *node) {
case_end;
case_ast_node(ce, CallExpr, node);
+ switch (ce->inlining) {
+ case ProcInlining_inline:
+ str = gb_string_appendc(str, "inline ");
+ break;
+ case ProcInlining_no_inline:
+ str = gb_string_appendc(str, "no_inline ");
+ break;
+ }
+
str = write_expr_to_string(str, ce->proc);
str = gb_string_appendc(str, "(");