aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp104
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) {