| ... | @@ -4992,31 +4992,121 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou | ... | @@ -4992,31 +4992,121 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou |
| 4992 | do_code_gen(g); | 4992 | do_code_gen(g); |
| 4993 | } | 4993 | } |
| 4994 | | 4994 | |
| 4995 | static void to_c_type(CodeGen *g, AstNode *type_node, Buf *out_buf) { | 4995 | static const char *c_int_type_names[] = { |
| 4996 | zig_panic("TODO this function needs some love"); | 4996 | [CIntTypeShort] = "short", |
| 4997 | TypeTableEntry *type_entry = get_resolved_expr(type_node)->type_entry; | 4997 | [CIntTypeUShort] = "unsigned short", |
| | 4998 | [CIntTypeInt] = "int", |
| | 4999 | [CIntTypeUInt] = "unsigned int", |
| | 5000 | [CIntTypeLong] = "long", |
| | 5001 | [CIntTypeULong] = "unsigned long", |
| | 5002 | [CIntTypeLongLong] = "long long", |
| | 5003 | [CIntTypeULongLong] = "unsigned long long", |
| | 5004 | }; |
| | 5005 | |
| | 5006 | static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { |
| 4998 | assert(type_entry); | 5007 | assert(type_entry); |
| 4999 | | 5008 | |
| 5000 | if (type_entry == g->builtin_types.entry_u8) { | 5009 | for (int i = 0; i < array_length(c_int_type_names); i += 1) { |
| 5001 | g->c_stdint_used = true; | 5010 | if (type_entry == g->builtin_types.entry_c_int[i]) { |
| 5002 | buf_init_from_str(out_buf, "uint8_t"); | 5011 | buf_init_from_str(out_buf, c_int_type_names[i]); |
| 5003 | } else if (type_entry == g->builtin_types.entry_i32) { | 5012 | return; |
| 5004 | g->c_stdint_used = true; | 5013 | } |
| 5005 | buf_init_from_str(out_buf, "int32_t"); | 5014 | } |
| 5006 | } else if (type_entry == g->builtin_types.entry_isize) { | 5015 | if (type_entry == g->builtin_types.entry_c_long_double) { |
| 5007 | g->c_stdint_used = true; | 5016 | buf_init_from_str(out_buf, "long double"); |
| 5008 | buf_init_from_str(out_buf, "intptr_t"); | 5017 | return; |
| 5009 | } else if (type_entry == g->builtin_types.entry_f32) { | 5018 | } |
| 5010 | buf_init_from_str(out_buf, "float"); | 5019 | if (type_entry == g->builtin_types.entry_c_void) { |
| 5011 | } else if (type_entry == g->builtin_types.entry_unreachable) { | | |
| 5012 | buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); | | |
| 5013 | } else if (type_entry == g->builtin_types.entry_bool) { | | |
| 5014 | buf_init_from_str(out_buf, "unsigned char"); | | |
| 5015 | } else if (type_entry == g->builtin_types.entry_void) { | | |
| 5016 | buf_init_from_str(out_buf, "void"); | 5020 | buf_init_from_str(out_buf, "void"); |
| 5017 | } else { | 5021 | return; |
| 5018 | zig_panic("TODO to_c_type"); | 5022 | } |
| | 5023 | if (type_entry == g->builtin_types.entry_isize) { |
| | 5024 | g->c_want_stdint = true; |
| | 5025 | buf_init_from_str(out_buf, "intptr_t"); |
| | 5026 | return; |
| 5019 | } | 5027 | } |
| | 5028 | if (type_entry == g->builtin_types.entry_usize) { |
| | 5029 | g->c_want_stdint = true; |
| | 5030 | buf_init_from_str(out_buf, "uintptr_t"); |
| | 5031 | return; |
| | 5032 | } |
| | 5033 | |
| | 5034 | switch (type_entry->id) { |
| | 5035 | case TypeTableEntryIdVoid: |
| | 5036 | buf_init_from_str(out_buf, "void"); |
| | 5037 | break; |
| | 5038 | case TypeTableEntryIdBool: |
| | 5039 | buf_init_from_str(out_buf, "bool"); |
| | 5040 | g->c_want_stdbool = true; |
| | 5041 | break; |
| | 5042 | case TypeTableEntryIdUnreachable: |
| | 5043 | buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); |
| | 5044 | break; |
| | 5045 | case TypeTableEntryIdFloat: |
| | 5046 | switch (type_entry->data.floating.bit_count) { |
| | 5047 | case 32: |
| | 5048 | buf_init_from_str(out_buf, "float"); |
| | 5049 | break; |
| | 5050 | case 64: |
| | 5051 | buf_init_from_str(out_buf, "double"); |
| | 5052 | break; |
| | 5053 | default: |
| | 5054 | zig_unreachable(); |
| | 5055 | } |
| | 5056 | break; |
| | 5057 | case TypeTableEntryIdInt: |
| | 5058 | g->c_want_stdint = true; |
| | 5059 | buf_resize(out_buf, 0); |
| | 5060 | buf_appendf(out_buf, "%sint%d_t", |
| | 5061 | type_entry->data.integral.is_signed ? "" : "u", |
| | 5062 | type_entry->data.integral.bit_count); |
| | 5063 | break; |
| | 5064 | case TypeTableEntryIdPointer: |
| | 5065 | { |
| | 5066 | Buf child_buf = BUF_INIT; |
| | 5067 | TypeTableEntry *child_type = type_entry->data.pointer.child_type; |
| | 5068 | get_c_type(g, child_type, &child_buf); |
| | 5069 | |
| | 5070 | const char *const_str = type_entry->data.pointer.is_const ? "const " : ""; |
| | 5071 | buf_resize(out_buf, 0); |
| | 5072 | buf_appendf(out_buf, "%s*%s", const_str, buf_ptr(&child_buf)); |
| | 5073 | break; |
| | 5074 | } |
| | 5075 | case TypeTableEntryIdArray: |
| | 5076 | case TypeTableEntryIdStruct: |
| | 5077 | case TypeTableEntryIdMaybe: |
| | 5078 | case TypeTableEntryIdErrorUnion: |
| | 5079 | case TypeTableEntryIdPureError: |
| | 5080 | case TypeTableEntryIdEnum: |
| | 5081 | case TypeTableEntryIdUnion: |
| | 5082 | case TypeTableEntryIdFn: |
| | 5083 | case TypeTableEntryIdTypeDecl: |
| | 5084 | zig_panic("TODO"); |
| | 5085 | case TypeTableEntryIdInvalid: |
| | 5086 | case TypeTableEntryIdMetaType: |
| | 5087 | case TypeTableEntryIdGenericFn: |
| | 5088 | case TypeTableEntryIdNamespace: |
| | 5089 | case TypeTableEntryIdNumLitFloat: |
| | 5090 | case TypeTableEntryIdNumLitInt: |
| | 5091 | case TypeTableEntryIdUndefLit: |
| | 5092 | case TypeTableEntryIdNullLit: |
| | 5093 | zig_unreachable(); |
| | 5094 | } |
| | 5095 | } |
| | 5096 | |
| | 5097 | static void get_c_type_node(CodeGen *g, AstNode *type_node, Buf *out_buf) { |
| | 5098 | assert(type_node->type != NodeTypeSymbol || !type_node->data.symbol_expr.override_type_entry); |
| | 5099 | |
| | 5100 | Expr *expr = get_resolved_expr(type_node); |
| | 5101 | assert(expr->type_entry); |
| | 5102 | assert(expr->type_entry->id == TypeTableEntryIdMetaType); |
| | 5103 | |
| | 5104 | ConstExprValue *const_val = &expr->const_val; |
| | 5105 | assert(const_val->ok); |
| | 5106 | |
| | 5107 | TypeTableEntry *type_entry = const_val->data.x_type; |
| | 5108 | |
| | 5109 | return get_c_type(g, type_entry, out_buf); |
| 5020 | } | 5110 | } |
| 5021 | | 5111 | |
| 5022 | void codegen_generate_h_file(CodeGen *g) { | 5112 | void codegen_generate_h_file(CodeGen *g) { |
| ... | @@ -5045,7 +5135,7 @@ void codegen_generate_h_file(CodeGen *g) { | ... | @@ -5045,7 +5135,7 @@ void codegen_generate_h_file(CodeGen *g) { |
| 5045 | continue; | 5135 | continue; |
| 5046 | | 5136 | |
| 5047 | Buf return_type_c = BUF_INIT; | 5137 | Buf return_type_c = BUF_INIT; |
| 5048 | to_c_type(g, fn_proto->return_type, &return_type_c); | 5138 | get_c_type_node(g, fn_proto->return_type, &return_type_c); |
| 5049 | | 5139 | |
| 5050 | buf_appendf(&h_buf, "%s %s %s(", | 5140 | buf_appendf(&h_buf, "%s %s %s(", |
| 5051 | buf_ptr(export_macro), | 5141 | buf_ptr(export_macro), |
| ... | @@ -5057,7 +5147,7 @@ void codegen_generate_h_file(CodeGen *g) { | ... | @@ -5057,7 +5147,7 @@ void codegen_generate_h_file(CodeGen *g) { |
| 5057 | for (int param_i = 0; param_i < fn_proto->params.length; param_i += 1) { | 5147 | for (int param_i = 0; param_i < fn_proto->params.length; param_i += 1) { |
| 5058 | AstNode *param_decl_node = fn_proto->params.at(param_i); | 5148 | AstNode *param_decl_node = fn_proto->params.at(param_i); |
| 5059 | AstNode *param_type = param_decl_node->data.param_decl.type; | 5149 | AstNode *param_type = param_decl_node->data.param_decl.type; |
| 5060 | to_c_type(g, param_type, &param_type_c); | 5150 | get_c_type_node(g, param_type, &param_type_c); |
| 5061 | buf_appendf(&h_buf, "%s %s", | 5151 | buf_appendf(&h_buf, "%s %s", |
| 5062 | buf_ptr(&param_type_c), | 5152 | buf_ptr(&param_type_c), |
| 5063 | buf_ptr(param_decl_node->data.param_decl.name)); | 5153 | buf_ptr(param_decl_node->data.param_decl.name)); |
| ... | @@ -5080,7 +5170,9 @@ void codegen_generate_h_file(CodeGen *g) { | ... | @@ -5080,7 +5170,9 @@ void codegen_generate_h_file(CodeGen *g) { |
| 5080 | fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); | 5170 | fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); |
| 5081 | fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name)); | 5171 | fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name)); |
| 5082 | | 5172 | |
| 5083 | if (g->c_stdint_used) | 5173 | if (g->c_want_stdbool) |
| | 5174 | fprintf(out_h, "#include <stdbool.h>\n"); |
| | 5175 | if (g->c_want_stdint) |
| 5084 | fprintf(out_h, "#include <stdint.h>\n"); | 5176 | fprintf(out_h, "#include <stdint.h>\n"); |
| 5085 | | 5177 | |
| 5086 | fprintf(out_h, "\n"); | 5178 | fprintf(out_h, "\n"); |