diff --git a/src/check_decl.cpp b/src/check_decl.cpp index cf3cb8e97..d87e6def0 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -791,7 +791,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } } -void check_var_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_expr) { +void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_expr) { GB_ASSERT(e->type == nullptr); GB_ASSERT(e->kind == Entity_Variable); @@ -805,6 +805,7 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_ex ac.init_expr_list_count = init_expr != nullptr ? 1 : 0; DeclInfo *decl = decl_info_of_entity(e); + GB_ASSERT(decl == ctx->decl); if (decl != nullptr) { check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac); } @@ -1051,7 +1052,7 @@ void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_ switch (e->kind) { case Entity_Variable: - check_var_decl(&c, e, d->type_expr, d->init_expr); + check_global_variable_decl(&c, e, d->type_expr, d->init_expr); break; case Entity_Constant: check_const_decl(&c, e, d->type_expr, d->init_expr, named_type); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 88661558d..6945fb00e 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1735,7 +1735,12 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { } for (isize i = 0; i < entity_count; i++) { - add_entity(ctx->checker, ctx->scope, entities[i]->identifier, entities[i]); + Entity *e = entities[i]; + DeclInfo *d = decl_info_of_entity(e); + GB_ASSERT(d == nullptr); + add_entity(ctx->checker, ctx->scope, e->identifier, e); + d = make_decl_info(ctx->allocator, ctx->scope, ctx->decl); + add_entity_and_decl_info(ctx, e->identifier, e, d); } check_stmt(ctx, rs->body, new_flags); diff --git a/src/checker.cpp b/src/checker.cpp index d6f5ad402..fc8cb5c63 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -85,9 +85,13 @@ int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { EntityGraphNode *y = data[j]; isize a = x->entity->order_in_src; isize b = y->entity->order_in_src; - if (x->dep_count < y->dep_count) return -1; - if (x->dep_count > y->dep_count) return +1; - return a < b ? -1 : b > a; + if (x->dep_count < y->dep_count) { + return -1; + } + if (x->dep_count == y->dep_count) { + return a < b ? -1 : b > a; + } + return +1; } void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { @@ -1164,6 +1168,7 @@ void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, Dec add_entity_definition(&c->checker->info, identifier, e); GB_ASSERT(e->decl_info == nullptr); e->decl_info = d; + d->entity = e; array_add(&c->checker->info.entities, e); e->order_in_src = c->checker->info.entities.count; e->pkg = c->pkg; @@ -1602,6 +1607,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("args__"), str_lit("type_table"), + str_lit("__type_info_of"), str_lit("global_scratch_allocator"), str_lit("Type_Info"), @@ -1688,9 +1694,10 @@ bool is_entity_a_dependency(Entity *e) { if (e == nullptr) return false; switch (e->kind) { case Entity_Procedure: - case Entity_Variable: - case Entity_Constant: return true; + case Entity_Constant: + case Entity_Variable: + return e->pkg != nullptr; } return false; } @@ -1717,18 +1724,17 @@ Array generate_entity_dependency_graph(CheckerInfo *info) { EntityGraphNode *n = M.entries[i].value; DeclInfo *decl = decl_info_of_entity(e); - if (decl != nullptr) { - for_array(j, decl->deps.entries) { - auto entry = decl->deps.entries[j]; - Entity *dep = entry.ptr; - if (dep && is_entity_a_dependency(dep)) { - EntityGraphNode **m_ = map_get(&M, hash_pointer(dep)); - if (m_ != nullptr) { - EntityGraphNode *m = *m_; - entity_graph_node_set_add(&n->succ, m); - entity_graph_node_set_add(&m->pred, n); - } - } + GB_ASSERT(decl != nullptr); + + for_array(j, decl->deps.entries) { + Entity *dep = decl->deps.entries[j].ptr; + GB_ASSERT(dep != nullptr); + if (is_entity_a_dependency(dep)) { + EntityGraphNode **m_ = map_get(&M, hash_pointer(dep)); + GB_ASSERT(m_ != nullptr); + EntityGraphNode *m = *m_; + entity_graph_node_set_add(&n->succ, m); + entity_graph_node_set_add(&m->pred, n); } } } @@ -2562,6 +2568,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Ast *init_expr = value; DeclInfo *d = make_decl_info(heap_allocator(), c->scope, c->decl); + d->entity = e; d->type_expr = vd->type; d->init_expr = init_expr; d->attributes = vd->attributes; @@ -3576,7 +3583,6 @@ void calculate_global_init_order(Checker *c) { #define TIME_SECTION(str) #endif - CheckerInfo *info = &c->info; TIME_SECTION("generate entity dependency graph"); @@ -3618,21 +3624,26 @@ void calculate_global_init_order(Checker *c) { for_array(i, n->pred.entries) { EntityGraphNode *p = n->pred.entries[i].ptr; - p->dep_count -= gb_max(p->dep_count-1, 0); + p->dep_count -= 1; + p->dep_count = gb_max(p->dep_count, 0); priority_queue_fix(&pq, p->index); } - if (e == nullptr || e->kind != Entity_Variable) { + DeclInfo *d = decl_info_of_entity(e); + if (e->kind != Entity_Variable) { continue; } - DeclInfo *d = decl_info_of_entity(e); - + // IMPORTANT NOTE(bill, 2019-08-29): Just add it regardless of the ordering + // because it does not need any initialization other than zero + // if (!decl_info_has_init(d)) { + // continue; + // } if (ptr_set_exists(&emitted, d)) { continue; } ptr_set_add(&emitted, d); - d->entity = e; + array_add(&info->variable_init_order, d); } diff --git a/src/ir.cpp b/src/ir.cpp index 62519c259..26f787976 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2226,18 +2226,9 @@ irDebugInfo *ir_add_debug_info_type_complex(irModule *module, Type *type) { Type *field_type = base_complex_elem_type(type); - // Field "real" - irDebugInfo *real_di = ir_add_debug_info_field_internal(module, str_lit("real"), field_type, - 0, - nullptr, - di); + irDebugInfo *real_di = ir_add_debug_info_field_internal(module, str_lit("real"), field_type, 0*cast(i32)type_size_of(field_type), nullptr, di); + irDebugInfo *imag_di = ir_add_debug_info_field_internal(module, str_lit("imag"), field_type, 1*cast(i32)type_size_of(field_type), nullptr, di); map_set(&module->debug_info, hash_pointer(real_di), real_di); - - // Field "imag" - irDebugInfo *imag_di = ir_add_debug_info_field_internal(module, str_lit("imag"), field_type, - real_di->DerivedType.size, - nullptr, - di); map_set(&module->debug_info, hash_pointer(imag_di), imag_di); irDebugInfo *elements_di = ir_add_debug_info_array(module, 0, 2); diff --git a/src/priority_queue.cpp b/src/priority_queue.cpp index 7c36e6a22..aee2061b5 100644 --- a/src/priority_queue.cpp +++ b/src/priority_queue.cpp @@ -20,7 +20,7 @@ bool priority_queue_shift_down(PriorityQueue *pq, isize i0, isize n) { if (j2 < n && pq->cmp(&pq->queue[0], j2, j1) < 0) { j = j2; } - if (pq->cmp(&pq->queue[0], i, j) < 0) break; + if (pq->cmp(&pq->queue[0], j, i) >= 0) break; pq->swap(&pq->queue[0], i, j); i = j; @@ -32,7 +32,7 @@ template void priority_queue_shift_up(PriorityQueue *pq, isize j) { while (0 <= j && j < pq->queue.count) { isize i = (j-1)/2; - if (i == j || pq->cmp(&pq->queue[0], i, j) < 0) { + if (i == j || pq->cmp(&pq->queue[0], j, i) >= 0) { break; } pq->swap(&pq->queue[0], i, j);