| ... | ... | @@ -4992,31 +4992,121 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou |
| 4992 | 4992 | do_code_gen(g); |
| 4993 | 4993 | } |
| 4994 | 4994 | |
| 4995 | | static void to_c_type(CodeGen *g, AstNode *type_node, Buf *out_buf) { |
| 4996 | | zig_panic("TODO this function needs some love"); |
| 4997 | | TypeTableEntry *type_entry = get_resolved_expr(type_node)->type_entry; |
| 4995 | static const char *c_int_type_names[] = { |
| 4996 | [CIntTypeShort] = "short", |
| 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 | 5007 | assert(type_entry); |
| 4999 | 5008 | |
| 5000 | | if (type_entry == g->builtin_types.entry_u8) { |
| 5001 | | g->c_stdint_used = true; |
| 5002 | | buf_init_from_str(out_buf, "uint8_t"); |
| 5003 | | } else if (type_entry == g->builtin_types.entry_i32) { |
| 5004 | | g->c_stdint_used = true; |
| 5005 | | buf_init_from_str(out_buf, "int32_t"); |
| 5006 | | } else if (type_entry == g->builtin_types.entry_isize) { |
| 5007 | | g->c_stdint_used = true; |
| 5008 | | buf_init_from_str(out_buf, "intptr_t"); |
| 5009 | | } else if (type_entry == g->builtin_types.entry_f32) { |
| 5010 | | buf_init_from_str(out_buf, "float"); |
| 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) { |
| 5009 | for (int i = 0; i < array_length(c_int_type_names); i += 1) { |
| 5010 | if (type_entry == g->builtin_types.entry_c_int[i]) { |
| 5011 | buf_init_from_str(out_buf, c_int_type_names[i]); |
| 5012 | return; |
| 5013 | } |
| 5014 | } |
| 5015 | if (type_entry == g->builtin_types.entry_c_long_double) { |
| 5016 | buf_init_from_str(out_buf, "long double"); |
| 5017 | return; |
| 5018 | } |
| 5019 | if (type_entry == g->builtin_types.entry_c_void) { |
| 5016 | 5020 | buf_init_from_str(out_buf, "void"); |
| 5017 | | } else { |
| 5018 | | zig_panic("TODO to_c_type"); |
| 5021 | return; |
| 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 | 5112 | void codegen_generate_h_file(CodeGen *g) { |
| ... | ... | @@ -5045,7 +5135,7 @@ void codegen_generate_h_file(CodeGen *g) { |
| 5045 | 5135 | continue; |
| 5046 | 5136 | |
| 5047 | 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 | 5140 | buf_appendf(&h_buf, "%s %s %s(", |
| 5051 | 5141 | buf_ptr(export_macro), |
| ... | ... | @@ -5057,7 +5147,7 @@ void codegen_generate_h_file(CodeGen *g) { |
| 5057 | 5147 | for (int param_i = 0; param_i < fn_proto->params.length; param_i += 1) { |
| 5058 | 5148 | AstNode *param_decl_node = fn_proto->params.at(param_i); |
| 5059 | 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 | 5151 | buf_appendf(&h_buf, "%s %s", |
| 5062 | 5152 | buf_ptr(&param_type_c), |
| 5063 | 5153 | buf_ptr(param_decl_node->data.param_decl.name)); |
| ... | ... | @@ -5080,7 +5170,9 @@ void codegen_generate_h_file(CodeGen *g) { |
| 5080 | 5170 | fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); |
| 5081 | 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 | 5176 | fprintf(out_h, "#include <stdint.h>\n"); |
| 5085 | 5177 | |
| 5086 | 5178 | fprintf(out_h, "\n"); |