aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-01-06 14:07:56 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-01-06 14:07:56 -0500
commit0a9daeb37e997ff75dcd16d1fc3b4cc143314e85 (patch)
tree05ca7f6b64b1e40fc16a595816f3a632a986617c /src/ir.cpp
parentc30106c90665079f525129e344cc1c13e4db162b (diff)
parentd09bd3d86c4d36ad608a91b36c9a6eb6208c9626 (diff)
downloadzig-0a9daeb37e997ff75dcd16d1fc3b4cc143314e85.tar.gz
zig-0a9daeb37e997ff75dcd16d1fc3b4cc143314e85.zip
Merge branch 'cc-work' of https://github.com/LemonBoy/zig into LemonBoy-cc-work
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp58
1 files changed, 46 insertions, 12 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 762e97e257..78be3256c0 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -3248,12 +3248,13 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope,
}
static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type,
- bool is_var_args)
+ IrInstruction **param_types, IrInstruction *align_value, IrInstruction *callconv_value,
+ IrInstruction *return_type, bool is_var_args)
{
IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node);
instruction->param_types = param_types;
instruction->align_value = align_value;
+ instruction->callconv_value = callconv_value;
instruction->return_type = return_type;
instruction->is_var_args = is_var_args;
@@ -3264,6 +3265,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s
if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);
}
if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
+ if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block);
ir_ref_instruction(return_type, irb->current_basic_block);
return &instruction->base;
@@ -8843,6 +8845,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
return irb->codegen->invalid_instruction;
}
+ IrInstruction *callconv_value = nullptr;
+ if (node->data.fn_proto.callconv_expr != nullptr) {
+ callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope);
+ if (callconv_value == irb->codegen->invalid_instruction)
+ return irb->codegen->invalid_instruction;
+ }
+
IrInstruction *return_type;
if (node->data.fn_proto.return_var_token == nullptr) {
if (node->data.fn_proto.return_type == nullptr) {
@@ -8859,7 +8868,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
//return_type = nullptr;
}
- return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
+ return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args);
}
static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -16729,9 +16738,17 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
} break;
case CallingConventionC:
- case CallingConventionNaked:
case CallingConventionCold:
+ case CallingConventionNaked:
+ case CallingConventionInterrupt:
+ case CallingConventionSignal:
case CallingConventionStdcall:
+ case CallingConventionFastcall:
+ case CallingConventionVectorcall:
+ case CallingConventionThiscall:
+ case CallingConventionAPCS:
+ case CallingConventionAAPCS:
+ case CallingConventionAAPCSVFP:
add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);
break;
}
@@ -18094,7 +18111,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
return ira->codegen->invalid_instruction;
}
-
if (fn_type_id->is_var_args) {
if (call_param_count < src_param_count) {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
@@ -18247,8 +18263,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
impl_fn->child_scope = &impl_fn->fndef_scope->base;
+ impl_fn->cc = fn_entry->cc;
FnTypeId inst_fn_type_id = {0};
- init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);
+ init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count);
inst_fn_type_id.param_count = 0;
inst_fn_type_id.is_var_args = false;
@@ -22585,8 +22602,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
// calling_convention: TypeInfo.CallingConvention
ensure_field_index(fn_decl_val->type, "calling_convention", 2);
fn_decl_fields[2]->special = ConstValSpecialStatic;
- fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
- bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc);
+ fn_decl_fields[2]->type = get_builtin_type(ira->codegen, "CallingConvention");
+ bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_entry->cc);
// is_var_args: bool
ensure_field_index(fn_decl_val->type, "is_var_args", 3);
bool is_varargs = fn_node->is_var_args;
@@ -23273,7 +23290,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
// calling_convention: TypeInfo.CallingConvention
ensure_field_index(result->type, "calling_convention", 0);
fields[0]->special = ConstValSpecialStatic;
- fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
+ fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention");
bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
// is_generic: bool
ensure_field_index(result->type, "is_generic", 1);
@@ -26185,6 +26202,21 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
}
+ lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto);
+ if (instruction->callconv_value != nullptr) {
+ ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention");
+
+ IrInstruction *casted_value = ir_implicit_cast(ira, instruction->callconv_value, cc_enum_type);
+ if (type_is_invalid(casted_value->value->type))
+ return ira->codegen->invalid_instruction;
+
+ ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad);
+ if (const_value == nullptr)
+ return ira->codegen->invalid_instruction;
+
+ lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag);
+ }
+
size_t param_count = proto_node->data.fn_proto.params.length;
lazy_fn_type->proto_node = proto_node;
lazy_fn_type->param_types = allocate<IrInstruction *>(param_count);
@@ -26195,9 +26227,11 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
bool param_is_var_args = param_node->data.param_decl.is_var_args;
if (param_is_var_args) {
- if (proto_node->data.fn_proto.cc == CallingConventionC) {
+ const CallingConvention cc = lazy_fn_type->cc;
+
+ if (cc == CallingConventionC) {
break;
- } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) {
+ } else if (cc == CallingConventionUnspecified) {
lazy_fn_type->is_generic = true;
return result;
} else {
@@ -29076,7 +29110,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La
AstNode *proto_node = lazy_fn_type->proto_node;
FnTypeId fn_type_id = {0};
- init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);
+ init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length);
for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index);