| author | |
| committer | |
| log | b04e64d300b8531c0e84c376d484a62aa9f92614 |
| tree | f44c70585a172d6e4a6ed2ec4368d1e7fe012c1b |
| parent | a50474e7cfc97e404fbb9f3b2f33507afac0ae2b |
4 files changed, 55 insertions(+), 1 deletions(-)
src/all_types.hpp+2| ... | @@ -998,6 +998,7 @@ enum BuiltinFnId { | ... | @@ -998,6 +998,7 @@ enum BuiltinFnId { |
| 998 | BuiltinFnIdCInclude, | 998 | BuiltinFnIdCInclude, |
| 999 | BuiltinFnIdCDefine, | 999 | BuiltinFnIdCDefine, |
| 1000 | BuiltinFnIdCUndef, | 1000 | BuiltinFnIdCUndef, |
| 1001 | BuiltinFnIdCompileVar, | ||
| 1001 | }; | 1002 | }; |
| 1002 | 1003 | ||
| 1003 | struct BuiltinFnEntry { | 1004 | struct BuiltinFnEntry { |
| ... | @@ -1058,6 +1059,7 @@ struct CodeGen { | ... | @@ -1058,6 +1059,7 @@ struct CodeGen { |
| 1058 | 1059 | ||
| 1059 | LLVMTargetDataRef target_data_ref; | 1060 | LLVMTargetDataRef target_data_ref; |
| 1060 | unsigned pointer_size_bytes; | 1061 | unsigned pointer_size_bytes; |
| 1062 | bool is_big_endian; | ||
| 1061 | bool is_static; | 1063 | bool is_static; |
| 1062 | bool strip_debug_symbols; | 1064 | bool strip_debug_symbols; |
| 1063 | bool have_exported_main; | 1065 | bool have_exported_main; |
src/analyze.cpp+45-1| ... | @@ -3896,7 +3896,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -3896,7 +3896,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3896 | uint64_t big_c = char_val->data.x_bignum.data.x_uint; | 3896 | uint64_t big_c = char_val->data.x_bignum.data.x_uint; |
| 3897 | assert(big_c <= UINT8_MAX); | 3897 | assert(big_c <= UINT8_MAX); |
| 3898 | uint8_t c = big_c; | 3898 | uint8_t c = big_c; |
| 3899 | buf_appendf(context->c_import_buf, "%c", c); | 3899 | buf_append_char(context->c_import_buf, c); |
| 3900 | } | 3900 | } |
| 3901 | buf_appendf(context->c_import_buf, ">\n"); | 3901 | buf_appendf(context->c_import_buf, ">\n"); |
| 3902 | 3902 | ||
| ... | @@ -3907,6 +3907,50 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -3907,6 +3907,50 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3907 | case BuiltinFnIdCUndef: | 3907 | case BuiltinFnIdCUndef: |
| 3908 | zig_panic("TODO"); | 3908 | zig_panic("TODO"); |
| 3909 | 3909 | ||
| 3910 | case BuiltinFnIdCompileVar: | ||
| 3911 | { | ||
| 3912 | AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field; | ||
| 3913 | |||
| 3914 | TypeTableEntry *str_type = get_unknown_size_array_type(g, g->builtin_types.entry_u8, true); | ||
| 3915 | TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node); | ||
| 3916 | |||
| 3917 | if (resolved_type->id == TypeTableEntryIdInvalid) { | ||
| 3918 | return resolved_type; | ||
| 3919 | } | ||
| 3920 | |||
| 3921 | ConstExprValue *const_str_val = &get_resolved_expr(*str_node)->const_val; | ||
| 3922 | |||
| 3923 | if (!const_str_val->ok) { | ||
| 3924 | add_node_error(g, *str_node, buf_sprintf("@compile_var requires constant expression")); | ||
| 3925 | return g->builtin_types.entry_void; | ||
| 3926 | } | ||
| 3927 | |||
| 3928 | ConstExprValue *ptr_field = const_str_val->data.x_struct.fields[0]; | ||
| 3929 | uint64_t len = ptr_field->data.x_ptr.len; | ||
| 3930 | Buf var_name = BUF_INIT; | ||
| 3931 | buf_resize(&var_name, 0); | ||
| 3932 | for (uint64_t i = 0; i < len; i += 1) { | ||
| 3933 | ConstExprValue *char_val = ptr_field->data.x_ptr.ptr[i]; | ||
| 3934 | uint64_t big_c = char_val->data.x_bignum.data.x_uint; | ||
| 3935 | assert(big_c <= UINT8_MAX); | ||
| 3936 | uint8_t c = big_c; | ||
| 3937 | buf_append_char(&var_name, c); | ||
| 3938 | } | ||
| 3939 | |||
| 3940 | ConstExprValue *const_val = &get_resolved_expr(node)->const_val; | ||
| 3941 | const_val->depends_on_compile_var = true; | ||
| 3942 | |||
| 3943 | if (buf_eql_str(&var_name, "is_big_endian")) { | ||
| 3944 | return resolve_expr_const_val_as_bool(g, node, g->is_big_endian); | ||
| 3945 | } else { | ||
| 3946 | add_node_error(g, *str_node, | ||
| 3947 | buf_sprintf("unrecognized compile variable: '%s'", buf_ptr(&var_name))); | ||
| 3948 | return g->builtin_types.entry_invalid; | ||
| 3949 | } | ||
| 3950 | |||
| 3951 | break; | ||
| 3952 | } | ||
| 3953 | |||
| 3910 | } | 3954 | } |
| 3911 | zig_unreachable(); | 3955 | zig_unreachable(); |
| 3912 | } | 3956 | } |
src/codegen.cpp+3| ... | @@ -304,6 +304,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -304,6 +304,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 304 | case BuiltinFnIdMinValue: | 304 | case BuiltinFnIdMinValue: |
| 305 | case BuiltinFnIdMaxValue: | 305 | case BuiltinFnIdMaxValue: |
| 306 | case BuiltinFnIdMemberCount: | 306 | case BuiltinFnIdMemberCount: |
| 307 | case BuiltinFnIdCompileVar: | ||
| 307 | // caught by constant expression eval codegen | 308 | // caught by constant expression eval codegen |
| 308 | zig_unreachable(); | 309 | zig_unreachable(); |
| 309 | } | 310 | } |
| ... | @@ -3221,6 +3222,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -3221,6 +3222,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 3221 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCInclude, "c_include", 1); | 3222 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCInclude, "c_include", 1); |
| 3222 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2); | 3223 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2); |
| 3223 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1); | 3224 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1); |
| 3225 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileVar, "compile_var", 1); | ||
| 3224 | } | 3226 | } |
| 3225 | 3227 | ||
| 3226 | 3228 | ||
| ... | @@ -3267,6 +3269,7 @@ static void init(CodeGen *g, Buf *source_path) { | ... | @@ -3267,6 +3269,7 @@ static void init(CodeGen *g, Buf *source_path) { |
| 3267 | 3269 | ||
| 3268 | 3270 | ||
| 3269 | g->pointer_size_bytes = LLVMPointerSize(g->target_data_ref); | 3271 | g->pointer_size_bytes = LLVMPointerSize(g->target_data_ref); |
| 3272 | g->is_big_endian = (LLVMByteOrder(g->target_data_ref) == LLVMBigEndian); | ||
| 3270 | 3273 | ||
| 3271 | g->builder = LLVMCreateBuilder(); | 3274 | g->builder = LLVMCreateBuilder(); |
| 3272 | g->dbuilder = LLVMZigCreateDIBuilder(g->module, true); | 3275 | g->dbuilder = LLVMZigCreateDIBuilder(g->module, true); |
test/run_tests.cpp+5| ... | @@ -2033,6 +2033,11 @@ fn func() -> bogus {} | ... | @@ -2033,6 +2033,11 @@ fn func() -> bogus {} |
| 2033 | )SOURCE", 2, | 2033 | )SOURCE", 2, |
| 2034 | ".tmp_source.zig:3:1: error: redefinition of 'func'", | 2034 | ".tmp_source.zig:3:1: error: redefinition of 'func'", |
| 2035 | ".tmp_source.zig:2:14: error: use of undeclared identifier 'bogus'"); | 2035 | ".tmp_source.zig:2:14: error: use of undeclared identifier 'bogus'"); |
| 2036 | |||
| 2037 | |||
| 2038 | add_compile_fail_case("bogus compile var", R"SOURCE( | ||
| 2039 | const x = @compile_var("bogus"); | ||
| 2040 | )SOURCE", 1, ".tmp_source.zig:2:24: error: unrecognized compile variable: 'bogus'"); | ||
| 2036 | } | 2041 | } |
| 2037 | 2042 | ||
| 2038 | ////////////////////////////////////////////////////////////////////////////// | 2043 | ////////////////////////////////////////////////////////////////////////////// |