| ... | @@ -115,7 +115,16 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t | ... | @@ -115,7 +115,16 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t |
| 115 | for (int i = 0; i < node->data.fn_proto.params.length; i += 1) { | 115 | for (int i = 0; i < node->data.fn_proto.params.length; i += 1) { |
| 116 | AstNode *child = node->data.fn_proto.params.at(i); | 116 | AstNode *child = node->data.fn_proto.params.at(i); |
| 117 | assert(child->type == NodeTypeParamDecl); | 117 | assert(child->type == NodeTypeParamDecl); |
| 118 | resolve_type(g, child->data.param_decl.type); | 118 | TypeTableEntry *type_entry = resolve_type(g, child->data.param_decl.type); |
| | 119 | if (type_entry == g->builtin_types.entry_unreachable) { |
| | 120 | add_node_error(g, child->data.param_decl.type, |
| | 121 | buf_sprintf("parameter of type 'unreachable' not allowed")); |
| | 122 | } else if (type_entry == g->builtin_types.entry_void) { |
| | 123 | if (node->data.fn_proto.visib_mod == FnProtoVisibModExport) { |
| | 124 | add_node_error(g, child->data.param_decl.type, |
| | 125 | buf_sprintf("parameter of type 'void' not allowed on exported functions")); |
| | 126 | } |
| | 127 | } |
| 119 | } | 128 | } |
| 120 | | 129 | |
| 121 | resolve_type(g, node->data.fn_proto.return_type); | 130 | resolve_type(g, node->data.fn_proto.return_type); |
| ... | @@ -423,18 +432,18 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -423,18 +432,18 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 423 | resolve_type(g, variable_declaration->type) : nullptr; | 432 | resolve_type(g, variable_declaration->type) : nullptr; |
| 424 | if (explicit_type == g->builtin_types.entry_unreachable) { | 433 | if (explicit_type == g->builtin_types.entry_unreachable) { |
| 425 | add_node_error(g, variable_declaration->type, | 434 | add_node_error(g, variable_declaration->type, |
| 426 | buf_sprintf("variable of type 'unreachable' is not allowed.")); | 435 | buf_sprintf("variable of type 'unreachable' not allowed")); |
| 427 | } | 436 | } |
| 428 | | 437 | |
| 429 | TypeTableEntry *implicit_type = variable_declaration->expr != nullptr ? | 438 | TypeTableEntry *implicit_type = variable_declaration->expr != nullptr ? |
| 430 | analyze_expression(g, import, context, explicit_type, variable_declaration->expr) : nullptr; | 439 | analyze_expression(g, import, context, explicit_type, variable_declaration->expr) : nullptr; |
| 431 | if (implicit_type == g->builtin_types.entry_unreachable) { | 440 | if (implicit_type == g->builtin_types.entry_unreachable) { |
| 432 | add_node_error(g, node, | 441 | add_node_error(g, node, |
| 433 | buf_sprintf("variable initialization is unreachable.")); | 442 | buf_sprintf("variable initialization is unreachable")); |
| 434 | } | 443 | } |
| 435 | | 444 | |
| 436 | if (implicit_type == nullptr) { | 445 | if (implicit_type == nullptr) { |
| 437 | add_node_error(g, node, buf_sprintf("initial values are required for variable declaration.")); | 446 | add_node_error(g, node, buf_sprintf("initial values are required for variable declaration")); |
| 438 | } | 447 | } |
| 439 | | 448 | |
| 440 | TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type; | 449 | TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type; |
| ... | @@ -443,7 +452,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -443,7 +452,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 443 | LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol); | 452 | LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol); |
| 444 | if (existing_variable) { | 453 | if (existing_variable) { |
| 445 | add_node_error(g, node, | 454 | add_node_error(g, node, |
| 446 | buf_sprintf("redeclaration of variable '%s'.", buf_ptr(&variable_declaration->symbol))); | 455 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(&variable_declaration->symbol))); |
| 447 | } else { | 456 | } else { |
| 448 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); | 457 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); |
| 449 | buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol); | 458 | buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol); |
| ... | @@ -723,11 +732,6 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, | ... | @@ -723,11 +732,6 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, |
| 723 | assert(param_decl->type->type == NodeTypeType); | 732 | assert(param_decl->type->type == NodeTypeType); |
| 724 | TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry; | 733 | TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry; |
| 725 | | 734 | |
| 726 | if (type == g->builtin_types.entry_unreachable) { | | |
| 727 | add_node_error(g, param_decl->type, | | |
| 728 | buf_sprintf("parameter of type 'unreachable' is not allowed.")); | | |
| 729 | } | | |
| 730 | | | |
| 731 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); | 735 | LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1); |
| 732 | buf_init_from_buf(&variable_entry->name, &param_decl->name); | 736 | buf_init_from_buf(&variable_entry->name, &param_decl->name); |
| 733 | variable_entry->type = type; | 737 | variable_entry->type = type; |