diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2026-01-22 11:47:23 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-22 11:47:23 +0100 |
| commit | 3f8a32aeb963e056ac7709c26f05a99fb884ef95 (patch) | |
| tree | 4eed35fa23e9f4c5b7dedc6a355b16f5d3119661 /src/parser.cpp | |
| parent | fb479b3aaec5a9a715bcff7d65498ba18020f4f0 (diff) | |
| parent | 5c09550d383df49a1d29d8f66bc1c45ee3be1136 (diff) | |
Merge branch 'master' into xmlcomment
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 823021e04..fc55dae97 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2176,7 +2176,7 @@ gb_internal bool ast_on_same_line(Token const &x, Ast *yp) { return x.pos.line == y.pos.line; } -gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { +gb_internal Ast *parse_inlining_or_tailing_operand(AstFile *f, Token token) { Ast *expr = parse_unary_expr(f, false); Ast *e = strip_or_return_expr(expr); if (e == nullptr) { @@ -2187,11 +2187,14 @@ gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { return ast_bad_expr(f, token, f->curr_token); } ProcInlining pi = ProcInlining_none; + ProcTailing pt = ProcTailing_none; if (token.kind == Token_Ident) { if (token.string == "force_inline") { pi = ProcInlining_inline; } else if (token.string == "force_no_inline") { pi = ProcInlining_no_inline; + } else if (token.string == "must_tail") { + pt = ProcTailing_must_tail; } } @@ -2211,6 +2214,15 @@ gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { } } + if (pt != ProcTailing_none) { + if (e->kind == Ast_ProcLit) { + syntax_error(expr, "'#must_call' can only be applied to a procedure call, not the procedure literal"); + e->ProcLit.tailing = pt; + } else if (e->kind == Ast_CallExpr) { + e->CallExpr.tailing = pt; + } + } + return expr; } @@ -2507,8 +2519,9 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { syntax_error(tag, "#relative types have now been removed in favour of \"core:relative\""); return ast_relative_type(f, tag, type); } else if (name.string == "force_inline" || - name.string == "force_no_inline") { - return parse_force_inlining_operand(f, name); + name.string == "force_no_inline" || + name.string == "must_tail") { + return parse_inlining_or_tailing_operand(f, name); } return ast_basic_directive(f, token, name); } @@ -4008,6 +4021,10 @@ gb_internal ProcCallingConvention string_to_calling_convention(String const &s) if (s == "win64") return ProcCC_Win64; if (s == "sysv") return ProcCC_SysV; + if (s == "preserve/none") return ProcCC_PreserveNone; + if (s == "preserve/most") return ProcCC_PreserveMost; + if (s == "preserve/all") return ProcCC_PreserveAll; + if (s == "system") { if (build_context.metrics.os == TargetOs_windows) { return ProcCC_StdCall; @@ -5399,8 +5416,9 @@ gb_internal Ast *parse_stmt(AstFile *f) { expect_semicolon(f); return stmt; } else if (name.string == "force_inline" || - name.string == "force_no_inline") { - Ast *expr = parse_force_inlining_operand(f, name); + name.string == "force_no_inline" || + name.string == "must_tail") { + Ast *expr = parse_inlining_or_tailing_operand(f, name); Ast *stmt = ast_expr_stmt(f, expr); expect_semicolon(f); return stmt; |