diff options
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 104 |
1 files changed, 43 insertions, 61 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index e71369eac9..bc9789fca8 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -100,7 +100,7 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope } ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) { - assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); + assert(node == nullptr || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); ScopeDecls *scope = allocate<ScopeDecls>(1); init_scope(g, &scope->base, ScopeIdDecls, node, parent); scope->decl_table.init(4); @@ -181,7 +181,6 @@ ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn * } Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) { - assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr); ScopeCompTime *scope = allocate<ScopeCompTime>(1); init_scope(g, &scope->base, ScopeIdCompTime, node, parent); return &scope->base; @@ -367,23 +366,6 @@ uint64_t type_size_bits(CodeGen *g, ZigType *type_entry) { return LLVMSizeOfTypeInBits(g->target_data_ref, type_entry->type_ref); } -Result<bool> type_is_copyable(CodeGen *g, ZigType *type_entry) { - Error err; - if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) - return err; - - if (!type_has_bits(type_entry)) - return true; - - if (!handle_is_ptr(type_entry)) - return true; - - if ((err = ensure_complete_type(g, type_entry))) - return err; - - return type_entry->is_copyable; -} - static bool is_slice(ZigType *type) { return type->id == ZigTypeIdStruct && type->data.structure.is_slice; } @@ -465,7 +447,6 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons assert(type_is_resolved(child_type, ResolveStatusZeroBitsKnown)); ZigType *entry = new_type_table_entry(ZigTypeIdPointer); - entry->is_copyable = true; const char *star_str = ptr_len == PtrLenSingle ? "*" : "[*]"; const char *const_str = is_const ? "const " : ""; @@ -581,7 +562,6 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) { ZigType *entry = new_type_table_entry(ZigTypeIdOptional); assert(child_type->type_ref || child_type->zero_bits); - entry->is_copyable = type_is_copyable(g, child_type).unwrap(); buf_resize(&entry->name, 0); buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); @@ -671,7 +651,6 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa } ZigType *entry = new_type_table_entry(ZigTypeIdErrorUnion); - entry->is_copyable = true; assert(payload_type->di_type); assert(type_is_complete(payload_type)); @@ -766,7 +745,6 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size) { ZigType *entry = new_type_table_entry(ZigTypeIdArray); entry->zero_bits = (array_size == 0) || child_type->zero_bits; - entry->is_copyable = false; buf_resize(&entry->name, 0); buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name)); @@ -831,7 +809,6 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { } ZigType *entry = new_type_table_entry(ZigTypeIdStruct); - entry->is_copyable = true; // replace the & with [] to go from a ptr type name to a slice type name buf_resize(&entry->name, 0); @@ -986,7 +963,6 @@ ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const c ImportTableEntry *import = scope ? get_scope_import(scope) : nullptr; unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0; - entry->is_copyable = false; entry->type_ref = LLVMInt8Type(); entry->di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder, ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), @@ -1005,7 +981,6 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) { return fn_type->data.fn.bound_fn_parent; ZigType *bound_fn_type = new_type_table_entry(ZigTypeIdBoundFn); - bound_fn_type->is_copyable = false; bound_fn_type->data.bound_fn.fn_type = fn_type; bound_fn_type->zero_bits = true; @@ -1105,7 +1080,6 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { } ZigType *fn_type = new_type_table_entry(ZigTypeIdFn); - fn_type->is_copyable = true; fn_type->data.fn.fn_type_id = *fn_type_id; bool skip_debug_info = false; @@ -1318,7 +1292,6 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { ZigType *fn_type = new_type_table_entry(ZigTypeIdFn); - fn_type->is_copyable = false; buf_resize(&fn_type->name, 0); if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) { const char *async_allocator_type_str = (fn_type->data.fn.fn_type_id.async_allocator_type == nullptr) ? @@ -1526,7 +1499,6 @@ ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry) { ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); buf_resize(&err_set_type->name, 0); buf_appendf(&err_set_type->name, "@typeOf(%s).ReturnType.ErrorSet", buf_ptr(&fn_entry->symbol_name)); - err_set_type->is_copyable = true; err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref; err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type; err_set_type->data.error_set.err_count = 0; @@ -2846,7 +2818,6 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { tag_type = new_type_table_entry(ZigTypeIdEnum); buf_resize(&tag_type->name, 0); buf_appendf(&tag_type->name, "@TagType(%s)", buf_ptr(&union_type->name)); - tag_type->is_copyable = true; tag_type->type_ref = tag_int_type->type_ref; tag_type->zero_bits = tag_int_type->zero_bits; @@ -3366,10 +3337,10 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { } { - ZigType *type = get_primitive_type(g, tld->name); - if (type != nullptr) { + ZigType *type; + if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) { add_node_error(g, tld->source_node, - buf_sprintf("declaration shadows type '%s'", buf_ptr(&type->name))); + buf_sprintf("declaration shadows primitive type '%s'", buf_ptr(tld->name))); } } } @@ -3428,9 +3399,9 @@ void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { switch (node->type) { - case NodeTypeRoot: - for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) { - AstNode *child = node->data.root.top_level_decls.at(i); + case NodeTypeContainerDecl: + for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { + AstNode *child = node->data.container_decl.decls.at(i); scan_decls(g, decls_scope, child); } break; @@ -3477,7 +3448,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { case NodeTypeCompTime: preview_comptime_decl(g, node, decls_scope); break; - case NodeTypeContainerDecl: case NodeTypeParamDecl: case NodeTypeReturnExpr: case NodeTypeDefer: @@ -3613,10 +3583,10 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); variable_entry->value->type = g->builtin_types.entry_invalid; } else { - ZigType *type = get_primitive_type(g, name); - if (type != nullptr) { + ZigType *type; + if (get_primitive_type(g, name, &type) != ErrorPrimitiveTypeNotFound) { add_node_error(g, source_node, - buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); + buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); variable_entry->value->type = g->builtin_types.entry_invalid; } else { Scope *search_scope = nullptr; @@ -4366,9 +4336,9 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r import_entry->decls_scope = create_decls_scope(g, import_entry->root, nullptr, nullptr, import_entry); - assert(import_entry->root->type == NodeTypeRoot); - for (size_t decl_i = 0; decl_i < import_entry->root->data.root.top_level_decls.length; decl_i += 1) { - AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i); + assert(import_entry->root->type == NodeTypeContainerDecl); + for (size_t decl_i = 0; decl_i < import_entry->root->data.container_decl.decls.length; decl_i += 1) { + AstNode *top_level_decl = import_entry->root->data.container_decl.decls.at(decl_i); if (top_level_decl->type == NodeTypeFnDef) { AstNode *proto_node = top_level_decl->data.fn_def.fn_proto; @@ -4435,6 +4405,7 @@ void semantic_analyze(CodeGen *g) { } ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { + assert(size_in_bits <= 65535); TypeId type_id = {}; type_id.id = ZigTypeIdInt; type_id.data.integer.is_signed = is_signed; @@ -4515,7 +4486,7 @@ static ZigWindowsSDK *get_windows_sdk(CodeGen *g) { } -Buf *get_linux_libc_lib_path(const char *o_file) { +static Buf *get_linux_libc_lib_path(const char *o_file) { const char *cc_exe = getenv("CC"); cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; ZigList<const char *> args = {}; @@ -4523,7 +4494,7 @@ Buf *get_linux_libc_lib_path(const char *o_file) { Termination term; Buf *out_stderr = buf_alloc(); Buf *out_stdout = buf_alloc(); - int err; + Error err; if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { zig_panic("unable to determine libc lib path: executing C compiler: %s", err_str(err)); } @@ -4541,7 +4512,7 @@ Buf *get_linux_libc_lib_path(const char *o_file) { return result; } -Buf *get_linux_libc_include_path(void) { +static Buf *get_posix_libc_include_path(void) { const char *cc_exe = getenv("CC"); cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; ZigList<const char *> args = {}; @@ -4552,7 +4523,7 @@ Buf *get_linux_libc_include_path(void) { Termination term; Buf *out_stderr = buf_alloc(); Buf *out_stdout = buf_alloc(); - int err; + Error err; if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { zig_panic("unable to determine libc include path: executing C compiler: %s", err_str(err)); } @@ -4596,6 +4567,10 @@ Buf *get_linux_libc_include_path(void) { void find_libc_include_path(CodeGen *g) { if (g->libc_include_dir == nullptr) { + if (!g->is_native_target) { + fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); + exit(1); + } if (g->zig_target.os == OsWindows) { ZigWindowsSDK *sdk = get_windows_sdk(g); @@ -4604,13 +4579,13 @@ void find_libc_include_path(CodeGen *g) { fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); exit(1); } - } else if (g->zig_target.os == OsLinux) { - g->libc_include_dir = get_linux_libc_include_path(); - } else if (g->zig_target.os == OsMacOSX) { - g->libc_include_dir = buf_create_from_str("/usr/include"); + } else if (g->zig_target.os == OsLinux || g->zig_target.os == OsMacOSX) { + g->libc_include_dir = get_posix_libc_include_path(); } else { - // TODO find libc at runtime for other operating systems - zig_panic("Unable to determine libc include path."); + fprintf(stderr, "Unable to determine libc include path.\n" + "TODO: implement finding libc at runtime for other operating systems.\n" + "in the meantime, you can use as a workaround: --libc-include-dir\n"); + exit(1); } } assert(buf_len(g->libc_include_dir) != 0); @@ -5977,8 +5952,8 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { } ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { + assert(size_in_bits <= 65535); ZigType *entry = new_type_table_entry(ZigTypeIdInt); - entry->is_copyable = true; entry->type_ref = (size_in_bits == 0) ? LLVMVoidType() : LLVMIntType(size_in_bits); entry->zero_bits = (size_in_bits == 0); @@ -6455,7 +6430,10 @@ bool fn_type_can_fail(FnTypeId *fn_type_id) { return type_can_fail(fn_type_id->return_type) || fn_type_id->cc == CallingConventionAsync; } -ZigType *get_primitive_type(CodeGen *g, Buf *name) { +// ErrorNone - result pointer has the type +// ErrorOverflow - an integer primitive type has too large a bit width +// ErrorPrimitiveTypeNotFound - result pointer unchanged +Error get_primitive_type(CodeGen *g, Buf *name, ZigType **result) { if (buf_len(name) >= 2) { uint8_t first_c = buf_ptr(name)[0]; if (first_c == 'i' || first_c == 'u') { @@ -6466,18 +6444,22 @@ ZigType *get_primitive_type(CodeGen *g, Buf *name) { } } bool is_signed = (first_c == 'i'); - uint32_t bit_count = atoi(buf_ptr(name) + 1); - return get_int_type(g, is_signed, bit_count); + unsigned long int bit_count = strtoul(buf_ptr(name) + 1, nullptr, 10); + // strtoul returns ULONG_MAX on errors, so this comparison catches that as well. + if (bit_count >= 65536) return ErrorOverflow; + *result = get_int_type(g, is_signed, bit_count); + return ErrorNone; } } not_integer: auto primitive_table_entry = g->primitive_type_table.maybe_get(name); - if (primitive_table_entry != nullptr) { - return primitive_table_entry->value; - } - return nullptr; + if (primitive_table_entry == nullptr) + return ErrorPrimitiveTypeNotFound; + + *result = primitive_table_entry->value; + return ErrorNone; } Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) { |
