mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-17 17:24:43 +00:00
Add #must_tail and "preserve/none" calling convention
This commit is contained in:
@@ -8426,11 +8426,14 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
||||
break;
|
||||
case ProcTailing_must_tail:
|
||||
is_call_tailed = true;
|
||||
if (proc != nullptr) {
|
||||
Entity *e = entity_from_expr(proc);
|
||||
if (e != nullptr && e->kind == Entity_Procedure) {
|
||||
// TODO(bill): `preserve_none`
|
||||
}
|
||||
if (c->curr_proc_sig == nullptr || !are_types_identical(c->curr_proc_sig, pt)) {
|
||||
ERROR_BLOCK();
|
||||
gbString a = type_to_string(pt);
|
||||
gbString b = type_to_string(c->curr_proc_sig);
|
||||
error(call, "Use of '#must_tail' of a procedure must have the same type as the procedure it was called within");
|
||||
error_line("\tCall type: %s, parent type: %s", a, b);
|
||||
gb_string_free(b);
|
||||
gb_string_free(a);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -671,6 +671,7 @@ enum lbCallingConventionKind : unsigned {
|
||||
lbCallingConvention_PreserveAll = 15,
|
||||
lbCallingConvention_Swift = 16,
|
||||
lbCallingConvention_CXX_FAST_TLS = 17,
|
||||
lbCallingConvention_PreserveNone = 21,
|
||||
lbCallingConvention_FirstTargetCC = 64,
|
||||
lbCallingConvention_X86_StdCall = 64,
|
||||
lbCallingConvention_X86_FastCall = 65,
|
||||
@@ -724,6 +725,8 @@ lbCallingConventionKind const lb_calling_convention_map[ProcCC_MAX] = {
|
||||
lbCallingConvention_Win64, // ProcCC_Win64,
|
||||
lbCallingConvention_X86_64_SysV, // ProcCC_SysV,
|
||||
|
||||
lbCallingConvention_PreserveNone, // ProcCC_PreserveNone,
|
||||
|
||||
};
|
||||
|
||||
enum : LLVMDWARFTypeEncoding {
|
||||
|
||||
@@ -179,12 +179,6 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i
|
||||
}
|
||||
}
|
||||
|
||||
switch (p->tailing) {
|
||||
case ProcTailing_must_tail:
|
||||
lb_add_attribute_to_proc(m, p->value, "preserve_none");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (entity->Procedure.optimization_mode) {
|
||||
case ProcedureOptimizationMode_None:
|
||||
lb_add_attribute_to_proc(m, p->value, "optnone");
|
||||
|
||||
@@ -2216,6 +2216,7 @@ gb_internal Ast *parse_inlining_or_tailing_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;
|
||||
@@ -4020,6 +4021,8 @@ 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 == "system") {
|
||||
if (build_context.metrics.os == TargetOs_windows) {
|
||||
return ProcCC_StdCall;
|
||||
|
||||
@@ -301,6 +301,7 @@ enum ProcCallingConvention : i32 {
|
||||
ProcCC_Win64 = 9,
|
||||
ProcCC_SysV = 10,
|
||||
|
||||
ProcCC_PreserveNone = 11,
|
||||
|
||||
ProcCC_MAX,
|
||||
|
||||
@@ -320,6 +321,7 @@ gb_global char const *proc_calling_convention_strings[ProcCC_MAX] = {
|
||||
"inlineasm",
|
||||
"win64",
|
||||
"sysv",
|
||||
"preserve/none",
|
||||
};
|
||||
|
||||
gb_internal ProcCallingConvention default_calling_convention(void) {
|
||||
|
||||
@@ -5210,40 +5210,12 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha
|
||||
case Type_Proc:
|
||||
str = gb_string_appendc(str, "proc");
|
||||
|
||||
switch (type->Proc.calling_convention) {
|
||||
case ProcCC_Odin:
|
||||
if (default_calling_convention() != ProcCC_Odin) {
|
||||
str = gb_string_appendc(str, " \"odin\" ");
|
||||
}
|
||||
break;
|
||||
case ProcCC_Contextless:
|
||||
if (default_calling_convention() != ProcCC_Contextless) {
|
||||
str = gb_string_appendc(str, " \"contextless\" ");
|
||||
}
|
||||
break;
|
||||
case ProcCC_CDecl:
|
||||
str = gb_string_appendc(str, " \"c\" ");
|
||||
break;
|
||||
case ProcCC_StdCall:
|
||||
str = gb_string_appendc(str, " \"std\" ");
|
||||
break;
|
||||
case ProcCC_FastCall:
|
||||
str = gb_string_appendc(str, " \"fastcall\" ");
|
||||
break;
|
||||
break;
|
||||
case ProcCC_None:
|
||||
str = gb_string_appendc(str, " \"none\" ");
|
||||
break;
|
||||
case ProcCC_Naked:
|
||||
str = gb_string_appendc(str, " \"naked\" ");
|
||||
break;
|
||||
// case ProcCC_VectorCall:
|
||||
// str = gb_string_appendc(str, " \"vectorcall\" ");
|
||||
// break;
|
||||
// case ProcCC_ClrCall:
|
||||
// str = gb_string_appendc(str, " \"clrcall\" ");
|
||||
// break;
|
||||
if (type->Proc.calling_convention != default_calling_convention()) {
|
||||
str = gb_string_appendc(str, " \"");
|
||||
str = gb_string_appendc(str, proc_calling_convention_strings[type->Proc.calling_convention]);
|
||||
str = gb_string_appendc(str, "\" ");
|
||||
}
|
||||
|
||||
str = gb_string_appendc(str, "(");
|
||||
if (type->Proc.params) {
|
||||
str = write_type_to_string(str, type->Proc.params, shorthand, allow_polymorphic);
|
||||
|
||||
Reference in New Issue
Block a user