From 31f4590f4b291bd5a21248d2c27ab8630b3e5fd9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 9 Nov 2020 13:04:36 +0000 Subject: Fix default parameters on record types --- src/parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 330d78263..794ff231d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2122,7 +2122,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { if (allow_token(f, Token_OpenParen)) { isize param_count = 0; - polymorphic_params = parse_field_list(f, ¶m_count, 0, Token_CloseParen, false, true); + polymorphic_params = parse_field_list(f, ¶m_count, 0, Token_CloseParen, true, true); if (param_count == 0) { syntax_error(polymorphic_params, "Expected at least 1 polymorphic parameter"); polymorphic_params = nullptr; @@ -2203,7 +2203,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { if (allow_token(f, Token_OpenParen)) { isize param_count = 0; - polymorphic_params = parse_field_list(f, ¶m_count, 0, Token_CloseParen, false, true); + polymorphic_params = parse_field_list(f, ¶m_count, 0, Token_CloseParen, true, true); if (param_count == 0) { syntax_error(polymorphic_params, "Expected at least 1 polymorphic parametric"); polymorphic_params = nullptr; -- cgit v1.2.3 From 3c1c10a1785a97831a69fb6d94356d5cc4989bd6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Nov 2020 18:08:52 +0000 Subject: Begin clarifying allocation patterns by changing from `heap_allocator` to specific arenas --- src/checker.cpp | 4 +- src/checker.hpp | 2 - src/common.cpp | 48 +++++++-- src/entity.cpp | 2 +- src/llvm_abi.cpp | 7 +- src/llvm_backend.cpp | 279 +++++++++++++++++++++------------------------------ src/main.cpp | 16 ++- src/parser.cpp | 43 ++++---- src/parser.hpp | 1 + src/types.cpp | 8 +- 10 files changed, 209 insertions(+), 201 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index fe669ab8c..a07a3ffbe 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -690,8 +690,10 @@ void add_global_type_entity(String name, Type *type) { void init_universal(void) { BuildContext *bc = &build_context; + // NOTE(bill): No need to free these - gbAllocator a = heap_allocator(); + // gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); builtin_pkg = gb_alloc_item(a, AstPackage); builtin_pkg->name = str_lit("builtin"); diff --git a/src/checker.hpp b/src/checker.hpp index 3d21a4cec..88e9451ee 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -337,8 +337,6 @@ struct Checker { - - gb_global AstPackage *builtin_pkg = nullptr; gb_global AstPackage *intrinsics_pkg = nullptr; gb_global AstPackage *config_pkg = nullptr; diff --git a/src/common.cpp b/src/common.cpp index 350127e1e..567655c04 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -373,8 +373,8 @@ typedef struct Arena { gbAllocator backing; isize block_size; gbMutex mutex; - isize total_used; + bool use_mutex; } Arena; #define ARENA_MIN_ALIGNMENT 16 @@ -388,8 +388,9 @@ void arena_init(Arena *arena, gbAllocator backing, isize block_size=ARENA_DEFAUL } void arena_grow(Arena *arena, isize min_size) { - // gb_mutex_lock(&arena->mutex); - // defer (gb_mutex_unlock(&arena->mutex)); + if (arena->use_mutex) { + gb_mutex_lock(&arena->mutex); + } isize size = gb_max(arena->block_size, min_size); size = ALIGN_UP(size, ARENA_MIN_ALIGNMENT); @@ -399,11 +400,16 @@ void arena_grow(Arena *arena, isize min_size) { GB_ASSERT(arena->ptr == ALIGN_DOWN_PTR(arena->ptr, ARENA_MIN_ALIGNMENT)); arena->end = arena->ptr + size; array_add(&arena->blocks, arena->ptr); + + if (arena->use_mutex) { + gb_mutex_unlock(&arena->mutex); + } } void *arena_alloc(Arena *arena, isize size, isize alignment) { - // gb_mutex_lock(&arena->mutex); - // defer (gb_mutex_unlock(&arena->mutex)); + if (arena->use_mutex) { + gb_mutex_lock(&arena->mutex); + } arena->total_used += size; @@ -419,12 +425,17 @@ void *arena_alloc(Arena *arena, isize size, isize alignment) { GB_ASSERT(arena->ptr <= arena->end); GB_ASSERT(ptr == ALIGN_DOWN_PTR(ptr, align)); // zero_size(ptr, size); + + if (arena->use_mutex) { + gb_mutex_unlock(&arena->mutex); + } return ptr; } void arena_free_all(Arena *arena) { - // gb_mutex_lock(&arena->mutex); - // defer (gb_mutex_unlock(&arena->mutex)); + if (arena->use_mutex) { + gb_mutex_lock(&arena->mutex); + } for_array(i, arena->blocks) { gb_free(arena->backing, arena->blocks[i]); @@ -432,6 +443,10 @@ void arena_free_all(Arena *arena) { array_clear(&arena->blocks); arena->ptr = nullptr; arena->end = nullptr; + + if (arena->use_mutex) { + gb_mutex_unlock(&arena->mutex); + } } @@ -460,7 +475,14 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) { // GB_PANIC("gbAllocation_Free not supported"); break; case gbAllocation_Resize: - GB_PANIC("gbAllocation_Resize: not supported"); + if (size == 0) { + ptr = nullptr; + } else if (size <= old_size) { + ptr = old_memory; + } else { + ptr = arena_alloc(arena, size, alignment); + gb_memmove(ptr, old_memory, old_size); + } break; case gbAllocation_FreeAll: arena_free_all(arena); @@ -472,6 +494,16 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) { +gb_global Arena permanent_arena = {}; +gb_global Arena temporary_arena = {}; + +gbAllocator permanent_allocator() { + return arena_allocator(&permanent_arena); +} +gbAllocator temporary_allocator() { + return arena_allocator(&temporary_arena); +} + diff --git a/src/entity.cpp b/src/entity.cpp index a9d598735..708b0862c 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -220,7 +220,7 @@ bool entity_has_deferred_procedure(Entity *e) { gb_global u64 global_entity_id = 0; Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) { - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); Entity *entity = gb_alloc_item(a, Entity); entity->kind = kind; entity->state = EntityState_Unresolved; diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 79f7948a3..f0422e0f8 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -276,6 +276,9 @@ Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, } Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, bool is_packed, bool must_be_tuple) { + if (field_count == 0) { + return nullptr; + } if (!must_be_tuple && field_count == 1) { return field_types[0]; } @@ -297,7 +300,9 @@ Type *alloc_type_proc_from_types(Type **param_types, unsigned param_count, Type Type *params = alloc_type_tuple_from_field_types(param_types, param_count, false, true); isize results_count = 0; if (results != nullptr) { - GB_ASSERT(results->kind == Type_Tuple); + if (results->kind != Type_Tuple) { + results = alloc_type_tuple_from_field_types(&results, 1, false, true); + } results_count = results->Tuple.variables.count; } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1f20c607d..43f4125ba 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -144,7 +144,7 @@ lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) { lbValue h = lb_gen_map_header(p, addr.addr, map_type); lbValue key = lb_gen_map_key(p, addr.map.key, map_type->Map.key); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = h; args[1] = key; @@ -209,7 +209,7 @@ void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue le lbValue line = lb_const_int(p->module, t_int, token.pos.line); lbValue column = lb_const_int(p->module, t_int, token.pos.column); - auto args = array_make(heap_allocator(), 5); + auto args = array_make(permanent_allocator(), 5); args[0] = file; args[1] = line; args[2] = column; @@ -233,7 +233,7 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu high = lb_emit_conv(p, high, t_int); if (!lower_value_used) { - auto args = array_make(heap_allocator(), 5); + auto args = array_make(permanent_allocator(), 5); args[0] = file; args[1] = line; args[2] = column; @@ -245,7 +245,7 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu // No need to convert unless used low = lb_emit_conv(p, low, t_int); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = file; args[1] = line; args[2] = column; @@ -357,7 +357,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { } - auto args = array_make(heap_allocator(), gb_max(arg_count, param_count)); + auto args = array_make(permanent_allocator(), gb_max(arg_count, param_count)); args[0] = ptr; args[1] = index; args[2] = value; @@ -594,7 +594,7 @@ lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { lbValue h = lb_gen_map_header(p, addr.addr, map_type); lbValue key = lb_gen_map_key(p, addr.map.key, map_type->Map.key); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = h; args[1] = key; @@ -773,7 +773,6 @@ void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *varia } void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) { - gbAllocator a = heap_allocator(); lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type)); lb_emit_store(p, underlying, variant); @@ -783,10 +782,9 @@ void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { unsigned field_count = LLVMCountStructElementTypes(src); - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); LLVMGetStructElementTypes(src, fields); LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src)); - gb_free(heap_allocator(), fields); } LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) { @@ -821,8 +819,6 @@ bool lb_is_elem_const(Ast *elem, Type *elem_type) { } String lb_mangle_name(lbModule *m, Entity *e) { - gbAllocator a = heap_allocator(); - String name = e->token.string; AstPackage *pkg = e->pkg; @@ -848,7 +844,7 @@ String lb_mangle_name(lbModule *m, Entity *e) { max_len += 21; } - char *new_name = gb_alloc_array(a, char, max_len); + char *new_name = gb_alloc_array(permanent_allocator(), char, max_len); isize new_name_len = gb_snprintf( new_name, max_len, "%.*s.%.*s", LIT(pkgn), LIT(name) @@ -899,7 +895,7 @@ String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) { if (p != nullptr) { isize name_len = p->name.len + 1 + ts_name.len + 1 + 10 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); u32 guid = ++p->module->nested_type_name_guid; name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%u", LIT(p->name), LIT(ts_name), guid); @@ -909,7 +905,7 @@ String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) { } else { // NOTE(bill): a nested type be required before its parameter procedure exists. Just give it a temp name for now isize name_len = 9 + 1 + ts_name.len + 1 + 10 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); static u32 guid = 0; guid += 1; name_len = gb_snprintf(name_text, name_len, "_internal.%.*s-%u", LIT(ts_name), guid); @@ -1191,7 +1187,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { if (found) { LLVMTypeKind kind = LLVMGetTypeKind(*found); if (kind == LLVMStructTypeKind) { - char const *name = alloc_cstring(heap_allocator(), lb_get_entity_name(m, type->Named.type_name)); + char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name)); LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name); if (llvm_type != nullptr) { return llvm_type; @@ -1208,7 +1204,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_Union: case Type_BitField: { - char const *name = alloc_cstring(heap_allocator(), lb_get_entity_name(m, type->Named.type_name)); + char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name)); LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name); if (llvm_type != nullptr) { return llvm_type; @@ -1265,7 +1261,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { { if (type->Struct.is_raw_union) { unsigned field_count = 2; - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); + LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count); i64 alignment = type_align_of(type); unsigned size_of_union = cast(unsigned)type_size_of(type); fields[0] = lb_alignment_prefix_type_hack(m, alignment); @@ -1282,9 +1278,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { defer (m->internal_type_level -= 1); unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset); - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); GB_ASSERT(fields != nullptr); - defer (gb_free(heap_allocator(), fields)); for_array(i, type->Struct.fields) { Entity *field = type->Struct.fields[i]; @@ -1344,8 +1339,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { return lb_type(m, type->Tuple.variables[0]->type); } else { unsigned field_count = cast(unsigned)(type->Tuple.variables.count); - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); - defer (gb_free(heap_allocator(), fields)); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); for_array(i, type->Tuple.variables) { Entity *field = type->Tuple.variables[i]; @@ -1444,8 +1438,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { } isize param_count = type->Proc.abi_compat_params.count + extra_param_count; - auto param_types = array_make(heap_allocator(), 0, param_count); - defer (array_free(¶m_types)); + auto param_types = array_make(temporary_allocator(), 0, param_count); if (type->Proc.return_by_pointer) { array_add(¶m_types, LLVMPointerType(lb_type(m, type->Proc.abi_compat_result_type), 0)); @@ -1492,8 +1485,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { { GB_ASSERT(type->BitField.fields.count == type->BitField.sizes.count); unsigned field_count = cast(unsigned)type->BitField.fields.count; - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); - defer (gb_free(heap_allocator(), fields)); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); for_array(i, type->BitField.sizes) { u32 size = type->BitField.sizes[i]; @@ -2135,7 +2127,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { } - lbProcedure *p = gb_alloc_item(heap_allocator(), lbProcedure); + lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); p->module = m; entity->code_gen_module = m; @@ -2149,7 +2141,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { Type *pt = base_type(entity->type); GB_ASSERT(pt->kind == Type_Proc); - set_procedure_abi_types(heap_allocator(), entity->type); + set_procedure_abi_types(permanent_allocator(), entity->type); p->type = entity->type; p->type_expr = decl->type_expr; @@ -2172,7 +2164,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library); } - char *c_link_name = alloc_cstring(heap_allocator(), p->name); + char *c_link_name = alloc_cstring(permanent_allocator(), p->name); LLVMTypeRef func_ptr_type = lb_type(m, p->type); LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type); @@ -2209,19 +2201,19 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { LLVMSetVisibility(p->value, LLVMDefaultVisibility); if (build_context.metrics.os == TargetOs_js) { - char const *export_name = alloc_cstring(heap_allocator(), p->name); + char const *export_name = alloc_cstring(permanent_allocator(), p->name); LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name); } } if (p->is_foreign) { if (build_context.metrics.os == TargetOs_js) { - char const *import_name = alloc_cstring(heap_allocator(), p->name); + char const *import_name = alloc_cstring(permanent_allocator(), p->name); char const *module_name = "env"; if (entity->Procedure.foreign_library != nullptr) { Entity *foreign_library = entity->Procedure.foreign_library; GB_ASSERT(foreign_library->kind == Entity_LibraryName); if (foreign_library->LibraryName.paths.count > 0) { - module_name = alloc_cstring(heap_allocator(), foreign_library->LibraryName.paths[0]); + module_name = alloc_cstring(permanent_allocator(), foreign_library->LibraryName.paths[0]); } } LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-name", import_name); @@ -2310,7 +2302,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type GB_ASSERT(found == nullptr); } - lbProcedure *p = gb_alloc_item(heap_allocator(), lbProcedure); + lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); p->module = m; p->name = link_name; @@ -2324,7 +2316,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type p->is_export = false; p->is_entry_point = false; - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); p->children.allocator = a; p->params.allocator = a; p->defer_stmts.allocator = a; @@ -2333,7 +2325,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type p->context_stack.allocator = a; - char *c_link_name = alloc_cstring(heap_allocator(), p->name); + char *c_link_name = alloc_cstring(permanent_allocator(), p->name); LLVMTypeRef func_ptr_type = lb_type(m, p->type); LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type); @@ -2833,7 +2825,7 @@ void lb_add_edge(lbBlock *from, lbBlock *to) { lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) { - lbBlock *b = gb_alloc_item(heap_allocator(), lbBlock); + lbBlock *b = gb_alloc_item(permanent_allocator(), lbBlock); b->block = LLVMCreateBasicBlockInContext(p->module->ctx, name); b->appended = false; if (append) { @@ -2932,7 +2924,7 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 p char const *name = ""; if (e != nullptr) { - // name = alloc_cstring(heap_allocator(), e->token.string); + // name = alloc_cstring(permanent_allocator(), e->token.string); } LLVMTypeRef llvm_type = lb_type(p->module, type); @@ -2980,13 +2972,13 @@ void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) { isize name_len = p->name.len + 1 + pd_name.len + 1 + 10 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); i32 guid = cast(i32)p->children.count; name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid); String name = make_string(cast(u8 *)name_text, name_len-1); - set_procedure_abi_types(heap_allocator(), e->type); + set_procedure_abi_types(permanent_allocator(), e->type); e->Procedure.link_name = name; @@ -3123,7 +3115,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) { return; } - set_procedure_abi_types(heap_allocator(), e->type); + set_procedure_abi_types(permanent_allocator(), e->type); e->Procedure.link_name = name; lbProcedure *nested_proc = lb_create_procedure(p->module, e); @@ -3179,7 +3171,7 @@ lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) { lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, lbBlock *continue_, lbBlock *fallthrough_) { - lbTargetList *tl = gb_alloc_item(heap_allocator(), lbTargetList); + lbTargetList *tl = gb_alloc_item(permanent_allocator(), lbTargetList); tl->prev = p->target_list; tl->break_ = break_; tl->continue_ = continue_; @@ -3400,7 +3392,7 @@ void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type, lbValue str_elem = lb_emit_ptr_offset(p, lb_string_elem(p, expr), offset); lbValue str_len = lb_emit_arith(p, Token_Sub, count, offset, t_int); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = lb_emit_string(p, str_elem, str_len); lbValue rune_and_len = lb_emit_runtime_call(p, "string_decode_rune", args); lbValue len = lb_emit_struct_ev(p, rune_and_len, 1); @@ -4275,14 +4267,14 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { String mangled_name = {}; { - gbString str = gb_string_make_length(heap_allocator(), p->name.text, p->name.len); + gbString str = gb_string_make_length(permanent_allocator(), p->name.text, p->name.len); str = gb_string_appendc(str, "-"); str = gb_string_append_fmt(str, ".%.*s-%llu", LIT(name), cast(long long)e->id); mangled_name.text = cast(u8 *)str; mangled_name.len = gb_string_length(str); } - char *c_name = alloc_cstring(heap_allocator(), mangled_name); + char *c_name = alloc_cstring(permanent_allocator(), mangled_name); LLVMValueRef global = LLVMAddGlobal(p->module->mod, lb_type(p->module, e->type), c_name); LLVMSetInitializer(global, LLVMConstNull(lb_type(p->module, e->type))); @@ -4329,8 +4321,8 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } } } else { // Tuple(s) - auto lvals = array_make(heap_allocator(), 0, vd->names.count); - auto inits = array_make(heap_allocator(), 0, vd->names.count); + auto lvals = array_make(permanent_allocator(), 0, vd->names.count); + auto inits = array_make(permanent_allocator(), 0, vd->names.count); for_array(i, vd->names) { Ast *name = vd->names[i]; @@ -4367,7 +4359,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { case_ast_node(as, AssignStmt, node); if (as->op.kind == Token_Eq) { - auto lvals = array_make(heap_allocator(), 0, as->lhs.count); + auto lvals = array_make(permanent_allocator(), 0, as->lhs.count); for_array(i, as->lhs) { Ast *lhs = as->lhs[i]; @@ -4385,7 +4377,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { lbValue init = lb_build_expr(p, rhs); lb_addr_store(p, lvals[0], init); } else { - auto inits = array_make(heap_allocator(), 0, lvals.count); + auto inits = array_make(permanent_allocator(), 0, lvals.count); for_array(i, as->rhs) { lbValue init = lb_build_expr(p, as->rhs[i]); @@ -4399,7 +4391,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } } } else { - auto inits = array_make(heap_allocator(), 0, lvals.count); + auto inits = array_make(permanent_allocator(), 0, lvals.count); for_array(i, as->rhs) { lbValue init = lb_build_expr(p, as->rhs[i]); @@ -4491,7 +4483,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } } else { - auto results = array_make(heap_allocator(), 0, return_count); + auto results = array_make(permanent_allocator(), 0, return_count); if (res_count != 0) { for (isize res_index = 0; res_index < res_count; res_index++) { @@ -4794,9 +4786,8 @@ lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) { y = lb_emit_conv(p, y, t); if (is_type_float(t)) { - gbAllocator a = heap_allocator(); i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = x; args[1] = y; switch (sz) { @@ -4812,9 +4803,8 @@ lbValue lb_emit_max(lbProcedure *p, Type *t, lbValue x, lbValue y) { y = lb_emit_conv(p, y, t); if (is_type_float(t)) { - gbAllocator a = heap_allocator(); i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = x; args[1] = y; switch (sz) { @@ -4850,7 +4840,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) { isize max_len = 7+8+1; - char *name = gb_alloc_array(heap_allocator(), char, max_len); + char *name = gb_alloc_array(permanent_allocator(), char, max_len); isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index); len -= 1; m->global_array_index++; @@ -4892,7 +4882,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) char *name = nullptr; { isize max_len = 7+8+1; - name = gb_alloc_array(heap_allocator(), char, max_len); + name = gb_alloc_array(permanent_allocator(), char, max_len); isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index); len -= 1; m->global_array_index++; @@ -5103,7 +5093,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } } else { isize max_len = 7+8+1; - char *str = gb_alloc_array(heap_allocator(), char, max_len); + char *str = gb_alloc_array(permanent_allocator(), char, max_len); isize len = gb_snprintf(str, max_len, "csba$%x", m->global_array_index); m->global_array_index++; @@ -5151,7 +5141,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc lbValue single_elem = lb_const_value(m, elem, value, allow_local); - LLVMValueRef *elems = gb_alloc_array(heap_allocator(), LLVMValueRef, count); + LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count); for (i64 i = 0; i < count; i++) { elems[i] = single_elem.value; } @@ -5204,7 +5194,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc isize byte_len = gb_size_of(u64)*len; u8 *old_bytes = cast(u8 *)words; // TODO(bill): Use a different allocator here for a temporary allocation - u8 *new_bytes = cast(u8 *)gb_alloc_align(heap_allocator(), byte_len, gb_align_of(u64)); + u8 *new_bytes = cast(u8 *)gb_alloc_align(permanent_allocator(), byte_len, gb_align_of(u64)); for (i64 i = 0; i < sz; i++) { new_bytes[i] = old_bytes[sz-1-i]; } @@ -5291,8 +5281,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc if (cl->elems[0]->kind == Ast_FieldValue) { // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->Array.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); isize value_index = 0; for (i64 i = 0; i < type->Array.count; i++) { @@ -5349,8 +5338,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count); - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->Array.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; @@ -5374,8 +5362,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc if (cl->elems[0]->kind == Ast_FieldValue) { // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->EnumeratedArray.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); isize value_index = 0; @@ -5436,8 +5423,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count); - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->EnumeratedArray.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; @@ -5462,8 +5448,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc GB_ASSERT(elem_type_can_be_constant(elem_type)); isize total_elem_count = type->SimdVector.count; - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, total_elem_count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, total_elem_count); for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; @@ -5489,11 +5474,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } isize value_count = type->Struct.fields.count + offset; - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, value_count); - bool *visited = gb_alloc_array(heap_allocator(), bool, value_count); - defer (gb_free(heap_allocator(), values)); - defer (gb_free(heap_allocator(), visited)); - + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count); + bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count); if (cl->elems.count > 0) { @@ -5822,7 +5804,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty Type *ft = base_complex_elem_type(type); if (op == Token_Quo) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lhs; args[1] = rhs; @@ -5896,7 +5878,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty return lb_addr_load(p, res); } else if (op == Token_Mul) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lhs; args[1] = rhs; @@ -5906,7 +5888,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty default: GB_PANIC("Unknown float type"); break; } } else if (op == Token_Quo) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lhs; args[1] = rhs; @@ -6132,7 +6114,7 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { lbValue h = lb_gen_map_header(p, addr, rt); lbValue key = lb_gen_map_key(p, left, rt->Map.key); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = h; args[1] = key; @@ -6378,7 +6360,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (are_types_identical(src, t_cstring) && are_types_identical(dst, t_string)) { lbValue c = lb_emit_conv(p, value, t_cstring); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = c; lbValue s = lb_emit_runtime_call(p, "cstring_to_string", args); return lb_emit_conv(p, s, dst); @@ -6395,7 +6377,6 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { // float -> float if (is_type_float(src) && is_type_float(dst)) { - gbAllocator a = heap_allocator(); i64 sz = type_size_of(src); i64 dz = type_size_of(dst); @@ -6837,8 +6818,7 @@ void lb_emit_init_context(lbProcedure *p, lbAddr addr) { GB_ASSERT(addr.ctx.sel.index.count == 0); lbModule *m = p->module; - gbAllocator a = heap_allocator(); - auto args = array_make(a, 1); + auto args = array_make(permanent_allocator(), 1); args[0] = addr.addr; lb_emit_runtime_call(p, "__init_context", args); } @@ -6907,7 +6887,6 @@ lbValue lb_copy_value_to_ptr(lbProcedure *p, lbValue val, Type *new_type, i64 al } lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) { - gbAllocator a = heap_allocator(); GB_ASSERT(is_type_pointer(s.type)); Type *t = base_type(type_deref(s.type)); Type *result_type = nullptr; @@ -7015,7 +6994,6 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) { return lb_emit_load(p, ptr); } - gbAllocator a = heap_allocator(); Type *t = base_type(s.type); Type *result_type = nullptr; @@ -7121,7 +7099,6 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) { lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) { GB_ASSERT(sel.index.count > 0); Type *type = type_deref(e.type); - gbAllocator a = heap_allocator(); for_array(i, sel.index) { i32 index = cast(i32)sel.index[i]; @@ -7292,14 +7269,14 @@ Array lb_value_to_array(lbProcedure *p, lbValue value) { GB_ASSERT(t->kind == Type_Tuple); auto *rt = &t->Tuple; if (rt->variables.count > 0) { - array = array_make(heap_allocator(), rt->variables.count); + array = array_make(permanent_allocator(), rt->variables.count); for_array(i, rt->variables) { lbValue elem = lb_emit_struct_ev(p, value, cast(i32)i); array[i] = elem; } } } else { - array = array_make(heap_allocator(), 1); + array = array_make(permanent_allocator(), 1); array[0] = value; } return array; @@ -7316,7 +7293,7 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, arg_count += 1; } - LLVMValueRef *args = gb_alloc_array(heap_allocator(), LLVMValueRef, arg_count); + LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count); isize arg_index = 0; if (return_ptr.value != nullptr) { args[arg_index++] = return_ptr.value; @@ -7399,7 +7376,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, LLVMBuildUnreachable(p->builder); }); - set_procedure_abi_types(heap_allocator(), pt); + set_procedure_abi_types(permanent_allocator(), pt); bool is_c_vararg = pt->Proc.c_vararg; isize param_count = pt->Proc.param_count; @@ -7412,7 +7389,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, lbValue result = {}; - auto processed_args = array_make(heap_allocator(), 0, args.count); + auto processed_args = array_make(permanent_allocator(), 0, args.count); if (USE_LLVM_ABI) { lbFunctionType **ft_found = nullptr; @@ -7635,7 +7612,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, case DeferredProcedure_in_out: { auto out_args = lb_value_to_array(p, result); - array_init(&result_as_args, heap_allocator(), in_args.count + out_args.count); + array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count); array_copy(&result_as_args, in_args, 0); array_copy(&result_as_args, out_args, in_args.count); } @@ -7744,7 +7721,7 @@ lbValue lb_string_len(lbProcedure *p, lbValue string) { lbValue lb_cstring_len(lbProcedure *p, lbValue value) { GB_ASSERT(is_type_cstring(value.type)); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = lb_emit_conv(p, value, t_cstring); return lb_emit_runtime_call(p, "cstring_len", args); } @@ -7782,7 +7759,6 @@ lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) { } lbValue lb_map_entries(lbProcedure *p, lbValue value) { - gbAllocator a = heap_allocator(); Type *t = base_type(value.type); GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); init_map_internal_types(t); @@ -7793,7 +7769,6 @@ lbValue lb_map_entries(lbProcedure *p, lbValue value) { } lbValue lb_map_entries_ptr(lbProcedure *p, lbValue value) { - gbAllocator a = heap_allocator(); Type *t = base_type(type_deref(value.type)); GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); init_map_internal_types(t); @@ -7917,7 +7892,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } GB_ASSERT(is_type_typeid(tav.type)); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = lb_build_expr(p, arg); return lb_emit_runtime_call(p, "__type_info_of", args); } @@ -7994,7 +7969,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } unsigned mask_len = cast(unsigned)index_count; - LLVMValueRef *mask_elems = gb_alloc_array(heap_allocator(), LLVMValueRef, index_count); + LLVMValueRef *mask_elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, index_count); for (isize i = 1; i < ce->args.count; i++) { TypeAndValue tv = type_and_value_of_expr(ce->args[i]); GB_ASSERT(is_type_integer(tv.type)); @@ -8224,7 +8199,6 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_abs: { - gbAllocator a = heap_allocator(); lbValue x = lb_build_expr(p, ce->args[0]); Type *t = x.type; if (is_type_unsigned(t)) { @@ -8232,7 +8206,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } if (is_type_quaternion(t)) { i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = x; switch (sz) { case 128: return lb_emit_runtime_call(p, "abs_quaternion128", args); @@ -8241,7 +8215,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_PANIC("Unknown complex type"); } else if (is_type_complex(t)) { i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = x; switch (sz) { case 64: return lb_emit_runtime_call(p, "abs_complex64", args); @@ -8250,7 +8224,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_PANIC("Unknown complex type"); } else if (is_type_float(t)) { i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = x; switch (sz) { case 32: return lb_emit_runtime_call(p, "abs_f32", args); @@ -8506,7 +8480,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_ASSERT(tv.type->kind == Type_Tuple); Type *fix_typed = alloc_type_tuple(); - array_init(&fix_typed->Tuple.variables, heap_allocator(), 2); + array_init(&fix_typed->Tuple.variables, permanent_allocator(), 2); fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0]; fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1); @@ -8621,10 +8595,10 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { Type *proc_type_ = base_type(value.type); GB_ASSERT(proc_type_->kind == Type_Proc); TypeProc *pt = &proc_type_->Proc; - set_procedure_abi_types(heap_allocator(), proc_type_); + set_procedure_abi_types(permanent_allocator(), proc_type_); if (is_call_expr_field_value(ce)) { - auto args = array_make(heap_allocator(), pt->param_count); + auto args = array_make(permanent_allocator(), pt->param_count); for_array(arg_index, ce->args) { Ast *arg = ce->args[arg_index]; @@ -8693,7 +8667,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { param_count = pt->params->Tuple.variables.count; } - auto args = array_make(heap_allocator(), cast(isize)gb_max(param_count, arg_count)); + auto args = array_make(permanent_allocator(), cast(isize)gb_max(param_count, arg_count)); isize variadic_index = pt->variadic_index; bool variadic = pt->variadic && variadic_index >= 0; bool vari_expand = ce->ellipsis.pos.line != 0; @@ -8801,7 +8775,6 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { if (variadic && !vari_expand && !is_c_vararg) { // variadic call argument generation - gbAllocator allocator = heap_allocator(); Type *slice_type = param_tuple->variables[variadic_index]->type; Type *elem_type = base_type(slice_type)->Slice.elem; lbAddr slice = lb_add_local_generated(p, slice_type, true); @@ -9077,7 +9050,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { lbValue invalid_typeid = lb_const_value(p->module, t_typeid, exact_value_i64(0)); return lb_emit_comp(p, op_kind, x, invalid_typeid); } else if (is_type_bit_field(t)) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); lbValue lhs = lb_address_from_load_or_generate_local(p, x); args[0] = lb_emit_conv(p, lhs, t_rawptr); args[1] = lb_const_int(p->module, t_int, type_size_of(t)); @@ -9106,7 +9079,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { } } } else if (is_type_struct(t) && type_has_nil(t)) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); lbValue lhs = lb_address_from_load_or_generate_local(p, x); args[0] = lb_emit_conv(p, lhs, t_rawptr); args[1] = lb_const_int(p->module, t_int, type_size_of(t)); @@ -9141,8 +9114,6 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } else if (lb_is_const(right) || lb_is_const_nil(right)) { right = lb_emit_conv(p, right, left.type); } else { - gbAllocator a = heap_allocator(); - Type *lt = left.type; Type *rt = right.type; @@ -9222,7 +9193,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } else { if (is_type_simple_compare(tl) && (op_kind == Token_CmpEq || op_kind == Token_NotEq)) { // TODO(bill): Test to see if this is actually faster!!!! - auto args = array_make(heap_allocator(), 3); + auto args = array_make(permanent_allocator(), 3); args[0] = lb_emit_conv(p, lhs, t_rawptr); args[1] = lb_emit_conv(p, rhs, t_rawptr); args[2] = lb_const_int(p->module, t_int, type_size_of(tl)); @@ -9265,7 +9236,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } GB_ASSERT(runtime_procedure != nullptr); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; return lb_emit_runtime_call(p, runtime_procedure, args); @@ -9290,7 +9261,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } GB_ASSERT(runtime_procedure != nullptr); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; return lb_emit_runtime_call(p, runtime_procedure, args); @@ -9315,7 +9286,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } GB_ASSERT(runtime_procedure != nullptr); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; return lb_emit_runtime_call(p, runtime_procedure, args); @@ -9464,14 +9435,14 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A // NOTE(bill): Generate a new name // parent$count isize name_len = prefix_name.len + 1 + 8 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); i32 name_id = cast(i32)m->anonymous_proc_lits.entries.count; name_len = gb_snprintf(name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), name_id); String name = make_string((u8 *)name_text, name_len-1); Type *type = type_of_expr(expr); - set_procedure_abi_types(heap_allocator(), type); + set_procedure_abi_types(permanent_allocator(), type); Token token = {}; @@ -9567,7 +9538,7 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p Type *dst_type = tuple->Tuple.variables[0]->type; lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_const_string(m, pos.file); @@ -9628,7 +9599,7 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos // NOTE(bill): Panic on invalid conversion lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_const_string(m, pos.file); @@ -9912,7 +9883,6 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { return addr.addr; } else if (ue_expr->kind == Ast_TypeAssertion) { - gbAllocator a = heap_allocator(); GB_ASSERT(is_type_pointer(tv.type)); ast_node(ta, TypeAssertion, ue_expr); @@ -9934,7 +9904,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue dst_tag = lb_const_union_tag(p->module, src_type, dst_type); lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_find_or_add_entity_string(p->module, pos.file); @@ -9959,7 +9929,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_find_or_add_entity_string(p->module, pos.file); @@ -10110,7 +10080,6 @@ lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) { lbValue lb_gen_map_header(lbProcedure *p, lbValue map_val_ptr, Type *map_type) { GB_ASSERT_MSG(is_type_pointer(map_val_ptr.type), "%s", type_to_string(map_val_ptr.type)); - gbAllocator a = heap_allocator(); lbAddr h = lb_add_local_generated(p, t_map_header, false); // all the values will be initialzed later map_type = base_type(map_type); GB_ASSERT(map_type->kind == Type_Map); @@ -10154,7 +10123,7 @@ lbValue lb_gen_map_key(lbProcedure *p, lbValue key, Type *key_type) { u64 hs = fnv64a(v.text, v.len); hashed_str = lb_const_int(p->module, t_u64, hs); } else { - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = str; hashed_str = lb_emit_runtime_call(p, "default_hash_string", args); } @@ -10167,7 +10136,7 @@ lbValue lb_gen_map_key(lbProcedure *p, lbValue key, Type *key_type) { i64 sz = type_size_of(t); GB_ASSERT(sz <= 8); if (sz != 0) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lb_address_from_load_or_generate_local(p, key); args[1] = lb_const_int(p->module, t_int, sz); lbValue hash = lb_emit_runtime_call(p, "default_hash_ptr", args); @@ -10197,7 +10166,7 @@ void lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbAddr addr, Type *map_ lbAddr value_addr = lb_add_local_generated(p, v.type, false); lb_addr_store(p, value_addr, v); - auto args = array_make(heap_allocator(), 4); + auto args = array_make(permanent_allocator(), 4); args[0] = h; args[1] = key; args[2] = lb_emit_conv(p, value_addr.addr, t_rawptr); @@ -10356,7 +10325,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_end; case_ast_node(ta, TypeAssertion, expr); - gbAllocator a = heap_allocator(); TokenPos pos = ast_token(expr).pos; lbValue e = lb_build_expr(p, ta->expr); Type *t = type_deref(e.type); @@ -10393,7 +10361,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_ast_node(ie, IndexExpr, expr); Type *t = base_type(type_of_expr(ie->expr)); - gbAllocator a = heap_allocator(); bool deref = is_type_pointer(t); t = base_type(type_deref(t)); @@ -10593,7 +10560,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_end; case_ast_node(se, SliceExpr, expr); - gbAllocator a = heap_allocator(); lbValue low = lb_const_int(p->module, t_int, 0); lbValue high = {}; @@ -10892,9 +10858,8 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count == 0) { break; } - gbAllocator a = heap_allocator(); { - auto args = array_make(a, 3); + auto args = array_make(permanent_allocator(), 3); args[0] = lb_gen_map_header(p, v.addr, type); args[1] = lb_const_int(p->module, t_int, 2*cl->elems.count); args[2] = lb_emit_source_code_location(p, proc_name, pos); @@ -10915,8 +10880,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks for_array(i, cl->elems) { @@ -11015,8 +10979,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks for_array(i, cl->elems) { @@ -11124,8 +11087,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { lbValue data = lb_slice_elem(p, slice); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); for_array(i, cl->elems) { Ast *elem = cl->elems[i]; @@ -11218,14 +11180,13 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { break; } Type *et = bt->DynamicArray.elem; - gbAllocator a = heap_allocator(); lbValue size = lb_const_int(p->module, t_int, type_size_of(et)); lbValue align = lb_const_int(p->module, t_int, type_align_of(et)); i64 item_count = gb_max(cl->max_count, cl->elems.count); { - auto args = array_make(a, 5); + auto args = array_make(permanent_allocator(), 5); args[0] = lb_emit_conv(p, lb_addr_get_ptr(p, v), t_rawptr); args[1] = size; args[2] = align; @@ -11279,7 +11240,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { } { - auto args = array_make(a, 6); + auto args = array_make(permanent_allocator(), 6); args[0] = lb_emit_conv(p, v.addr, t_rawptr); args[1] = size; args[2] = align; @@ -11491,7 +11452,7 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { type = default_type(type); isize max_len = 7+8+1; - u8 *str = cast(u8 *)gb_alloc_array(heap_allocator(), u8, max_len); + u8 *str = cast(u8 *)gb_alloc_array(permanent_allocator(), u8, max_len); isize len = gb_snprintf(cast(char *)str, max_len, "ggv$%x", m->global_generated_index); m->global_generated_index++; String name = make_string(str, len-1); @@ -11571,12 +11532,11 @@ lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool } lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id) { - gbAllocator a = heap_allocator(); Token token = {Token_Ident}; isize name_len = prefix.len + 1 + 20; auto suffix_id = cast(unsigned long long)id; - char *text = gb_alloc_array(a, char, name_len+1); + char *text = gb_alloc_array(permanent_allocator(), char, name_len+1); gb_snprintf(text, name_len, "%.*s-%llu", LIT(prefix), suffix_id); text[name_len] = 0; @@ -11598,7 +11558,6 @@ lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data lbModule *m = p->module; LLVMContextRef ctx = m->ctx; - gbAllocator a = heap_allocator(); CheckerInfo *info = m->info; { @@ -11976,10 +11935,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da str_lit("$enum_values"), cast(i64)entry_index); - LLVMValueRef *name_values = gb_alloc_array(heap_allocator(), LLVMValueRef, fields.count); - LLVMValueRef *value_values = gb_alloc_array(heap_allocator(), LLVMValueRef, fields.count); - defer (gb_free(heap_allocator(), name_values)); - defer (gb_free(heap_allocator(), value_values)); + LLVMValueRef *name_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); + LLVMValueRef *value_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); GB_ASSERT(is_type_integer(t->Enum.base_type)); @@ -12328,10 +12285,6 @@ void lb_generate_code(lbGenerator *gen) { LLVMModuleRef mod = gen->module.mod; CheckerInfo *info = gen->info; - Arena temp_arena = {}; - arena_init(&temp_arena, heap_allocator()); - gbAllocator temp_allocator = arena_allocator(&temp_arena); - auto *min_dep_set = &info->minimum_dependency_set; @@ -12344,8 +12297,8 @@ void lb_generate_code(lbGenerator *gen) { LLVMInitializeNativeTarget(); - char const *target_triple = alloc_cstring(heap_allocator(), build_context.metrics.target_triplet); - char const *target_data_layout = alloc_cstring(heap_allocator(), build_context.metrics.target_data_layout); + char const *target_triple = alloc_cstring(permanent_allocator(), build_context.metrics.target_triplet); + char const *target_data_layout = alloc_cstring(permanent_allocator(), build_context.metrics.target_data_layout); LLVMSetTarget(mod, target_triple); LLVMTargetRef target = {}; @@ -12367,7 +12320,7 @@ void lb_generate_code(lbGenerator *gen) { if (build_context.microarch == "native") { llvm_cpu = host_cpu_name; } else { - llvm_cpu = alloc_cstring(heap_allocator(), build_context.microarch); + llvm_cpu = alloc_cstring(permanent_allocator(), build_context.microarch); } if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) { llvm_features = LLVMGetHostCPUFeatures(); @@ -12538,7 +12491,7 @@ void lb_generate_code(lbGenerator *gen) { lbValue init; DeclInfo *decl; }; - auto global_variables = array_make(heap_allocator(), 0, global_variable_max_count); + auto global_variables = array_make(permanent_allocator(), 0, global_variable_max_count); for_array(i, info->variable_init_order) { DeclInfo *d = info->variable_init_order[i]; @@ -12565,7 +12518,7 @@ void lb_generate_code(lbGenerator *gen) { lbValue g = {}; - g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(heap_allocator(), name)); + g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); g.type = alloc_type_pointer(e->type); if (e->Variable.thread_local_model != "") { LLVMSetThreadLocal(g.value, true); @@ -12619,9 +12572,6 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Global Procedures and Types"); for_array(i, info->entities) { - // arena_free_all(&temp_arena); - // gbAllocator a = temp_allocator; - Entity *e = info->entities[i]; String name = e->token.string; DeclInfo *decl = e->decl_info; @@ -12906,12 +12856,12 @@ void lb_generate_code(lbGenerator *gen) { if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) { name = str_lit("mainCRTStartup"); } else { - array_init(¶ms->Tuple.variables, heap_allocator(), 2); + array_init(¶ms->Tuple.variables, permanent_allocator(), 2); params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true); params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), alloc_type_pointer(t_cstring), false, true); } - array_init(&results->Tuple.variables, heap_allocator(), 1); + array_init(&results->Tuple.variables, permanent_allocator(), 1); results->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("_"), t_i32, false, true); Type *proc_type = alloc_type_proc(nullptr, @@ -12944,8 +12894,7 @@ void lb_generate_code(lbGenerator *gen) { } - String filepath_ll = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".ll")); - defer (gb_free(heap_allocator(), filepath_ll.text)); + String filepath_ll = concatenate_strings(temporary_allocator(), gen->output_base, STR_LIT(".ll")); TIME_SECTION("LLVM Procedure Generation"); for_array(i, m->procedures_to_generate) { @@ -13032,20 +12981,20 @@ void lb_generate_code(lbGenerator *gen) { LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile; if (build_context.build_mode == BuildMode_Assembly) { - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".S")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".S")); code_gen_file_type = LLVMAssemblyFile; } else { switch (build_context.metrics.os) { case TargetOs_windows: - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".obj")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".obj")); break; case TargetOs_darwin: case TargetOs_linux: case TargetOs_essence: - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".o")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".o")); break; case TargetOs_js: - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".wasm-obj")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".wasm-obj")); break; } } diff --git a/src/main.cpp b/src/main.cpp index 3717a4147..d0d2e2bbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1643,12 +1643,15 @@ int main(int arg_count, char const **arg_ptr) { timings_init(timings, str_lit("Total Time"), 128); defer (timings_destroy(timings)); + arena_init(&permanent_arena, heap_allocator()); + arena_init(&temporary_arena, heap_allocator()); + arena_init(&global_ast_arena, heap_allocator()); + init_string_buffer_memory(); init_string_interner(); init_global_error_collector(); init_keyword_hash_table(); global_big_int_init(); - arena_init(&global_ast_arena, heap_allocator()); array_init(&library_collections, heap_allocator()); // NOTE(bill): 'core' cannot be (re)defined by the user @@ -1795,6 +1798,8 @@ int main(int arg_count, char const **arg_ptr) { return 1; } + arena_free_all(&temporary_arena); + if (build_context.generate_docs) { // generate_documentation(&parser); return 0; @@ -1812,6 +1817,7 @@ int main(int arg_count, char const **arg_ptr) { check_parsed_files(&checker); } + arena_free_all(&temporary_arena); if (build_context.no_output_files) { if (build_context.query_data_set_settings.ok) { @@ -1842,6 +1848,8 @@ int main(int arg_count, char const **arg_ptr) { } lb_generate_code(&gen); + arena_free_all(&temporary_arena); + switch (build_context.build_mode) { case BuildMode_Executable: case BuildMode_DynamicLibrary: @@ -1919,12 +1927,18 @@ int main(int arg_count, char const **arg_ptr) { timings_start_section(timings, str_lit("llvm ir gen")); ir_gen_tree(&ir_gen); + arena_free_all(&temporary_arena); + timings_start_section(timings, str_lit("llvm ir opt tree")); ir_opt_tree(&ir_gen); + arena_free_all(&temporary_arena); + timings_start_section(timings, str_lit("llvm ir print")); print_llvm_ir(&ir_gen); + arena_free_all(&temporary_arena); + String output_name = ir_gen.output_name; String output_base = ir_gen.output_base; diff --git a/src/parser.cpp b/src/parser.cpp index 794ff231d..5e04aea17 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -108,6 +108,30 @@ Token ast_token(Ast *node) { return empty_token; } + +gb_global gbAtomic64 total_allocated_node_memory = {0}; +gb_global gbAtomic64 total_subtype_node_memory_test = {0}; + +isize ast_node_size(AstKind kind) { + return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); + +} +// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ +Ast *alloc_ast_node(AstFile *f, AstKind kind) { + gbAllocator a = ast_allocator(f); + + isize size = ast_node_size(kind); + + gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); + gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); + + // Ast *node = gb_alloc_item(a, Ast); + Ast *node = cast(Ast *)gb_alloc(a, size); + node->kind = kind; + node->file = f; + return node; +} + Ast *clone_ast(Ast *node); Array clone_ast_array(Array array) { Array result = {}; @@ -125,7 +149,7 @@ Ast *clone_ast(Ast *node) { return nullptr; } Ast *n = alloc_ast_node(node->file, node->kind); - gb_memmove(n, node, gb_size_of(Ast)); + gb_memmove(n, node, ast_node_size(node->kind)); switch (n->kind) { default: GB_PANIC("Unhandled Ast %.*s", LIT(ast_strings[n->kind])); break; @@ -463,23 +487,6 @@ bool ast_node_expect(Ast *node, AstKind kind) { return true; } - -gb_global gbAtomic64 total_allocated_node_memory = {0}; -gb_global gbAtomic64 total_subtype_node_memory_test = {0}; - -// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ -Ast *alloc_ast_node(AstFile *f, AstKind kind) { - gbAllocator a = ast_allocator(f); - - gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); - gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); - - Ast *node = gb_alloc_item(a, Ast); - node->kind = kind; - node->file = f; - return node; -} - Ast *ast_bad_expr(AstFile *f, Token begin, Token end) { Ast *result = alloc_ast_node(f, Ast_BadExpr); result->BadExpr.begin = begin; diff --git a/src/parser.hpp b/src/parser.hpp index 8e210876f..0804652a3 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -655,6 +655,7 @@ struct Ast { Scope * scope; TypeAndValue tav; + // IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant union { #define AST_KIND(_kind_name_, name, ...) GB_JOIN2(Ast, _kind_name_) _kind_name_; AST_KINDS diff --git a/src/types.cpp b/src/types.cpp index 1a55c9b05..17dcedf45 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -771,7 +771,8 @@ void set_base_type(Type *t, Type *base) { Type *alloc_type(TypeKind kind) { - gbAllocator a = heap_allocator(); + // gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); Type *t = gb_alloc_item(a, Type); zero_item(t); t->kind = kind; @@ -2340,7 +2341,7 @@ Selection lookup_field_from_index(Type *type, i64 index) { GB_ASSERT(is_type_struct(type) || is_type_union(type) || is_type_tuple(type)); type = base_type(type); - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); isize max_count = 0; switch (type->kind) { case Type_Struct: max_count = type->Struct.fields.count; break; @@ -2397,7 +2398,6 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty return empty_selection; } - gbAllocator a = heap_allocator(); Type *type = type_deref(type_); bool is_ptr = type != type_; sel.indirect = sel.indirect || is_ptr; @@ -2986,7 +2986,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) { } Array type_set_offsets_of(Array const &fields, bool is_packed, bool is_raw_union) { - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); auto offsets = array_make(a, fields.count); i64 curr_offset = 0; if (is_raw_union) { -- cgit v1.2.3 From 939878df50cf314dd2cd0e5da737ac93e88b5b25 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Nov 2020 23:54:18 +0000 Subject: Improve logic for x->y() shorthand --- src/check_expr.cpp | 16 ++++++++++++++++ src/check_stmt.cpp | 3 +-- src/checker.hpp | 3 ++- src/main.cpp | 3 --- src/parser.cpp | 24 ++++++++++++------------ 5 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 110e83ef2..11ccf2dab 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3437,6 +3437,13 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ Entity *entity = nullptr; Selection sel = {}; // NOTE(bill): Not used if it's an import name + if (!c->allow_arrow_right_selector_expr && se->token.kind == Token_ArrowRight) { + error(node, "Illegal use of -> selector shorthand outside of a call"); + operand->mode = Addressing_Invalid; + operand->expr = node; + return nullptr; + } + operand->expr = node; Ast *op_expr = se->expr; @@ -9492,8 +9499,13 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type // // NOTE(bill, 2020-05-22): I'm going to regret this decision, ain't I? + bool allow_arrow_right_selector_expr; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; Operand x = {}; ExprKind kind = check_expr_base(c, &x, se->expr, nullptr); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + if (x.mode == Addressing_Invalid || x.type == t_invalid) { o->mode = Addressing_Invalid; o->type = t_invalid; @@ -9594,7 +9606,11 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type ce->args = modified_args; se->modified_call = true; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; check_expr_base(c, o, se->call, type_hint); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + o->expr = node; return Expr_Expr; case_end; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index a480e0fdf..4cafa8df5 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -858,8 +858,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { token.pos = ast_token(ss->body).pos; token.string = str_lit("true"); - x.expr = gb_alloc_item(permanent_allocator(), Ast); - x.expr->kind = Ast_Ident; + x.expr = alloc_ast_node(nullptr, Ast_Ident); x.expr->Ident.token = token; } diff --git a/src/checker.hpp b/src/checker.hpp index ed4809748..e6111d2af 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -45,7 +45,7 @@ enum StmtFlag { Stmt_TypeSwitch = 1<<4, - Stmt_CheckScopeDecls = 1<<5, + Stmt_CheckScopeDecls = 1<<5, }; enum BuiltinProcPkg { @@ -316,6 +316,7 @@ struct CheckerContext { bool no_polymorphic_errors; bool hide_polymorphic_errors; bool in_polymorphic_specialization; + bool allow_arrow_right_selector_expr; Scope * polymorphic_scope; Ast *assignment_lhs_hint; diff --git a/src/main.cpp b/src/main.cpp index 97fecb094..67dc5da00 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1876,9 +1876,6 @@ int main(int arg_count, char const **arg_ptr) { SIZE_T virtual_mem_used_by_me = pmc.PrivateUsage; gb_printf_err("virtual_memory_used: %tu B\n", virtual_mem_used_by_me); - gb_printf_err("total_allocated_node_memory: %lld B\n", total_allocated_node_memory.value); - gb_printf_err("total_subtype_node_memory_test: %lld B\n", total_subtype_node_memory_test.value); - gb_printf_err("fraction: %.6f\n", (f64)total_subtype_node_memory_test.value/(f64)total_allocated_node_memory.value); Parser *p = checker.parser; isize lines = p->total_line_count; isize tokens = p->total_token_count; diff --git a/src/parser.cpp b/src/parser.cpp index 5e04aea17..476504d52 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -109,9 +109,6 @@ Token ast_token(Ast *node) { } -gb_global gbAtomic64 total_allocated_node_memory = {0}; -gb_global gbAtomic64 total_subtype_node_memory_test = {0}; - isize ast_node_size(AstKind kind) { return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); @@ -122,10 +119,6 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { isize size = ast_node_size(kind); - gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); - gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); - - // Ast *node = gb_alloc_item(a, Ast); Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file = f; @@ -2511,7 +2504,15 @@ Ast *parse_call_expr(AstFile *f, Ast *operand) { f->expr_level--; close_paren = expect_closing(f, Token_CloseParen, str_lit("argument list")); - return ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis); + + Ast *call = ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis); + + Ast *o = unparen_expr(operand); + if (o->kind == Ast_SelectorExpr && o->SelectorExpr.token.kind == Token_ArrowRight) { + return ast_selector_call_expr(f, o->SelectorExpr.token, o, call); + } + + return call; } Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { @@ -2563,11 +2564,10 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { case Token_ArrowRight: { Token token = advance_token(f); - // syntax_error(token, "Selector expressions use '.' rather than '->'"); - Ast *sel = ast_selector_expr(f, token, operand, parse_ident(f)); - Ast *call = parse_call_expr(f, sel); - operand = ast_selector_call_expr(f, token, sel, call); + operand = ast_selector_expr(f, token, operand, parse_ident(f)); + // Ast *call = parse_call_expr(f, sel); + // operand = ast_selector_call_expr(f, token, sel, call); break; } -- cgit v1.2.3 From ca4b0527e80bda39aa677f013415eff0c62f433d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 16 Nov 2020 15:18:25 +0000 Subject: Minimize memory usage for AST nodes by using Slice rather than Array when the parameter doesn't need to grow --- src/array.cpp | 89 ++++++++++++++++++++++++++++++++++++- src/check_decl.cpp | 2 +- src/check_expr.cpp | 24 +++++----- src/check_stmt.cpp | 6 +-- src/check_type.cpp | 10 ++--- src/checker.cpp | 12 ++--- src/checker.hpp | 2 +- src/entity.cpp | 4 +- src/ir.cpp | 6 +-- src/llvm_backend.cpp | 4 +- src/parser.cpp | 121 +++++++++++++++++++++++++++++---------------------- src/parser.hpp | 57 ++++++++++++------------ 12 files changed, 218 insertions(+), 119 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/array.cpp b/src/array.cpp index 6fe54b847..dc52eeb8d 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -43,11 +43,96 @@ template void array_set_capacity (Array *array, isize capac template Array array_slice (Array const &array, isize lo, isize hi); template Array array_clone (gbAllocator const &a, Array const &array); - - template void array_ordered_remove (Array *array, isize index); template void array_unordered_remove(Array *array, isize index); +template void array_copy(Array *array, Array const &data, isize offset); +template void array_copy(Array *array, Array const &data, isize offset, isize count); + +template T *array_end_ptr(Array *array); + + +template +struct Slice { + T *data; + isize count; + + T &operator[](isize index) { + #if !defined(NO_ARRAY_BOUNDS_CHECK) + GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count); + #endif + return data[index]; + } + + T const &operator[](isize index) const { + #if !defined(NO_ARRAY_BOUNDS_CHECK) + GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count); + #endif + return data[index]; + } +}; + +template Slice slice_from_array(Array const &a); + + + +template +Slice slice_make(gbAllocator const &allocator, isize count) { + Slice s = {}; + s.data = gb_alloc_array(allocator, T, count); + s.count = count; + return s; +} + + +template +Slice slice_from_array(Array const &a) { + return {a.data, a.count}; +} +template +Slice slice_clone(gbAllocator const &allocator, Slice const &a) { + T *data = cast(T *)gb_alloc_copy_align(allocator, a.data, a.count*gb_size_of(T), gb_align_of(T)); + return {data, a.count}; +} + +template +Slice slice_clone_from_array(gbAllocator const &allocator, Array const &a) { + auto c = array_clone(allocator, a); + return {c.data, c.count}; +} + + +template +void slice_copy(Slice *slice, Slice const &data, isize offset) { + gb_memmove(slice->data+offset, data.data, gb_size_of(T)*data.count); +} +template +void slice_copy(Slice *slice, Slice const &data, isize offset, isize count) { + gb_memmove(slice->data+offset, data.data, gb_size_of(T)*gb_min(data.count, count)); +} + + + +template +void slice_ordered_remove(Slice *array, isize index) { + GB_ASSERT(0 <= index && index < array->count); + + isize bytes = gb_size_of(T) * (array->count-(index+1)); + gb_memmove(array->data+index, array->data+index+1, bytes); + array->count -= 1; +} + +template +void slice_unordered_remove(Slice *array, isize index) { + GB_ASSERT(0 <= index && index < array->count); + + isize n = array->count-1; + if (index != n) { + gb_memmove(array->data+index, array->data+n, gb_size_of(T)); + } + array->count -= 1; +} + template void array_copy(Array *array, Array const &data, isize offset) { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 248069b97..da07fe4bc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -113,7 +113,7 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri return e->type; } -void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array const &inits, String context_name) { +void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice const &inits, String context_name) { if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) { return; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 11ccf2dab..94a3467d2 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -73,7 +73,7 @@ void update_expr_type (CheckerContext *c, Ast *e, Type *type, bool check_is_terminating (Ast *node, String const &label); bool check_has_break (Ast *stmt, String const &label, bool implicit); void check_stmt (CheckerContext *c, Ast *node, u32 flags); -void check_stmt_list (CheckerContext *c, Array const &stmts, u32 flags); +void check_stmt_list (CheckerContext *c, Slice const &stmts, u32 flags); void check_init_constant (CheckerContext *c, Entity *e, Operand *operand); bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value); bool check_procedure_type (CheckerContext *c, Type *type, Ast *proc_type_node, Array *operands = nullptr); @@ -133,7 +133,7 @@ void error_operand_no_value(Operand *o) { } -void check_scope_decls(CheckerContext *c, Array const &nodes, isize reserve_size) { +void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reserve_size) { Scope *s = c->scope; check_collect_entities(c, nodes); @@ -6062,7 +6062,7 @@ isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs } -bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Array const &rhs) { +bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -6146,7 +6146,7 @@ bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, -bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Array const &rhs, bool allow_ok, bool is_variadic) { +bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -6748,7 +6748,7 @@ Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize } -bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Array *clauses, bool print_err) { +bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice *clauses, bool print_err) { if (clauses != nullptr) { for_array(i, *clauses) { Ast *clause = (*clauses)[i]; @@ -6813,7 +6813,7 @@ bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, A } -CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Array const &args) { +CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Slice const &args) { ast_node(ce, CallExpr, call); CallArgumentCheckerType *call_checker = check_call_arguments_internal; @@ -7598,7 +7598,7 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper -ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Array const &args, ProcInlining inlining, Type *type_hint) { +ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { if (proc != nullptr && proc->kind == Ast_BasicDirective) { ast_node(bd, BasicDirective, proc); @@ -8150,7 +8150,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_ast_node(bl, BasicLit, node); Type *t = t_invalid; - switch (bl->value.kind) { + switch (node->tav.value.kind) { case ExactValue_String: t = t_untyped_string; break; case ExactValue_Float: t = t_untyped_float; break; case ExactValue_Complex: t = t_untyped_complex; break; @@ -8168,7 +8168,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type o->mode = Addressing_Constant; o->type = t; - o->value = bl->value; + o->value = node->tav.value; case_end; case_ast_node(bd, BasicDirective, node); @@ -9600,9 +9600,9 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type - auto modified_args = array_make(heap_allocator(), ce->args.count+1); + auto modified_args = slice_make(heap_allocator(), ce->args.count+1); modified_args[0] = first_arg; - array_copy(&modified_args, ce->args, 1); + slice_copy(&modified_args, ce->args, 1); ce->args = modified_args; se->modified_call = true; @@ -10210,7 +10210,7 @@ void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) gbString write_expr_to_string(gbString str, Ast *node); -gbString write_struct_fields_to_string(gbString str, Array const ¶ms) { +gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4cafa8df5..ad72256c3 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -15,7 +15,7 @@ bool is_divigering_stmt(Ast *stmt) { return t->kind == Type_Proc && t->Proc.diverging; } -void check_stmt_list(CheckerContext *ctx, Array const &stmts, u32 flags) { +void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { if (stmts.count == 0) { return; } @@ -78,7 +78,7 @@ void check_stmt_list(CheckerContext *ctx, Array const &stmts, u32 flags) } } -bool check_is_terminating_list(Array const &stmts, String const &label) { +bool check_is_terminating_list(Slice const &stmts, String const &label) { // Iterate backwards for (isize n = stmts.count-1; n >= 0; n--) { Ast *stmt = stmts[n]; @@ -96,7 +96,7 @@ bool check_is_terminating_list(Array const &stmts, String const &label) { return false; } -bool check_has_break_list(Array const &stmts, String const &label, bool implicit) { +bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { for_array(i, stmts) { Ast *stmt = stmts[i]; if (check_has_break(stmt, label, implicit)) { diff --git a/src/check_type.cpp b/src/check_type.cpp index af0c70119..6ea17eca6 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -117,7 +117,7 @@ bool does_field_type_allow_using(Type *t) { return false; } -void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields, Array *tags, Array const ¶ms, +void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields, Array *tags, Slice const ¶ms, isize init_field_capacity, Type *struct_type, String context) { *fields = array_make(heap_allocator(), 0, init_field_capacity); *tags = array_make(heap_allocator(), 0, init_field_capacity); @@ -389,7 +389,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array< if (st->polymorphic_params != nullptr) { ast_node(field_list, FieldList, st->polymorphic_params); - Array params = field_list->list; + Slice params = field_list->list; if (params.count != 0) { isize variable_count = 0; for_array(i, params) { @@ -607,7 +607,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Arraypolymorphic_params != nullptr) { ast_node(field_list, FieldList, ut->polymorphic_params); - Array params = field_list->list; + Slice params = field_list->list; if (params.count != 0) { isize variable_count = 0; for_array(i, params) { @@ -1516,7 +1516,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is bool success = true; ast_node(field_list, FieldList, _params); - Array params = field_list->list; + Slice params = field_list->list; if (params.count == 0) { if (success_) *success_ = success; @@ -1875,7 +1875,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { return nullptr; } ast_node(field_list, FieldList, _results); - Array results = field_list->list; + Slice results = field_list->list; if (results.count == 0) { return nullptr; diff --git a/src/checker.cpp b/src/checker.cpp index 380872f24..f02b927c3 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2854,7 +2854,7 @@ void check_decl_attributes(CheckerContext *c, Array const &attributes, De } -isize get_total_value_count(Array const &values) { +isize get_total_value_count(Slice const &values) { isize count = 0; for_array(i, values) { Type *t = type_of_expr(values[i]); @@ -3068,7 +3068,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } else { entity_visibility_kind = kind; } - array_unordered_remove(elems, j); + slice_unordered_remove(elems, j); j -= 1; } } @@ -3252,7 +3252,7 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { } // NOTE(bill): If file_scopes == nullptr, this will act like a local scope -void check_collect_entities(CheckerContext *c, Array const &nodes) { +void check_collect_entities(CheckerContext *c, Slice const &nodes) { for_array(decl_index, nodes) { Ast *decl = nodes[decl_index]; if (!is_ast_decl(decl) && !is_ast_when_stmt(decl)) { @@ -3783,7 +3783,7 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { } } -bool collect_checked_packages_from_decl_list(Checker *c, Array const &decls) { +bool collect_checked_packages_from_decl_list(Checker *c, Slice const &decls) { bool new_files = false; for_array(i, decls) { Ast *decl = decls[i]; @@ -3805,7 +3805,7 @@ bool collect_checked_packages_from_decl_list(Checker *c, Array const &dec } // Returns true if a new package is present -bool collect_file_decls(CheckerContext *ctx, Array const &decls); +bool collect_file_decls(CheckerContext *ctx, Slice const &decls); bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws); bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { @@ -3880,7 +3880,7 @@ bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { return false; } -bool collect_file_decls(CheckerContext *ctx, Array const &decls) { +bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { GB_ASSERT(ctx->scope->flags&ScopeFlag_File); if (collect_checked_packages_from_decl_list(ctx->checker, decls)) { diff --git a/src/checker.hpp b/src/checker.hpp index e6111d2af..9c9b77ac3 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -384,7 +384,7 @@ void check_add_foreign_import_decl(CheckerContext *c, Ast *decl); bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false); -void check_collect_entities(CheckerContext *c, Array const &nodes); +void check_collect_entities(CheckerContext *c, Slice const &nodes); void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws); void check_delayed_file_import_entity(CheckerContext *c, Ast *decl); diff --git a/src/entity.cpp b/src/entity.cpp index 708b0862c..0aece39c3 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -165,7 +165,7 @@ struct Entity { Scope *scope; } ImportName; struct { - Array paths; + Slice paths; String name; } LibraryName; i32 Nil; @@ -333,7 +333,7 @@ Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type, } Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type, - Array paths, String name) { + Slice paths, String name) { Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type); entity->LibraryName.paths = paths; entity->LibraryName.name = name; diff --git a/src/ir.cpp b/src/ir.cpp index 7b6301e30..1f2819ccf 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6884,7 +6884,7 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) { return *value; } -void ir_build_stmt_list(irProcedure *proc, Array stmts); +void ir_build_stmt_list(irProcedure *proc, Slice stmts); void ir_build_assign_op(irProcedure *proc, irAddr const &lhs, irValue *value, TokenKind op); bool is_double_pointer(Type *t) { @@ -9689,7 +9689,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstValueDecl *vd) { } } -void ir_build_stmt_list(irProcedure *proc, Array stmts) { +void ir_build_stmt_list(irProcedure *proc, Slice stmts) { // NOTE(bill): Precollect constant entities for_array(i, stmts) { Ast *stmt = stmts[i]; @@ -10899,7 +10899,7 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { ast_node(body, BlockStmt, ss->body); - Array default_stmts = {}; + Slice default_stmts = {}; irBlock *default_fall = nullptr; irBlock *default_block = nullptr; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 6542da69b..50d200551 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3134,7 +3134,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) { } -void lb_build_stmt_list(lbProcedure *p, Array const &stmts) { +void lb_build_stmt_list(lbProcedure *p, Slice const &stmts) { for_array(i, stmts) { Ast *stmt = stmts[i]; switch (stmt->kind) { @@ -3865,7 +3865,7 @@ void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss) { ast_node(body, BlockStmt, ss->body); - Array default_stmts = {}; + Slice default_stmts = {}; lbBlock *default_fall = nullptr; lbBlock *default_block = nullptr; diff --git a/src/parser.cpp b/src/parser.cpp index 476504d52..cf464f149 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -126,7 +126,7 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { } Ast *clone_ast(Ast *node); -Array clone_ast_array(Array array) { +Array clone_ast_array(Array const &array) { Array result = {}; if (array.count > 0) { result = array_make(ast_allocator(nullptr), array.count); @@ -136,6 +136,16 @@ Array clone_ast_array(Array array) { } return result; } +Slice clone_ast_array(Slice const &array) { + Slice result = {}; + if (array.count > 0) { + result = slice_clone(permanent_allocator(), array); + for_array(i, array) { + result[i] = clone_ast(array[i]); + } + } + return result; +} Ast *clone_ast(Ast *node) { if (node == nullptr) { @@ -537,10 +547,10 @@ Ast *ast_paren_expr(AstFile *f, Ast *expr, Token open, Token close) { return result; } -Ast *ast_call_expr(AstFile *f, Ast *proc, Array args, Token open, Token close, Token ellipsis) { +Ast *ast_call_expr(AstFile *f, Ast *proc, Array const &args, Token open, Token close, Token ellipsis) { Ast *result = alloc_ast_node(f, Ast_CallExpr); result->CallExpr.proc = proc; - result->CallExpr.args = args; + result->CallExpr.args = slice_from_array(args); result->CallExpr.open = open; result->CallExpr.close = close; result->CallExpr.ellipsis = ellipsis; @@ -624,7 +634,8 @@ Ast *ast_undef(AstFile *f, Token token) { Ast *ast_basic_lit(AstFile *f, Token basic_lit) { Ast *result = alloc_ast_node(f, Ast_BasicLit); result->BasicLit.token = basic_lit; - result->BasicLit.value = exact_value_from_basic_literal(basic_lit); + result->tav.mode = Addressing_Constant; + result->tav.value = exact_value_from_basic_literal(basic_lit); return result; } @@ -643,12 +654,12 @@ Ast *ast_ellipsis(AstFile *f, Token token, Ast *expr) { } -Ast *ast_proc_group(AstFile *f, Token token, Token open, Token close, Array args) { +Ast *ast_proc_group(AstFile *f, Token token, Token open, Token close, Array const &args) { Ast *result = alloc_ast_node(f, Ast_ProcGroup); result->ProcGroup.token = token; result->ProcGroup.open = open; result->ProcGroup.close = close; - result->ProcGroup.args = args; + result->ProcGroup.args = slice_from_array(args); return result; } @@ -658,7 +669,7 @@ Ast *ast_proc_lit(AstFile *f, Ast *type, Ast *body, u64 tags, Token where_token, result->ProcLit.body = body; result->ProcLit.tags = tags; result->ProcLit.where_token = where_token; - result->ProcLit.where_clauses = where_clauses; + result->ProcLit.where_clauses = slice_from_array(where_clauses); return result; } @@ -670,10 +681,10 @@ Ast *ast_field_value(AstFile *f, Ast *field, Ast *value, Token eq) { return result; } -Ast *ast_compound_lit(AstFile *f, Ast *type, Array elems, Token open, Token close) { +Ast *ast_compound_lit(AstFile *f, Ast *type, Array const &elems, Token open, Token close) { Ast *result = alloc_ast_node(f, Ast_CompoundLit); result->CompoundLit.type = type; - result->CompoundLit.elems = elems; + result->CompoundLit.elems = slice_from_array(elems); result->CompoundLit.open = open; result->CompoundLit.close = close; return result; @@ -736,7 +747,7 @@ Ast *ast_inline_asm_expr(AstFile *f, Token token, Token open, Token close, result->InlineAsmExpr.token = token; result->InlineAsmExpr.open = open; result->InlineAsmExpr.close = close; - result->InlineAsmExpr.param_types = param_types; + result->InlineAsmExpr.param_types = slice_from_array(param_types); result->InlineAsmExpr.return_type = return_type; result->InlineAsmExpr.asm_string = asm_string; result->InlineAsmExpr.constraints_string = constraints_string; @@ -768,18 +779,18 @@ Ast *ast_expr_stmt(AstFile *f, Ast *expr) { return result; } -Ast *ast_assign_stmt(AstFile *f, Token op, Array lhs, Array rhs) { +Ast *ast_assign_stmt(AstFile *f, Token op, Array const &lhs, Array const &rhs) { Ast *result = alloc_ast_node(f, Ast_AssignStmt); result->AssignStmt.op = op; - result->AssignStmt.lhs = lhs; - result->AssignStmt.rhs = rhs; + result->AssignStmt.lhs = slice_from_array(lhs); + result->AssignStmt.rhs = slice_from_array(rhs); return result; } -Ast *ast_block_stmt(AstFile *f, Array stmts, Token open, Token close) { +Ast *ast_block_stmt(AstFile *f, Array const &stmts, Token open, Token close) { Ast *result = alloc_ast_node(f, Ast_BlockStmt); - result->BlockStmt.stmts = stmts; + result->BlockStmt.stmts = slice_from_array(stmts); result->BlockStmt.open = open; result->BlockStmt.close = close; return result; @@ -805,10 +816,10 @@ Ast *ast_when_stmt(AstFile *f, Token token, Ast *cond, Ast *body, Ast *else_stmt } -Ast *ast_return_stmt(AstFile *f, Token token, Array results) { +Ast *ast_return_stmt(AstFile *f, Token token, Array const &results) { Ast *result = alloc_ast_node(f, Ast_ReturnStmt); result->ReturnStmt.token = token; - result->ReturnStmt.results = results; + result->ReturnStmt.results = slice_from_array(results); return result; } @@ -866,11 +877,11 @@ Ast *ast_type_switch_stmt(AstFile *f, Token token, Ast *tag, Ast *body) { return result; } -Ast *ast_case_clause(AstFile *f, Token token, Array list, Array stmts) { +Ast *ast_case_clause(AstFile *f, Token token, Array const &list, Array const &stmts) { Ast *result = alloc_ast_node(f, Ast_CaseClause); result->CaseClause.token = token; - result->CaseClause.list = list; - result->CaseClause.stmts = stmts; + result->CaseClause.list = slice_from_array(list); + result->CaseClause.stmts = slice_from_array(stmts); return result; } @@ -889,10 +900,10 @@ Ast *ast_branch_stmt(AstFile *f, Token token, Ast *label) { return result; } -Ast *ast_using_stmt(AstFile *f, Token token, Array list) { +Ast *ast_using_stmt(AstFile *f, Token token, Array const &list) { Ast *result = alloc_ast_node(f, Ast_UsingStmt); result->UsingStmt.token = token; - result->UsingStmt.list = list; + result->UsingStmt.list = slice_from_array(list); return result; } @@ -905,10 +916,10 @@ Ast *ast_bad_decl(AstFile *f, Token begin, Token end) { return result; } -Ast *ast_field(AstFile *f, Array names, Ast *type, Ast *default_value, u32 flags, Token tag, +Ast *ast_field(AstFile *f, Array const &names, Ast *type, Ast *default_value, u32 flags, Token tag, CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_Field); - result->Field.names = names; + result->Field.names = slice_from_array(names); result->Field.type = type; result->Field.default_value = default_value; result->Field.flags = flags; @@ -918,10 +929,10 @@ Ast *ast_field(AstFile *f, Array names, Ast *type, Ast *default_value, u3 return result; } -Ast *ast_field_list(AstFile *f, Token token, Array list) { +Ast *ast_field_list(AstFile *f, Token token, Array const &list) { Ast *result = alloc_ast_node(f, Ast_FieldList); result->FieldList.token = token; - result->FieldList.list = list; + result->FieldList.list = slice_from_array(list); return result; } @@ -1002,7 +1013,7 @@ Ast *ast_dynamic_array_type(AstFile *f, Token token, Ast *elem) { return result; } -Ast *ast_struct_type(AstFile *f, Token token, Array fields, isize field_count, +Ast *ast_struct_type(AstFile *f, Token token, Slice fields, isize field_count, Ast *polymorphic_params, bool is_packed, bool is_raw_union, Ast *align, Token where_token, Array const &where_clauses) { @@ -1015,38 +1026,38 @@ Ast *ast_struct_type(AstFile *f, Token token, Array fields, isize field_c result->StructType.is_raw_union = is_raw_union; result->StructType.align = align; result->StructType.where_token = where_token; - result->StructType.where_clauses = where_clauses; + result->StructType.where_clauses = slice_from_array(where_clauses); return result; } -Ast *ast_union_type(AstFile *f, Token token, Array variants, Ast *polymorphic_params, Ast *align, bool no_nil, bool maybe, +Ast *ast_union_type(AstFile *f, Token token, Array const &variants, Ast *polymorphic_params, Ast *align, bool no_nil, bool maybe, Token where_token, Array const &where_clauses) { Ast *result = alloc_ast_node(f, Ast_UnionType); result->UnionType.token = token; - result->UnionType.variants = variants; + result->UnionType.variants = slice_from_array(variants); result->UnionType.polymorphic_params = polymorphic_params; result->UnionType.align = align; result->UnionType.no_nil = no_nil; - result->UnionType.maybe = maybe; + result->UnionType.maybe = maybe; result->UnionType.where_token = where_token; - result->UnionType.where_clauses = where_clauses; + result->UnionType.where_clauses = slice_from_array(where_clauses); return result; } -Ast *ast_enum_type(AstFile *f, Token token, Ast *base_type, Array fields) { +Ast *ast_enum_type(AstFile *f, Token token, Ast *base_type, Array const &fields) { Ast *result = alloc_ast_node(f, Ast_EnumType); result->EnumType.token = token; result->EnumType.base_type = base_type; - result->EnumType.fields = fields; + result->EnumType.fields = slice_from_array(fields); return result; } -Ast *ast_bit_field_type(AstFile *f, Token token, Array fields, Ast *align) { +Ast *ast_bit_field_type(AstFile *f, Token token, Array const &fields, Ast *align) { Ast *result = alloc_ast_node(f, Ast_BitFieldType); result->BitFieldType.token = token; - result->BitFieldType.fields = fields; + result->BitFieldType.fields = slice_from_array(fields); result->BitFieldType.align = align; return result; } @@ -1069,7 +1080,7 @@ Ast *ast_map_type(AstFile *f, Token token, Ast *key, Ast *value) { Ast *ast_foreign_block_decl(AstFile *f, Token token, Ast *foreign_library, Ast *body, - CommentGroup *docs) { + CommentGroup *docs) { Ast *result = alloc_ast_node(f, Ast_ForeignBlockDecl); result->ForeignBlockDecl.token = token; result->ForeignBlockDecl.foreign_library = foreign_library; @@ -1087,12 +1098,12 @@ Ast *ast_label_decl(AstFile *f, Token token, Ast *name) { return result; } -Ast *ast_value_decl(AstFile *f, Array names, Ast *type, Array values, bool is_mutable, +Ast *ast_value_decl(AstFile *f, Array const &names, Ast *type, Array const &values, bool is_mutable, CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ValueDecl); - result->ValueDecl.names = names; + result->ValueDecl.names = slice_from_array(names); result->ValueDecl.type = type; - result->ValueDecl.values = values; + result->ValueDecl.values = slice_from_array(values); result->ValueDecl.is_mutable = is_mutable; result->ValueDecl.docs = docs; result->ValueDecl.comment = comment; @@ -1126,7 +1137,7 @@ Ast *ast_foreign_import_decl(AstFile *f, Token token, Array filepaths, To CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl); result->ForeignImportDecl.token = token; - result->ForeignImportDecl.filepaths = filepaths; + result->ForeignImportDecl.filepaths = slice_from_array(filepaths); result->ForeignImportDecl.library_name = library_name; result->ForeignImportDecl.docs = docs; result->ForeignImportDecl.comment = comment; @@ -1136,11 +1147,11 @@ Ast *ast_foreign_import_decl(AstFile *f, Token token, Array filepaths, To } -Ast *ast_attribute(AstFile *f, Token token, Token open, Token close, Array elems) { +Ast *ast_attribute(AstFile *f, Token token, Token open, Token close, Array const &elems) { Ast *result = alloc_ast_node(f, Ast_Attribute); result->Attribute.token = token; result->Attribute.open = open; - result->Attribute.elems = elems; + result->Attribute.elems = slice_from_array(elems); result->Attribute.close = close; return result; } @@ -1192,7 +1203,7 @@ CommentGroup *consume_comment_group(AstFile *f, isize n, isize *end_line_) { CommentGroup *comments = nullptr; if (list.count > 0) { comments = gb_alloc_item(heap_allocator(), CommentGroup); - comments->list = list; + comments->list = slice_from_array(list); array_add(&f->comments, comments); } return comments; @@ -2181,7 +2192,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { Ast *fields = parse_struct_field_list(f, &name_count); Token close = expect_token(f, Token_CloseBrace); - Array decls = {}; + Slice decls = {}; if (fields != nullptr) { GB_ASSERT(fields->kind == Ast_FieldList); decls = fields->FieldList.list; @@ -4887,7 +4898,7 @@ bool determine_path_from_string(gbMutex *file_mutex, Ast *node, String base_dir, -void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array &decls); +void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Slice &decls); void parse_setup_file_when_stmt(Parser *p, AstFile *f, String base_dir, AstWhenStmt *ws) { if (ws->body != nullptr) { @@ -4908,7 +4919,7 @@ void parse_setup_file_when_stmt(Parser *p, AstFile *f, String base_dir, AstWhenS } } -void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array &decls) { +void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Slice &decls) { for_array(i, decls) { Ast *node = decls[i]; if (!is_ast_decl(node) && @@ -4947,8 +4958,7 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array } else if (node->kind == Ast_ForeignImportDecl) { ast_node(fl, ForeignImportDecl, node); - fl->fullpaths.allocator = heap_allocator(); - array_reserve(&fl->fullpaths, fl->filepaths.count); + auto fullpaths = array_make(permanent_allocator(), 0, fl->filepaths.count); for_array(fp_idx, fl->filepaths) { String file_str = fl->filepaths[fp_idx].string; @@ -4962,14 +4972,17 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array } fullpath = foreign_path; } - array_add(&fl->fullpaths, fullpath); + array_add(&fullpaths, fullpath); } - if (fl->fullpaths.count == 0) { + if (fullpaths.count == 0) { syntax_error(decls[i], "No foreign paths found"); decls[i] = ast_bad_decl(f, fl->filepaths[0], fl->filepaths[fl->filepaths.count-1]); goto end; } + fl->fullpaths = slice_from_array(fullpaths); + + } else if (node->kind == Ast_WhenStmt) { ast_node(ws, WhenStmt, node); parse_setup_file_when_stmt(p, f, base_dir, ws); @@ -5131,12 +5144,12 @@ bool parse_file(Parser *p, AstFile *f) { f->pkg_decl = pd; if (f->error_count == 0) { - f->decls = array_make(heap_allocator()); + auto decls = array_make(heap_allocator()); while (f->curr_token.kind != Token_EOF) { Ast *stmt = parse_stmt(f); if (stmt && stmt->kind != Ast_EmptyStmt) { - array_add(&f->decls, stmt); + array_add(&decls, stmt); if (stmt->kind == Ast_ExprStmt && stmt->ExprStmt.expr != nullptr && stmt->ExprStmt.expr->kind == Ast_ProcLit) { @@ -5145,6 +5158,8 @@ bool parse_file(Parser *p, AstFile *f) { } } + f->decls = slice_from_array(decls); + parse_setup_file_decls(p, f, base_dir, f->decls); } diff --git a/src/parser.hpp b/src/parser.hpp index 9a7ddd4b9..3be7939fa 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -46,7 +46,7 @@ enum ParseFileError { }; struct CommentGroup { - Array list; // Token_Comment + Slice list; // Token_Comment }; @@ -98,8 +98,8 @@ struct AstFile { bool in_foreign_block; bool allow_type; - Array decls; - Array imports; // 'import' 'using import' + Slice decls; + Array imports; // 'import' isize directive_count; Ast * curr_proc; @@ -277,7 +277,6 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { AST_KIND(Undef, "undef", Token) \ AST_KIND(BasicLit, "basic literal", struct { \ Token token; \ - ExactValue value; \ }) \ AST_KIND(BasicDirective, "basic directive", struct { \ Token token; \ @@ -291,7 +290,7 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { Token token; \ Token open; \ Token close; \ - Array args; \ + Slice args; \ }) \ AST_KIND(ProcLit, "procedure literal", struct { \ Ast *type; \ @@ -299,12 +298,12 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { u64 tags; \ ProcInlining inlining; \ Token where_token; \ - Array where_clauses; \ + Slice where_clauses; \ DeclInfo *decl; \ }) \ AST_KIND(CompoundLit, "compound literal", struct { \ Ast *type; \ - Array elems; \ + Slice elems; \ Token open, close; \ i64 max_count; \ }) \ @@ -327,7 +326,7 @@ AST_KIND(_ExprBegin, "", bool) \ }) \ AST_KIND(CallExpr, "call expression", struct { \ Ast * proc; \ - Array args; \ + Slice args; \ Token open; \ Token close; \ Token ellipsis; \ @@ -344,7 +343,7 @@ AST_KIND(_ExprBegin, "", bool) \ AST_KIND(InlineAsmExpr, "inline asm expression", struct { \ Token token; \ Token open, close; \ - Array param_types; \ + Slice param_types; \ Ast *return_type; \ Ast *asm_string; \ Ast *constraints_string; \ @@ -364,11 +363,11 @@ AST_KIND(_StmtBegin, "", bool) \ }) \ AST_KIND(AssignStmt, "assign statement", struct { \ Token op; \ - Array lhs, rhs; \ + Slice lhs, rhs; \ }) \ AST_KIND(_ComplexStmtBegin, "", bool) \ AST_KIND(BlockStmt, "block statement", struct { \ - Array stmts; \ + Slice stmts; \ Ast *label; \ Token open, close; \ }) \ @@ -390,7 +389,7 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ }) \ AST_KIND(ReturnStmt, "return statement", struct { \ Token token; \ - Array results; \ + Slice results; \ }) \ AST_KIND(ForStmt, "for statement", struct { \ Token token; \ @@ -420,8 +419,8 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ }) \ AST_KIND(CaseClause, "case clause", struct { \ Token token; \ - Array list; \ - Array stmts; \ + Slice list; \ + Slice stmts; \ Entity *implicit_entity; \ }) \ AST_KIND(SwitchStmt, "switch statement", struct { \ @@ -438,12 +437,12 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ Ast *tag; \ Ast *body; \ bool partial; \ -}) \ + }) \ AST_KIND(DeferStmt, "defer statement", struct { Token token; Ast *stmt; }) \ AST_KIND(BranchStmt, "branch statement", struct { Token token; Ast *label; }) \ AST_KIND(UsingStmt, "using statement", struct { \ Token token; \ - Array list; \ + Slice list; \ }) \ AST_KIND(_ComplexStmtEnd, "", bool) \ AST_KIND(_StmtEnd, "", bool) \ @@ -461,9 +460,9 @@ AST_KIND(_DeclBegin, "", bool) \ Ast *name; \ }) \ AST_KIND(ValueDecl, "value declaration", struct { \ - Array names; \ + Slice names; \ Ast * type; \ - Array values; \ + Slice values; \ Array attributes; \ CommentGroup *docs; \ CommentGroup *comment; \ @@ -488,10 +487,10 @@ AST_KIND(_DeclBegin, "", bool) \ }) \ AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \ Token token; \ - Array filepaths; \ + Slice filepaths; \ Token library_name; \ String collection_name; \ - Array fullpaths; \ + Slice fullpaths; \ Array attributes; \ CommentGroup *docs; \ CommentGroup *comment; \ @@ -499,11 +498,11 @@ AST_KIND(_DeclBegin, "", bool) \ AST_KIND(_DeclEnd, "", bool) \ AST_KIND(Attribute, "attribute", struct { \ Token token; \ - Array elems; \ + Slice elems; \ Token open, close; \ }) \ AST_KIND(Field, "field", struct { \ - Array names; \ + Slice names; \ Ast * type; \ Ast * default_value; \ Token tag; \ @@ -513,7 +512,7 @@ AST_KIND(_DeclEnd, "", bool) \ }) \ AST_KIND(FieldList, "field list", struct { \ Token token; \ - Array list; \ + Slice list; \ }) \ AST_KIND(_TypeBegin, "", bool) \ AST_KIND(TypeidType, "typeid", struct { \ @@ -567,34 +566,34 @@ AST_KIND(_TypeBegin, "", bool) \ }) \ AST_KIND(StructType, "struct type", struct { \ Token token; \ - Array fields; \ + Slice fields; \ isize field_count; \ Ast *polymorphic_params; \ Ast *align; \ Token where_token; \ - Array where_clauses; \ + Slice where_clauses; \ bool is_packed; \ bool is_raw_union; \ }) \ AST_KIND(UnionType, "union type", struct { \ Token token; \ - Array variants; \ + Slice variants; \ Ast *polymorphic_params; \ Ast * align; \ bool maybe; \ bool no_nil; \ Token where_token; \ - Array where_clauses; \ + Slice where_clauses; \ }) \ AST_KIND(EnumType, "enum type", struct { \ Token token; \ Ast * base_type; \ - Array fields; /* FieldValue */ \ + Slice fields; /* FieldValue */ \ bool is_using; \ }) \ AST_KIND(BitFieldType, "bit field type", struct { \ Token token; \ - Array fields; /* FieldValue with : */ \ + Slice fields; /* FieldValue with : */ \ Ast * align; \ }) \ AST_KIND(BitSetType, "bit set type", struct { \ -- cgit v1.2.3 From 6f71d1f2a97887d7039c4e4cc39477a1f474ccae Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 12:10:25 +0000 Subject: Add `-show-unused` (Shows unused package declarations of all imported packages) Crude output at the moment but better than nothing --- src/build_settings.cpp | 1 + src/check_decl.cpp | 3 +- src/checker.cpp | 28 +++------ src/checker.hpp | 13 ++-- src/main.cpp | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.cpp | 6 +- src/ptr_set.cpp | 29 ++++++++- 7 files changed, 207 insertions(+), 32 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4f06c2913..5c1babe0c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -143,6 +143,7 @@ struct BuildContext { bool generate_docs; i32 optimization_level; bool show_timings; + bool show_unused; bool show_more_timings; bool show_system_calls; bool keep_temp_files; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index da07fe4bc..5234955fb 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1007,11 +1007,10 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) continue; } - if (ptr_set_exists(&entity_set, e)) { + if (ptr_set_update(&entity_set, e)) { error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string)); continue; } - ptr_set_add(&entity_set, e); array_add(&pge->entities, e); } diff --git a/src/checker.cpp b/src/checker.cpp index f02b927c3..f8018506c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -700,7 +700,7 @@ void init_universal(void) { builtin_pkg->kind = Package_Normal; builtin_pkg->scope = create_scope(nullptr); - builtin_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; + builtin_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin; builtin_pkg->scope->pkg = builtin_pkg; intrinsics_pkg = gb_alloc_item(a, AstPackage); @@ -708,7 +708,7 @@ void init_universal(void) { intrinsics_pkg->kind = Package_Normal; intrinsics_pkg->scope = create_scope(nullptr); - intrinsics_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; + intrinsics_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin; intrinsics_pkg->scope->pkg = intrinsics_pkg; config_pkg = gb_alloc_item(a, AstPackage); @@ -716,7 +716,7 @@ void init_universal(void) { config_pkg->kind = Package_Normal; config_pkg->scope = create_scope(nullptr); - config_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; + config_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin; config_pkg->scope->pkg = config_pkg; @@ -1501,11 +1501,10 @@ void add_min_dep_type_info(Checker *c, Type *t) { ti_index = type_info_index(&c->info, t, false); } GB_ASSERT(ti_index >= 0); - if (ptr_set_exists(set, ti_index)) { + if (ptr_set_update(set, ti_index)) { // Type Already exists return; } - ptr_set_add(set, ti_index); // Add nested types if (t->kind == Type_Named) { @@ -1688,12 +1687,10 @@ void add_dependency_to_set(Checker *c, Entity *entity) { } } - if (ptr_set_exists(set, entity)) { + if (ptr_set_update(set, entity)) { return; } - - ptr_set_add(set, entity); DeclInfo *decl = decl_info_of_entity(entity); if (decl == nullptr) { return; @@ -3567,11 +3564,9 @@ struct ImportPathItem { Array find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet *visited) { Array empty_path = {}; - if (ptr_set_exists(visited, start)) { + if (ptr_set_update(visited, start)) { return empty_path; } - ptr_set_add(visited, start); - String path = start->fullpath; AstPackage **found = string_map_get(&c->info.packages, path); @@ -3657,10 +3652,8 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { GB_ASSERT(scope->flags&ScopeFlag_Pkg); - if (ptr_set_exists(&parent_scope->imported, scope)) { + if (ptr_set_update(&parent_scope->imported, scope)) { // error(token, "Multiple import of the same file within this scope"); - } else { - ptr_set_add(&parent_scope->imported, scope); } String import_name = path_to_entity_name(id->import_name.string, id->fullpath, false); @@ -4013,10 +4006,9 @@ void check_import_entities(Checker *c) { if (pkg == nullptr) { continue; } - if (ptr_set_exists(&emitted, pkg)) { + if (ptr_set_update(&emitted, pkg)) { continue; } - ptr_set_add(&emitted, pkg); array_add(&package_order, n); } @@ -4259,11 +4251,9 @@ void calculate_global_init_order(Checker *c) { // if (!decl_info_has_init(d)) { // continue; // } - if (ptr_set_exists(&emitted, d)) { + if (ptr_set_update(&emitted, d)) { continue; } - ptr_set_add(&emitted, d); - array_add(&info->variable_init_order, d); } diff --git a/src/checker.hpp b/src/checker.hpp index 9c9b77ac3..e672a477b 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -160,12 +160,13 @@ struct ProcInfo { enum ScopeFlag : i32 { - ScopeFlag_Pkg = 1<<1, - ScopeFlag_Global = 1<<2, - ScopeFlag_File = 1<<3, - ScopeFlag_Init = 1<<4, - ScopeFlag_Proc = 1<<5, - ScopeFlag_Type = 1<<6, + ScopeFlag_Pkg = 1<<1, + ScopeFlag_Builtin = 1<<2, + ScopeFlag_Global = 1<<3, + ScopeFlag_File = 1<<4, + ScopeFlag_Init = 1<<5, + ScopeFlag_Proc = 1<<6, + ScopeFlag_Type = 1<<7, ScopeFlag_HasBeenImported = 1<<10, // This is only applicable to file scopes diff --git a/src/main.cpp b/src/main.cpp index 67dc5da00..17477384e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -568,6 +568,7 @@ enum BuildFlagKind { BuildFlag_OutFile, BuildFlag_OptimizationLevel, BuildFlag_ShowTimings, + BuildFlag_ShowUnused, BuildFlag_ShowMoreTimings, BuildFlag_ShowSystemCalls, BuildFlag_ThreadCount, @@ -669,6 +670,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); @@ -860,6 +862,14 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_timings = true; break; + case BuildFlag_ShowUnused: + GB_ASSERT(value.kind == ExactValue_Invalid); + build_context.show_unused = true; + if (build_context.command != "check") { + gb_printf_err("%.*s is only allowed with 'odin check'\n", LIT(name)); + bad_flags = true; + } + break; case BuildFlag_ShowMoreTimings: GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_timings = true; @@ -1487,6 +1497,7 @@ void print_show_help(String const arg0, String const &command) { bool build = command == "build"; bool run_or_build = command == "run" || command == "build"; + bool check_only = command == "check"; bool check = command == "run" || command == "build" || command == "check"; print_usage_line(0, ""); @@ -1521,6 +1532,12 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); } + if (check_only) { + print_usage_line(1, "-show-unused"); + print_usage_line(2, "Shows unused package declarations within the current project"); + print_usage_line(0, ""); + } + if (run_or_build) { print_usage_line(1, "-keep-temp-files"); print_usage_line(2, "Keeps the temporary files generated during compilation"); @@ -1599,6 +1616,23 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-extra-linker-flags:"); print_usage_line(2, "Adds extra linker specific flags in a string"); print_usage_line(0, ""); + + print_usage_line(1, "-microarch:"); + print_usage_line(2, "Specifies the specific micro-architecture for the build in a string"); + print_usage_line(2, "Examples:"); + print_usage_line(3, "-microarch:sandybridge"); + print_usage_line(3, "-microarch:native"); + print_usage_line(0, ""); + } + + if (check) { + print_usage_line(1, "-disallow-do"); + print_usage_line(2, "Disallows the 'do' keyword in the project"); + print_usage_line(0, ""); + + print_usage_line(1, "-default-to-nil-allocator"); + print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing"); + print_usage_line(0, ""); } if (run_or_build) { @@ -1632,6 +1666,127 @@ void print_show_help(String const arg0, String const &command) { } } +int unused_entity_kind_ordering[Entity_Count] = { + /*Invalid*/ -1, + /*Constant*/ 0, + /*Variable*/ 1, + /*TypeName*/ 4, + /*Procedure*/ 2, + /*ProcGroup*/ 3, + /*Builtin*/ -1, + /*ImportName*/ -1, + /*LibraryName*/ -1, + /*Nil*/ -1, + /*Label*/ -1, +}; +char const *unused_entity_names[Entity_Count] = { + /*Invalid*/ "", + /*Constant*/ "constants", + /*Variable*/ "variables", + /*TypeName*/ "types", + /*Procedure*/ "procedures", + /*ProcGroup*/ "proc_group", + /*Builtin*/ "", + /*ImportName*/ "import names", + /*LibraryName*/ "library names", + /*Nil*/ "", + /*Label*/ "", +}; + + +GB_COMPARE_PROC(cmp_entities_for_unused) { + GB_ASSERT(a != nullptr); + GB_ASSERT(b != nullptr); + Entity *x = *cast(Entity **)a; + Entity *y = *cast(Entity **)b; + int res = 0; + res = string_compare(x->pkg->name, y->pkg->name); + if (res != 0) { + return res; + } + int ox = unused_entity_kind_ordering[x->kind]; + int oy = unused_entity_kind_ordering[y->kind]; + if (ox < oy) { + return -1; + } else if (ox > oy) { + return +1; + } + res = string_compare(x->token.string, y->token.string); + return res; +} + + +void print_show_unused(Checker *c) { + CheckerInfo *info = &c->info; + + auto unused = array_make(permanent_allocator(), 0, info->entities.count); + for_array(i, info->entities) { + Entity *e = info->entities[i]; + if (e == nullptr) { + continue; + } + if (e->pkg == nullptr || e->pkg->scope == nullptr) { + continue; + } + if (e->pkg->scope->flags & ScopeFlag_Builtin) { + continue; + } + switch (e->kind) { + case Entity_Invalid: + case Entity_Builtin: + case Entity_Nil: + case Entity_Label: + continue; + case Entity_Constant: + case Entity_Variable: + case Entity_TypeName: + case Entity_Procedure: + case Entity_ProcGroup: + case Entity_ImportName: + case Entity_LibraryName: + // Fine + break; + } + if ((e->scope->flags & (ScopeFlag_Pkg|ScopeFlag_File)) == 0) { + continue; + } + if (e->token.string.len == 0) { + continue; + } + if (e->token.string == "_") { + continue; + } + if (ptr_set_exists(&info->minimum_dependency_set, e)) { + continue; + } + array_add(&unused, e); + } + + gb_sort_array(unused.data, unused.count, cmp_entities_for_unused); + + print_usage_line(0, "Unused Package Declarations"); + + AstPackage *curr_pkg = nullptr; + EntityKind curr_entity_kind = Entity_Invalid; + for_array(i, unused) { + Entity *e = unused[i]; + if (curr_pkg != e->pkg) { + curr_pkg = e->pkg; + curr_entity_kind = Entity_Invalid; + print_usage_line(0, ""); + print_usage_line(0, "package %.*s", LIT(curr_pkg->name)); + } + if (curr_entity_kind != e->kind) { + curr_entity_kind = e->kind; + print_usage_line(1, "%s", unused_entity_names[e->kind]); + } + // TokenPos pos = e->token.pos; + // print_usage_line(2, "%.*s(%td:%td) %.*s", LIT(pos.file), pos.line, pos.column, LIT(e->token.string)); + print_usage_line(2, "%.*s", LIT(e->token.string)); + } + print_usage_line(0, ""); +} + int main(int arg_count, char const **arg_ptr) { if (arg_count < 2) { usage(make_string_c(arg_ptr[0])); @@ -1821,6 +1976,10 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); if (build_context.no_output_files) { + if (build_context.show_unused) { + print_show_unused(&checker); + } + if (build_context.query_data_set_settings.ok) { generate_and_print_query_data(&checker, timings); } else { diff --git a/src/parser.cpp b/src/parser.cpp index cf464f149..4470f979b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1099,7 +1099,7 @@ Ast *ast_label_decl(AstFile *f, Token token, Ast *name) { } Ast *ast_value_decl(AstFile *f, Array const &names, Ast *type, Array const &values, bool is_mutable, - CommentGroup *docs, CommentGroup *comment) { + CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ValueDecl); result->ValueDecl.names = slice_from_array(names); result->ValueDecl.type = type; @@ -1122,7 +1122,7 @@ Ast *ast_package_decl(AstFile *f, Token token, Token name, CommentGroup *docs, C } Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Token import_name, - CommentGroup *docs, CommentGroup *comment) { + CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ImportDecl); result->ImportDecl.token = token; result->ImportDecl.is_using = is_using; @@ -1134,7 +1134,7 @@ Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Toke } Ast *ast_foreign_import_decl(AstFile *f, Token token, Array filepaths, Token library_name, - CommentGroup *docs, CommentGroup *comment) { + CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl); result->ForeignImportDecl.token = token; result->ForeignImportDecl.filepaths = slice_from_array(filepaths); diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index e75202663..5432fa094 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -24,6 +24,7 @@ struct PtrSet { template void ptr_set_init (PtrSet *s, gbAllocator a, isize capacity = 16); template void ptr_set_destroy(PtrSet *s); template T ptr_set_add (PtrSet *s, T ptr); +template bool ptr_set_update (PtrSet *s, T ptr); // returns true if it previously existsed template bool ptr_set_exists (PtrSet *s, T ptr); template void ptr_set_remove (PtrSet *s, T ptr); template void ptr_set_clear (PtrSet *s); @@ -146,6 +147,29 @@ gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { // Returns true if it already exists template T ptr_set_add(PtrSet *s, T ptr) { + PtrSetIndex index; + PtrSetFindResult fr; + if (s->hashes.count == 0) { + ptr_set_grow(s); + } + fr = ptr_set__find(s, ptr); + if (fr.entry_index == PTR_SET_SENTINEL) { + index = ptr_set__add_entry(s, ptr); + if (fr.entry_prev != PTR_SET_SENTINEL) { + s->entries.data[fr.entry_prev].next = index; + } else { + s->hashes.data[fr.hash_index] = index; + } + } + if (ptr_set__full(s)) { + ptr_set_grow(s); + } + return ptr; +} + +template +bool ptr_set_update(PtrSet *s, T ptr) { // returns true if it previously existsed + bool exists = false; PtrSetIndex index; PtrSetFindResult fr; if (s->hashes.count == 0) { @@ -153,7 +177,7 @@ T ptr_set_add(PtrSet *s, T ptr) { } fr = ptr_set__find(s, ptr); if (fr.entry_index != PTR_SET_SENTINEL) { - index = fr.entry_index; + exists = true; } else { index = ptr_set__add_entry(s, ptr); if (fr.entry_prev != PTR_SET_SENTINEL) { @@ -165,10 +189,11 @@ T ptr_set_add(PtrSet *s, T ptr) { if (ptr_set__full(s)) { ptr_set_grow(s); } - return ptr; + return exists; } + template void ptr_set__erase(PtrSet *s, PtrSetFindResult fr) { PtrSetFindResult last; -- cgit v1.2.3 From d90fc18bef8300da0fc6102d57b9e970bd7fe935 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 15:05:16 +0000 Subject: Basic `odin doc` support --- src/build_settings.cpp | 2 + src/check_expr.cpp | 208 +++++++++++++++++++++++++++++------------------- src/checker.cpp | 4 +- src/checker.hpp | 1 + src/docs.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++++++-- src/exact_value.cpp | 6 +- src/main.cpp | 23 ++++++ src/parser.cpp | 6 +- 8 files changed, 363 insertions(+), 99 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 8cd516505..0e8f2c5bc 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -130,6 +130,7 @@ char const *odin_command_strings[32] = { enum CmdDocFlag : u32 { CmdDocFlag_All = 1<<0, + CmdDocFlag_AllPackages = 1<<1, }; @@ -198,6 +199,7 @@ struct BuildContext { bool linker_map_file; u32 cmd_doc_flags; + Array doc_packages; QueryDataSetSettings query_data_set_settings; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 94a3467d2..f6530df51 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -10208,14 +10208,14 @@ void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) } -gbString write_expr_to_string(gbString str, Ast *node); +gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, params[i]); + str = write_expr_to_string(str, params[i], false); } return str; } @@ -10229,11 +10229,23 @@ gbString string_append_string(gbString str, String string) { gbString string_append_token(gbString str, Token token) { - return string_append_string(str, token.string); + if (token.kind == Token_String) { + str = gb_string_append_rune(str, '"'); + } else if (token.kind == Token_Rune) { + str = gb_string_append_rune(str, '\''); + } + str = string_append_string(str, token.string); + if (token.kind == Token_String) { + str = gb_string_append_rune(str, '"'); + } else if (token.kind == Token_Rune) { + str = gb_string_append_rune(str, '\''); + } + + return str; } -gbString write_expr_to_string(gbString str, Ast *node) { +gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { if (node == nullptr) return str; @@ -10271,21 +10283,30 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, "proc{"); for_array(i, pg->args) { if (i > 0) str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, pg->args[i]); + str = write_expr_to_string(str, pg->args[i], shorthand); } str = gb_string_append_rune(str, '}'); case_end; case_ast_node(pl, ProcLit, node); - str = write_expr_to_string(str, pl->type); + str = write_expr_to_string(str, pl->type, shorthand); + if (pl->body) { + str = gb_string_appendc(str, " {...}"); + } else { + str = gb_string_appendc(str, " ---"); + } case_end; case_ast_node(cl, CompoundLit, node); - str = write_expr_to_string(str, cl->type); + str = write_expr_to_string(str, cl->type, shorthand); str = gb_string_append_rune(str, '{'); - for_array(i, cl->elems) { - if (i > 0) str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, cl->elems[i]); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + for_array(i, cl->elems) { + if (i > 0) str = gb_string_appendc(str, ", "); + str = write_expr_to_string(str, cl->elems[i], shorthand); + } } str = gb_string_append_rune(str, '}'); case_end; @@ -10294,71 +10315,71 @@ gbString write_expr_to_string(gbString str, Ast *node) { case_ast_node(te, TagExpr, node); str = gb_string_append_rune(str, '#'); str = string_append_token(str, te->name); - str = write_expr_to_string(str, te->expr); + str = write_expr_to_string(str, te->expr, shorthand); case_end; case_ast_node(ue, UnaryExpr, node); str = string_append_token(str, ue->op); - str = write_expr_to_string(str, ue->expr); + str = write_expr_to_string(str, ue->expr, shorthand); case_end; case_ast_node(de, DerefExpr, node); - str = write_expr_to_string(str, de->expr); + str = write_expr_to_string(str, de->expr, shorthand); str = gb_string_append_rune(str, '^'); case_end; case_ast_node(be, BinaryExpr, node); - str = write_expr_to_string(str, be->left); + str = write_expr_to_string(str, be->left, shorthand); str = gb_string_append_rune(str, ' '); str = string_append_token(str, be->op); str = gb_string_append_rune(str, ' '); - str = write_expr_to_string(str, be->right); + str = write_expr_to_string(str, be->right, shorthand); case_end; case_ast_node(te, TernaryExpr, node); - str = write_expr_to_string(str, te->cond); + str = write_expr_to_string(str, te->cond, shorthand); str = gb_string_appendc(str, " ? "); - str = write_expr_to_string(str, te->x); + str = write_expr_to_string(str, te->x, shorthand); str = gb_string_appendc(str, " : "); - str = write_expr_to_string(str, te->y); + str = write_expr_to_string(str, te->y, shorthand); case_end; case_ast_node(te, TernaryIfExpr, node); - str = write_expr_to_string(str, te->x); + str = write_expr_to_string(str, te->x, shorthand); str = gb_string_appendc(str, " if "); - str = write_expr_to_string(str, te->cond); + str = write_expr_to_string(str, te->cond, shorthand); str = gb_string_appendc(str, " else "); - str = write_expr_to_string(str, te->y); + str = write_expr_to_string(str, te->y, shorthand); case_end; case_ast_node(te, TernaryWhenExpr, node); - str = write_expr_to_string(str, te->x); + str = write_expr_to_string(str, te->x, shorthand); str = gb_string_appendc(str, " when "); - str = write_expr_to_string(str, te->cond); + str = write_expr_to_string(str, te->cond, shorthand); str = gb_string_appendc(str, " else "); - str = write_expr_to_string(str, te->y); + str = write_expr_to_string(str, te->y, shorthand); case_end; case_ast_node(pe, ParenExpr, node); str = gb_string_append_rune(str, '('); - str = write_expr_to_string(str, pe->expr); + str = write_expr_to_string(str, pe->expr, shorthand); str = gb_string_append_rune(str, ')'); case_end; case_ast_node(se, SelectorExpr, node); - str = write_expr_to_string(str, se->expr); + str = write_expr_to_string(str, se->expr, shorthand); str = string_append_token(str, se->token); - str = write_expr_to_string(str, se->selector); + str = write_expr_to_string(str, se->selector, shorthand); case_end; case_ast_node(se, ImplicitSelectorExpr, node); str = gb_string_append_rune(str, '.'); - str = write_expr_to_string(str, se->selector); + str = write_expr_to_string(str, se->selector, shorthand); case_end; case_ast_node(se, SelectorCallExpr, node); - str = write_expr_to_string(str, se->expr); + str = write_expr_to_string(str, se->expr, shorthand); str = gb_string_appendc(str, "("); ast_node(ce, CallExpr, se->call); isize start = se->modified_call ? 1 : 0; @@ -10367,86 +10388,86 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (i > start) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, arg); + str = write_expr_to_string(str, arg, shorthand); } str = gb_string_appendc(str, ")"); case_end; case_ast_node(ta, TypeAssertion, node); - str = write_expr_to_string(str, ta->expr); + str = write_expr_to_string(str, ta->expr, shorthand); str = gb_string_appendc(str, ".("); - str = write_expr_to_string(str, ta->type); + str = write_expr_to_string(str, ta->type, shorthand); str = gb_string_append_rune(str, ')'); case_end; case_ast_node(tc, TypeCast, node); str = string_append_token(str, tc->token); str = gb_string_append_rune(str, '('); - str = write_expr_to_string(str, tc->type); + str = write_expr_to_string(str, tc->type, shorthand); str = gb_string_append_rune(str, ')'); - str = write_expr_to_string(str, tc->expr); + str = write_expr_to_string(str, tc->expr, shorthand); case_end; case_ast_node(ac, AutoCast, node); str = string_append_token(str, ac->token); str = gb_string_append_rune(str, ' '); - str = write_expr_to_string(str, ac->expr); + str = write_expr_to_string(str, ac->expr, shorthand); case_end; case_ast_node(ie, IndexExpr, node); - str = write_expr_to_string(str, ie->expr); + str = write_expr_to_string(str, ie->expr, shorthand); str = gb_string_append_rune(str, '['); - str = write_expr_to_string(str, ie->index); + str = write_expr_to_string(str, ie->index, shorthand); str = gb_string_append_rune(str, ']'); case_end; case_ast_node(se, SliceExpr, node); - str = write_expr_to_string(str, se->expr); + str = write_expr_to_string(str, se->expr, shorthand); str = gb_string_append_rune(str, '['); - str = write_expr_to_string(str, se->low); + str = write_expr_to_string(str, se->low, shorthand); str = string_append_token(str, se->interval); - str = write_expr_to_string(str, se->high); + str = write_expr_to_string(str, se->high, shorthand); str = gb_string_append_rune(str, ']'); case_end; case_ast_node(e, Ellipsis, node); str = gb_string_appendc(str, ".."); - str = write_expr_to_string(str, e->expr); + str = write_expr_to_string(str, e->expr, shorthand); case_end; case_ast_node(fv, FieldValue, node); - str = write_expr_to_string(str, fv->field); + str = write_expr_to_string(str, fv->field, shorthand); str = gb_string_appendc(str, " = "); - str = write_expr_to_string(str, fv->value); + str = write_expr_to_string(str, fv->value, shorthand); case_end; case_ast_node(ht, HelperType, node); str = gb_string_appendc(str, "#type "); - str = write_expr_to_string(str, ht->type); + str = write_expr_to_string(str, ht->type, shorthand); case_end; case_ast_node(ht, DistinctType, node); str = gb_string_appendc(str, "distinct "); - str = write_expr_to_string(str, ht->type); + str = write_expr_to_string(str, ht->type, shorthand); case_end; case_ast_node(ht, OpaqueType, node); str = gb_string_appendc(str, "opaque "); - str = write_expr_to_string(str, ht->type); + str = write_expr_to_string(str, ht->type, shorthand); case_end; case_ast_node(pt, PolyType, node); str = gb_string_append_rune(str, '$'); - str = write_expr_to_string(str, pt->type); + str = write_expr_to_string(str, pt->type, shorthand); if (pt->specialization != nullptr) { str = gb_string_append_rune(str, '/'); - str = write_expr_to_string(str, pt->specialization); + str = write_expr_to_string(str, pt->specialization, shorthand); } case_end; case_ast_node(pt, PointerType, node); str = gb_string_append_rune(str, '^'); - str = write_expr_to_string(str, pt->type); + str = write_expr_to_string(str, pt->type, shorthand); case_end; case_ast_node(at, ArrayType, node); @@ -10456,40 +10477,44 @@ gbString write_expr_to_string(gbString str, Ast *node) { at->count->UnaryExpr.op.kind == Token_Question) { str = gb_string_appendc(str, "?"); } else { - str = write_expr_to_string(str, at->count); + str = write_expr_to_string(str, at->count, shorthand); } str = gb_string_append_rune(str, ']'); - str = write_expr_to_string(str, at->elem); + str = write_expr_to_string(str, at->elem, shorthand); case_end; case_ast_node(at, DynamicArrayType, node); str = gb_string_appendc(str, "[dynamic]"); - str = write_expr_to_string(str, at->elem); + str = write_expr_to_string(str, at->elem, shorthand); case_end; case_ast_node(bf, BitFieldType, node); str = gb_string_appendc(str, "bit_field "); if (bf->align) { str = gb_string_appendc(str, "#align "); - str = write_expr_to_string(str, bf->align); + str = write_expr_to_string(str, bf->align, shorthand); } str = gb_string_appendc(str, "{"); - str = write_struct_fields_to_string(str, bf->fields); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_struct_fields_to_string(str, bf->fields); + } str = gb_string_appendc(str, "}"); case_end; case_ast_node(bs, BitSetType, node); str = gb_string_appendc(str, "bit_set["); - str = write_expr_to_string(str, bs->elem); + str = write_expr_to_string(str, bs->elem, shorthand); str = gb_string_appendc(str, "]"); case_end; case_ast_node(mt, MapType, node); str = gb_string_appendc(str, "map["); - str = write_expr_to_string(str, mt->key); + str = write_expr_to_string(str, mt->key, shorthand); str = gb_string_append_rune(str, ']'); - str = write_expr_to_string(str, mt->value); + str = write_expr_to_string(str, mt->value, shorthand); case_end; case_ast_node(f, Field, node); @@ -10509,7 +10534,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { for_array(i, f->names) { Ast *name = f->names[i]; if (i > 0) str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, name); + str = write_expr_to_string(str, name, shorthand); } if (f->names.count > 0) { if (f->type == nullptr && f->default_value != nullptr) { @@ -10519,14 +10544,14 @@ gbString write_expr_to_string(gbString str, Ast *node) { } if (f->type != nullptr) { str = gb_string_append_rune(str, ' '); - str = write_expr_to_string(str, f->type); + str = write_expr_to_string(str, f->type, shorthand); } if (f->default_value != nullptr) { if (f->type != nullptr) { str = gb_string_append_rune(str, ' '); } str = gb_string_appendc(str, "= "); - str = write_expr_to_string(str, f->default_value); + str = write_expr_to_string(str, f->default_value, shorthand); } case_end; @@ -10552,7 +10577,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { for_array(i, f->list) { if (i > 0) str = gb_string_appendc(str, ", "); if (has_name) { - str = write_expr_to_string(str, f->list[i]); + str = write_expr_to_string(str, f->list[i], shorthand); } else { ast_node(field, Field, f->list[i]); @@ -10566,7 +10591,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, "#c_vararg "); } - str = write_expr_to_string(str, field->type); + str = write_expr_to_string(str, field->type, shorthand); } } case_end; @@ -10581,7 +10606,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { break; } - str = write_expr_to_string(str, ce->proc); + str = write_expr_to_string(str, ce->proc, shorthand); str = gb_string_appendc(str, "("); for_array(i, ce->args) { @@ -10589,7 +10614,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, arg); + str = write_expr_to_string(str, arg, shorthand); } str = gb_string_appendc(str, ")"); case_end; @@ -10598,17 +10623,17 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, "typeid"); if (tt->specialization) { str = gb_string_appendc(str, "/"); - str = write_expr_to_string(str, tt->specialization); + str = write_expr_to_string(str, tt->specialization, shorthand); } case_end; case_ast_node(pt, ProcType, node); str = gb_string_appendc(str, "proc("); - str = write_expr_to_string(str, pt->params); + str = write_expr_to_string(str, pt->params, shorthand); str = gb_string_appendc(str, ")"); if (pt->results != nullptr) { str = gb_string_appendc(str, " -> "); - str = write_expr_to_string(str, pt->results); + str = write_expr_to_string(str, pt->results, shorthand); } case_end; @@ -10618,7 +10643,11 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (st->is_packed) str = gb_string_appendc(str, "#packed "); if (st->is_raw_union) str = gb_string_appendc(str, "#raw_union "); str = gb_string_append_rune(str, '{'); - str = write_struct_fields_to_string(str, st->fields); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_struct_fields_to_string(str, st->fields); + } str = gb_string_append_rune(str, '}'); case_end; @@ -10626,30 +10655,38 @@ gbString write_expr_to_string(gbString str, Ast *node) { case_ast_node(st, UnionType, node); str = gb_string_appendc(str, "union "); str = gb_string_append_rune(str, '{'); - str = write_struct_fields_to_string(str, st->variants); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_struct_fields_to_string(str, st->variants); + } str = gb_string_append_rune(str, '}'); case_end; case_ast_node(et, EnumType, node); str = gb_string_appendc(str, "enum "); if (et->base_type != nullptr) { - str = write_expr_to_string(str, et->base_type); + str = write_expr_to_string(str, et->base_type, shorthand); str = gb_string_append_rune(str, ' '); } str = gb_string_append_rune(str, '{'); - for_array(i, et->fields) { - if (i > 0) { - str = gb_string_appendc(str, ", "); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + for_array(i, et->fields) { + if (i > 0) { + str = gb_string_appendc(str, ", "); + } + str = write_expr_to_string(str, et->fields[i], shorthand); } - str = write_expr_to_string(str, et->fields[i]); } str = gb_string_append_rune(str, '}'); case_end; case_ast_node(rt, RelativeType, node); - str = write_expr_to_string(str, rt->tag); + str = write_expr_to_string(str, rt->tag, shorthand); str = gb_string_appendc(str, "" ); - str = write_expr_to_string(str, rt->type); + str = write_expr_to_string(str, rt->type, shorthand); case_end; @@ -10659,12 +10696,12 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, ia->param_types[i]); + str = write_expr_to_string(str, ia->param_types[i], shorthand); } str = gb_string_appendc(str, ")"); if (ia->return_type != nullptr) { str = gb_string_appendc(str, " -> "); - str = write_expr_to_string(str, ia->return_type); + str = write_expr_to_string(str, ia->return_type, shorthand); } if (ia->has_side_effects) { str = gb_string_appendc(str, " #side_effects"); @@ -10677,9 +10714,13 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, inline_asm_dialect_strings[ia->dialect]); } str = gb_string_appendc(str, " {"); - str = write_expr_to_string(str, ia->asm_string); - str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, ia->constraints_string); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_expr_to_string(str, ia->asm_string, shorthand); + str = gb_string_appendc(str, ", "); + str = write_expr_to_string(str, ia->constraints_string, shorthand); + } str = gb_string_appendc(str, "}"); case_end; } @@ -10688,5 +10729,8 @@ gbString write_expr_to_string(gbString str, Ast *node) { } gbString expr_to_string(Ast *expression) { - return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression); + return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, false); +} +gbString expr_to_string_shorthand(Ast *expression) { + return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, true); } diff --git a/src/checker.cpp b/src/checker.cpp index f8018506c..8f8aa7381 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3115,6 +3115,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Ast *init_expr = value; DeclInfo *d = make_decl_info(c->scope, c->decl); + d->decl_node = decl; d->entity = e; d->type_expr = vd->type; d->init_expr = init_expr; @@ -3142,9 +3143,10 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Token token = name->Ident.token; Ast *fl = c->foreign_context.curr_library; - DeclInfo *d = make_decl_info(c->scope, c->decl); Entity *e = nullptr; + DeclInfo *d = make_decl_info(c->scope, c->decl); + d->decl_node = decl; d->attributes = vd->attributes; d->type_expr = vd->type; d->init_expr = init; diff --git a/src/checker.hpp b/src/checker.hpp index e672a477b..97469908b 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -132,6 +132,7 @@ struct DeclInfo { Entity *entity; + Ast * decl_node; Ast * type_expr; Ast * init_expr; Array attributes; diff --git a/src/docs.cpp b/src/docs.cpp index 237323af3..76d8c5433 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -59,9 +59,6 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) { } -gbString expr_to_string(Ast *expression); -gbString type_to_string(Type *type); - String alloc_comment_group_string(gbAllocator a, CommentGroup g) { isize len = 0; for_array(i, g.list) { @@ -103,18 +100,216 @@ void print_doc_line(i32 indent, char const *fmt, ...) { va_end(va); gb_printf("\n"); } +void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { + while (indent --> 0) { + gb_printf("\t"); + } + va_list va; + va_start(va, fmt); + gb_printf_va(fmt, va); + va_end(va); +} + +bool print_doc_comment_group_string(i32 indent, CommentGroup const &g) { + isize len = 0; + for_array(i, g.list) { + String comment = g.list[i].string; + len += comment.len; + len += 1; // for \n + } + if (len == 0) { + return false; + } + + isize count = 0; + for_array(i, g.list) { + String comment = g.list[i].string; + if (comment[1] == '/') { + comment.text += 2; + comment.len -= 2; + } else if (comment[1] == '*') { + comment.text += 2; + comment.len -= 4; + } + comment = string_trim_whitespace(comment); + if (string_starts_with(comment, str_lit("@("))) { + continue; + } + + print_doc_line(indent, "%.*s", LIT(comment)); + count += 1; + } + return count > 0; +} + + + + +void print_doc_expr(Ast *expr) { + gbString s = nullptr; + if (build_context.cmd_doc_flags & CmdDocFlag_All) { + s = expr_to_string(expr); + } else { + s = expr_to_string_shorthand(expr); + } + gb_file_write(gb_file_get_standard(gbFileStandard_Output), s, gb_string_length(s)); + gb_string_free(s); +} + void print_doc_package(CheckerInfo *info, AstPackage *pkg) { - print_doc_line(0, "%.*s", LIT(pkg->name)); + if (pkg == nullptr) { + return; + } + + print_doc_line(0, "package %.*s", LIT(pkg->name)); + + if (pkg->scope != nullptr) { + auto entities = array_make(heap_allocator(), 0, pkg->scope->elements.entries.count); + defer (array_free(&entities)); + for_array(i, pkg->scope->elements.entries) { + Entity *e = pkg->scope->elements.entries[i].value; + switch (e->kind) { + case Entity_Invalid: + case Entity_Builtin: + case Entity_Nil: + case Entity_Label: + continue; + case Entity_Constant: + case Entity_Variable: + case Entity_TypeName: + case Entity_Procedure: + case Entity_ProcGroup: + case Entity_ImportName: + case Entity_LibraryName: + // Fine + break; + } + array_add(&entities, e); + } + gb_sort_array(entities.data, entities.count, cmp_entities_for_printing); + + AstPackage *curr_pkg = nullptr; + EntityKind curr_entity_kind = Entity_Invalid; + for_array(i, entities) { + Entity *e = entities[i]; + if (e->pkg != pkg) { + continue; + } + if (!is_entity_exported(e)) { + continue; + } + + if (curr_entity_kind != e->kind) { + curr_entity_kind = e->kind; + print_doc_line(0, ""); + print_doc_line(1, "%s", print_entity_names[e->kind]); + } + + Ast *type_expr = nullptr; + Ast *init_expr = nullptr; + Ast *decl_node = nullptr; + if (e->decl_info != nullptr) { + type_expr = e->decl_info->type_expr; + init_expr = e->decl_info->init_expr; + decl_node = e->decl_info->decl_node; + } + GB_ASSERT(type_expr != nullptr || init_expr != nullptr); + print_doc_line_no_newline(2, "%.*s", LIT(e->token.string)); + if (type_expr != nullptr) { + gbString t = expr_to_string(type_expr); + gb_printf(": %s ", t); + gb_string_free(t); + } else { + gb_printf(" :"); + } + if (e->kind == Entity_Variable) { + if (init_expr != nullptr) { + gb_printf("= "); + print_doc_expr(init_expr); + } + } else { + gb_printf(": "); + print_doc_expr(init_expr); + } + + gb_printf(";\n"); + + + if (decl_node && (true || (build_context.cmd_doc_flags & CmdDocFlag_All))) { + CommentGroup *docs = nullptr; + CommentGroup *comment = nullptr; + switch (decl_node->kind) { + case_ast_node(vd, ValueDecl, decl_node); + docs = vd->docs; + comment = vd->comment; + case_end; + + case_ast_node(id, ImportDecl, decl_node); + docs = id->docs; + comment = id->comment; + case_end; + + case_ast_node(fl, ForeignImportDecl, decl_node); + docs = fl->docs; + comment = fl->comment; + case_end; + + case_ast_node(fb, ForeignBlockDecl, decl_node); + docs = fb->docs; + case_end; + } + if (comment) { + // gb_printf(" "); + } + if (docs) { + if (print_doc_comment_group_string(3, *docs)) { + gb_printf("\n"); + } + } + } + } + print_doc_line(0, ""); + } + + if (pkg->fullpath.len != 0) { + print_doc_line(0, ""); + print_doc_line(1, "fullpath: %.*s", LIT(pkg->fullpath)); + print_doc_line(1, "files:"); + for_array(i, pkg->files) { + AstFile *f = pkg->files[i]; + String filename = remove_directory_from_path(f->fullpath); + print_doc_line(2, "%.*s", LIT(filename)); + } + } + } void generate_documentation(Checker *c) { CheckerInfo *info = &c->info; - if (build_context.cmd_doc_flags & CmdDocFlag_All) { - auto pkgs = array_make(permanent_allocator(), info->packages.entries.count); - for_array(i, info->packages.entries) { - array_add(&pkgs, info->packages.entries[i].value); + if (build_context.doc_packages.count != 0) { + auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); + bool was_error = false; + for_array(j, build_context.doc_packages) { + bool found = false; + String name = build_context.doc_packages[j]; + for_array(i, info->packages.entries) { + AstPackage *pkg = info->packages.entries[i].value; + if (name == pkg->name) { + found = true; + array_add(&pkgs, pkg); + break; + } + } + if (!found) { + gb_printf_err("Unknown package %.*s\n", LIT(name)); + was_error = true; + } + } + if (was_error) { + gb_exit(1); + return; } gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); @@ -126,5 +321,6 @@ void generate_documentation(Checker *c) { GB_ASSERT(info->init_scope->flags & ScopeFlag_Pkg); AstPackage *pkg = info->init_scope->pkg; print_doc_package(info, pkg); + } } diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 9e22c0483..051b6d76a 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -945,7 +945,7 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { Entity *strip_entity_wrapping(Ast *expr); Entity *strip_entity_wrapping(Entity *e); -gbString write_expr_to_string(gbString str, Ast *node); +gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) { switch (v.kind) { @@ -981,9 +981,9 @@ gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize st case ExactValue_Pointer: return str; case ExactValue_Compound: - return write_expr_to_string(str, v.value_compound); + return write_expr_to_string(str, v.value_compound, false); case ExactValue_Procedure: - return write_expr_to_string(str, v.value_procedure); + return write_expr_to_string(str, v.value_procedure, false); } return str; }; diff --git a/src/main.cpp b/src/main.cpp index 45fb9ac85..d6dc3f9b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -598,6 +598,8 @@ enum BuildFlagKind { BuildFlag_GlobalDefinitions, BuildFlag_GoToDefinitions, + BuildFlag_Package, + #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, BuildFlag_ResourceFile, @@ -704,6 +706,8 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_Package, str_lit("package"), BuildFlagParam_String, Command_doc, true); + #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); @@ -1192,6 +1196,15 @@ bool parse_build_flags(Array args) { } break; + case BuildFlag_Package: + GB_ASSERT(value.kind == ExactValue_String); + if (value.value_string.len == 0) { + gb_printf_err("Invalid use of -package flag\n"); + } else { + array_add(&build_context.doc_packages, value.value_string); + } + break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: GB_ASSERT(value.kind == ExactValue_Invalid); @@ -1529,6 +1542,14 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "Flags"); print_usage_line(0, ""); + if (doc) { + print_usage_line(1, "-package:"); + print_usage_line(2, "Add package name to generate documentation for"); + print_usage_line(2, "Multiple flags are allowed"); + print_usage_line(2, "Example: -doc:runtime"); + print_usage_line(0, ""); + } + if (run_or_build) { print_usage_line(1, "-out:"); print_usage_line(2, "Set the file name of the outputted executable"); @@ -1795,6 +1816,8 @@ int main(int arg_count, char const **arg_ptr) { add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); map_init(&build_context.defined_values, heap_allocator()); + build_context.doc_packages.allocator = heap_allocator(); + Array args = setup_args(arg_count, arg_ptr); diff --git a/src/parser.cpp b/src/parser.cpp index 4470f979b..ce5e53d92 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4648,10 +4648,6 @@ void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFi // NOTE(bill): Returns true if it's added bool try_add_import_path(Parser *p, String const &path, String const &rel_path, TokenPos pos, PackageKind kind = Package_Normal) { - if (build_context.generate_docs) { - return false; - } - String const FILE_EXT = str_lit(".odin"); gb_mutex_lock(&p->file_add_mutex); @@ -5253,7 +5249,7 @@ ParseFileError parse_packages(Parser *p, String init_filename) { } TokenPos init_pos = {}; - if (!build_context.generate_docs) { + { String s = get_fullpath_core(heap_allocator(), str_lit("runtime")); try_add_import_path(p, s, s, init_pos, Package_Runtime); } -- cgit v1.2.3 From 34ca4e92eb5316cebb66aa1c69d4ced5719e7773 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 15:45:55 +0000 Subject: Fix parser logic for first comment group line in a file --- src/docs.cpp | 36 +++++++++++++++++++++++++----------- src/parser.cpp | 6 ++++++ 2 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/docs.cpp b/src/docs.cpp index 67e3ebbe5..50586ed8f 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -110,20 +110,23 @@ void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { va_end(va); } -bool print_doc_comment_group_string(i32 indent, CommentGroup const &g) { +bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { + if (g == nullptr) { + return false; + } isize len = 0; - for_array(i, g.list) { - String comment = g.list[i].string; + for_array(i, g->list) { + String comment = g->list[i].string; len += comment.len; len += 1; // for \n } - if (len == 0) { + if (len <= g->list.count) { return false; } isize count = 0; - for_array(i, g.list) { - String comment = g.list[i].string; + for_array(i, g->list) { + String comment = g->list[i].string; if (comment[1] == '/') { comment.text += 2; comment.len -= 2; @@ -131,7 +134,11 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup const &g) { comment.text += 2; comment.len -= 4; } - comment = string_trim_whitespace(comment); + if (comment.len > 0 && comment[0] == ' ') { + comment.text += 1; + comment.len -= 1; + } + if (string_starts_with(comment, str_lit("@("))) { continue; } @@ -164,6 +171,15 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { print_doc_line(0, "package %.*s", LIT(pkg->name)); + + for_array(i, pkg->files) { + AstFile *f = pkg->files[i]; + if (f->pkg_decl) { + GB_ASSERT(f->pkg_decl->kind == Ast_PackageDecl); + print_doc_comment_group_string(1, f->pkg_decl->PackageDecl.docs); + } + } + if (pkg->scope != nullptr) { auto entities = array_make(heap_allocator(), 0, pkg->scope->elements.entries.count); defer (array_free(&entities)); @@ -244,10 +260,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { if (comment) { // gb_printf(" "); } - if (docs) { - if (print_doc_comment_group_string(3, *docs)) { - gb_printf("\n"); - } + if (print_doc_comment_group_string(3, docs)) { + gb_printf("\n"); } } } diff --git a/src/parser.cpp b/src/parser.cpp index ce5e53d92..9e9708f9c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1193,6 +1193,12 @@ CommentGroup *consume_comment_group(AstFile *f, isize n, isize *end_line_) { Array list = {}; list.allocator = heap_allocator(); isize end_line = f->curr_token.pos.line; + if (f->curr_token_index == 1 && + f->prev_token.kind == Token_Comment && + f->prev_token.pos.line+1 == f->curr_token.pos.line) { + // NOTE(bill): Special logic for the first comment in the file + array_add(&list, f->prev_token); + } while (f->curr_token.kind == Token_Comment && f->curr_token.pos.line <= end_line+n) { array_add(&list, consume_comment(f, &end_line)); -- cgit v1.2.3 From 9408eb9580c1663195089ba18a53b704b382e40a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 18 Nov 2020 23:22:27 +0000 Subject: Update `odin doc` to support multiple package outputs by passing multiple paths; Replace `-all` with `-short` Example: odin doc core/path core/path/filepath --- core/path/match.odin | 2 - src/build_settings.cpp | 4 +- src/docs.cpp | 131 ++++++++++++++++++++++++++----------------------- src/main.cpp | 67 +++++++++++++------------ src/parser.cpp | 77 ++++++++++++++++++++++++----- src/parser.hpp | 1 + 6 files changed, 171 insertions(+), 111 deletions(-) (limited to 'src/parser.cpp') diff --git a/core/path/match.odin b/core/path/match.odin index 555c1b05c..e77bf79c3 100644 --- a/core/path/match.odin +++ b/core/path/match.odin @@ -28,8 +28,6 @@ Match_Error :: enum { // match requires that the pattern matches the entirety of the name, not just a substring // The only possible error returned is .Syntax_Error // -// NOTE(bill): This is effectively the shell pattern matching system found -// match :: proc(pattern, name: string) -> (matched: bool, err: Match_Error) { pattern, name := pattern, name; pattern_loop: for len(pattern) > 0 { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 35dc9a7c1..c251cba53 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -130,7 +130,7 @@ char const *odin_command_strings[32] = { enum CmdDocFlag : u32 { - CmdDocFlag_All = 1<<0, + CmdDocFlag_Short = 1<<0, CmdDocFlag_AllPackages = 1<<1, }; @@ -200,7 +200,7 @@ struct BuildContext { bool linker_map_file; u32 cmd_doc_flags; - Array doc_packages; + Array extra_packages; QueryDataSetSettings query_data_set_settings; diff --git a/src/docs.cpp b/src/docs.cpp index d86f85c8d..aa1b89560 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -93,6 +93,8 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { isize count = 0; for_array(i, g->list) { String comment = g->list[i].string; + String original_comment = comment; + bool slash_slash = comment[1] == '/'; bool slash_star = comment[1] == '*'; if (comment[1] == '/') { @@ -113,15 +115,51 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { if (string_starts_with(comment, str_lit("+"))) { continue; } + if (string_starts_with(comment, str_lit("@("))) { + continue; + } } - if (string_starts_with(comment, str_lit("@("))) { - continue; + + if (slash_slash) { + print_doc_line(indent, "%.*s", LIT(comment)); + count += 1; + } else { + isize pos = 0; + for (; pos < comment.len; pos++) { + isize end = pos; + for (; end < comment.len; end++) { + if (comment[end] == '\n') { + break; + } + } + String line = substring(comment, pos, end); + pos = end+1; + String trimmed_line = string_trim_whitespace(line); + if (trimmed_line.len == 0) { + if (count == 0) { + continue; + } + } + /* + * Remove comments with + * styles + * like this + */ + if (string_starts_with(line, str_lit("* "))) { + line = substring(line, 2, line.len); + } + + print_doc_line(indent, "%.*s", LIT(line)); + count += 1; + } } + } - print_doc_line(indent, "%.*s", LIT(comment)); - count += 1; + if (count > 0) { + print_doc_line(0, ""); + return true; } - return count > 0; + return false; } @@ -129,10 +167,10 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { void print_doc_expr(Ast *expr) { gbString s = nullptr; - if (build_context.cmd_doc_flags & CmdDocFlag_All) { - s = expr_to_string(expr); - } else { + if (build_context.cmd_doc_flags & CmdDocFlag_Short) { s = expr_to_string_shorthand(expr); + } else { + s = expr_to_string(expr); } gb_file_write(gb_file_get_standard(gbFileStandard_Output), s, gb_string_length(s)); gb_string_free(s); @@ -151,9 +189,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { AstFile *f = pkg->files[i]; if (f->pkg_decl) { GB_ASSERT(f->pkg_decl->kind == Ast_PackageDecl); - if (print_doc_comment_group_string(1, f->pkg_decl->PackageDecl.docs)) { - print_doc_line(0, ""); - } + print_doc_comment_group_string(1, f->pkg_decl->PackageDecl.docs); } } @@ -182,6 +218,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { } gb_sort_array(entities.data, entities.count, cmp_entities_for_printing); + bool show_docs = (build_context.cmd_doc_flags & CmdDocFlag_Short) == 0; + EntityKind curr_entity_kind = Entity_Invalid; for_array(i, entities) { Entity *e = entities[i]; @@ -192,6 +230,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { continue; } + if (curr_entity_kind != e->kind) { if (curr_entity_kind != Entity_Invalid) { print_doc_line(0, ""); @@ -213,6 +252,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { docs = e->decl_info->docs; } GB_ASSERT(type_expr != nullptr || init_expr != nullptr); + print_doc_line_no_newline(2, "%.*s", LIT(e->token.string)); if (type_expr != nullptr) { gbString t = expr_to_string(type_expr); @@ -233,14 +273,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { gb_printf(";\n"); - - if (build_context.cmd_doc_flags & CmdDocFlag_All) { - if (comment) { - // gb_printf(" "); - } - if (print_doc_comment_group_string(3, docs)) { - gb_printf("\n"); - } + if (show_docs) { + print_doc_comment_group_string(3, docs); } } print_doc_line(0, ""); @@ -248,7 +282,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { if (pkg->fullpath.len != 0) { print_doc_line(0, ""); - print_doc_line(1, "fullpath: %.*s", LIT(pkg->fullpath)); + print_doc_line(1, "fullpath:"); + print_doc_line(2, "%.*s", LIT(pkg->fullpath)); print_doc_line(1, "files:"); for_array(i, pkg->files) { AstFile *f = pkg->files[i]; @@ -262,51 +297,23 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { void generate_documentation(Checker *c) { CheckerInfo *info = &c->info; - if (build_context.doc_packages.count != 0) { - auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); - bool was_error = false; - for_array(j, build_context.doc_packages) { - bool found = false; - String name = build_context.doc_packages[j]; - for_array(i, info->packages.entries) { - AstPackage *pkg = info->packages.entries[i].value; - if (name == pkg->name) { - found = true; - array_add(&pkgs, pkg); - break; - } - } - if (!found) { - gb_printf_err("Unknown package %.*s\n", LIT(name)); - was_error = true; - } - } - if (was_error) { - gb_exit(1); - return; - } - - gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); - - for_array(i, pkgs) { - print_doc_package(info, pkgs[i]); - } - } else if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) { - auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); - for_array(i, info->packages.entries) { - AstPackage *pkg = info->packages.entries[i].value; + auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); + for_array(i, info->packages.entries) { + AstPackage *pkg = info->packages.entries[i].value; + if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) { array_add(&pkgs, pkg); + } else { + if (pkg->kind == Package_Init) { + array_add(&pkgs, pkg); + } else if (pkg->is_extra) { + array_add(&pkgs, pkg); + } } + } - gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); - - for_array(i, pkgs) { - print_doc_package(info, pkgs[i]); - } - } else { - GB_ASSERT(info->init_scope->flags & ScopeFlag_Pkg); - AstPackage *pkg = info->init_scope->pkg; - print_doc_package(info, pkg); + gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); + for_array(i, pkgs) { + print_doc_package(info, pkgs[i]); } } diff --git a/src/main.cpp b/src/main.cpp index 7eef5d2ad..dbade085d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -589,8 +589,7 @@ enum BuildFlagKind { BuildFlag_GlobalDefinitions, BuildFlag_GoToDefinitions, - BuildFlag_Package, - BuildFlag_All, + BuildFlag_Short, BuildFlag_AllPackages, #if defined(GB_SYSTEM_WINDOWS) @@ -699,9 +698,8 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_Package, str_lit("package"), BuildFlagParam_String, Command_doc, true); - add_flag(&build_flags, BuildFlag_All, str_lit("all"), BuildFlagParam_None, Command_doc); - add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); #if defined(GB_SYSTEM_WINDOWS) @@ -852,7 +850,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String path = value.value_string; path = string_trim_whitespace(path); - if (is_import_path_valid(path)) { + if (is_build_flag_path_valid(path)) { #if defined(GB_SYSTEM_WINDOWS) String ext = path_extension(path); if (ext == ".exe") { @@ -1191,22 +1189,15 @@ bool parse_build_flags(Array args) { } break; - case BuildFlag_Package: - GB_ASSERT(value.kind == ExactValue_String); - if (value.value_string.len == 0) { - gb_printf_err("Invalid use of -package flag\n"); - } else { - array_add(&build_context.doc_packages, value.value_string); - } - break; - case BuildFlag_All: - build_context.cmd_doc_flags |= CmdDocFlag_All; + case BuildFlag_Short: + build_context.cmd_doc_flags |= CmdDocFlag_Short; break; case BuildFlag_AllPackages: build_context.cmd_doc_flags |= CmdDocFlag_AllPackages; break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: GB_ASSERT(value.kind == ExactValue_Invalid); @@ -1217,7 +1208,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String path = value.value_string; path = string_trim_whitespace(path); - if (is_import_path_valid(path)) { + if (is_build_flag_path_valid(path)) { if(!string_ends_with(path, str_lit(".rc"))) { gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path)); bad_flags = true; @@ -1235,7 +1226,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String path = value.value_string; path = string_trim_whitespace(path); - if (is_import_path_valid(path)) { + if (is_build_flag_path_valid(path)) { // #if defined(GB_SYSTEM_WINDOWS) // String ext = path_extension(path); // if (ext != ".pdb") { @@ -1299,12 +1290,6 @@ bool parse_build_flags(Array args) { } } - if (build_context.doc_packages.count > 0 && set_flags[BuildFlag_AllPackages]) { - gb_printf_err("'odin doc' does not allow both flags together '-all-packages' and '-package' together");; - bad_flags = true; - } - - if (build_context.query_data_set_settings.ok) { if (build_context.query_data_set_settings.kind == QueryDataSet_Invalid) { gb_printf_err("'odin query' requires a flag determining the kind of query data set to be returned\n"); @@ -1537,6 +1522,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program"); } else if (command == "doc") { print_usage_line(1, "doc generate documentation from a .odin file, or directory of .odin files"); + print_usage_line(2, "Examples:"); + print_usage_line(3, "odin doc core/path"); + print_usage_line(3, "odin doc core/path core/path/filepath"); } else if (command == "version") { print_usage_line(1, "version print version"); } @@ -1552,14 +1540,8 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); if (doc) { - print_usage_line(1, "-all"); - print_usage_line(2, "Show all documentation for the packages"); - print_usage_line(0, ""); - - print_usage_line(1, "-package:"); - print_usage_line(2, "Add package name to generate documentation for"); - print_usage_line(2, "Multiple flags are allowed"); - print_usage_line(2, "Example: -doc:runtime"); + print_usage_line(1, "-short"); + print_usage_line(2, "Show shortened documentation for the packages"); print_usage_line(0, ""); print_usage_line(1, "-all-packages"); @@ -1833,7 +1815,7 @@ int main(int arg_count, char const **arg_ptr) { add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); map_init(&build_context.defined_values, heap_allocator()); - build_context.doc_packages.allocator = heap_allocator(); + build_context.extra_packages.allocator = heap_allocator(); Array args = setup_args(arg_count, arg_ptr); @@ -1904,6 +1886,20 @@ int main(int arg_count, char const **arg_ptr) { build_context.command_kind = Command_doc; init_filename = args[2]; + for (isize i = 3; i < args.count; i++) { + auto arg = args[i]; + if (string_starts_with(arg, str_lit("-"))) { + break; + } + array_add(&build_context.extra_packages, arg); + } + isize extra_count = build_context.extra_packages.count; + if (extra_count > 0) { + gb_memmove(args.data + 3, args.data + 3 + extra_count, extra_count * gb_size_of(*args.data)); + args.count -= extra_count; + } + + build_context.no_output_files = true; build_context.generate_docs = true; build_context.no_entry_point = true; // ignore entry point @@ -2005,8 +2001,11 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); if (build_context.generate_docs) { + if (global_error_collector.count != 0) { + return 1; + } generate_documentation(&checker); - return global_error_collector.count ? 1 : 0; + return 0; } if (build_context.no_output_files) { diff --git a/src/parser.cpp b/src/parser.cpp index 9e9708f9c..ec38dca9b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4653,14 +4653,14 @@ void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFi // NOTE(bill): Returns true if it's added -bool try_add_import_path(Parser *p, String const &path, String const &rel_path, TokenPos pos, PackageKind kind = Package_Normal) { +AstPackage *try_add_import_path(Parser *p, String const &path, String const &rel_path, TokenPos pos, PackageKind kind = Package_Normal) { String const FILE_EXT = str_lit(".odin"); gb_mutex_lock(&p->file_add_mutex); defer (gb_mutex_unlock(&p->file_add_mutex)); if (string_set_exists(&p->imported_files, path)) { - return false; + return nullptr; } string_set_add(&p->imported_files, path); @@ -4683,7 +4683,7 @@ bool try_add_import_path(Parser *p, String const &path, String const &rel_path, pkg->is_single_file = true; parser_add_file_to_process(p, pkg, fi, pos); parser_add_package(p, pkg); - return true; + return pkg; } @@ -4699,22 +4699,22 @@ bool try_add_import_path(Parser *p, String const &path, String const &rel_path, switch (rd_err) { case ReadDirectory_InvalidPath: syntax_error(pos, "Invalid path: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_NotExists: syntax_error(pos, "Path does not exist: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_Permission: syntax_error(pos, "Unknown error whilst reading path %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_NotDir: syntax_error(pos, "Expected a directory for a package, got a file: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_Empty: syntax_error(pos, "Empty directory: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_Unknown: syntax_error(pos, "Unknown error whilst reading path %.*s", LIT(rel_path)); - return false; + return nullptr; } for_array(list_index, list) { @@ -4736,7 +4736,7 @@ bool try_add_import_path(Parser *p, String const &path, String const &rel_path, parser_add_package(p, pkg); - return true; + return pkg; } gb_global Rune illegal_import_runes[] = { @@ -4755,7 +4755,7 @@ bool is_import_path_valid(String path) { u8 *curr = start; while (curr < end) { isize width = 1; - Rune r = curr[0]; + Rune r = *curr; if (r >= 0x80) { width = gb_utf8_decode(curr, end-curr, &r); if (r == GB_RUNE_INVALID && width == 1) { @@ -4780,6 +4780,45 @@ bool is_import_path_valid(String path) { return false; } +bool is_build_flag_path_valid(String path) { + if (path.len > 0) { + u8 *start = path.text; + u8 *end = path.text + path.len; + u8 *curr = start; + isize index = 0; + while (curr < end) { + isize width = 1; + Rune r = *curr; + if (r >= 0x80) { + width = gb_utf8_decode(curr, end-curr, &r); + if (r == GB_RUNE_INVALID && width == 1) { + return false; + } + else if (r == GB_RUNE_BOM && curr-start > 0) { + return false; + } + } + + for (isize i = 0; i < gb_count_of(illegal_import_runes); i++) { +#if defined(GB_SYSTEM_WINDOWS) + if (r == '\\') { + break; + } +#endif + if (r == illegal_import_runes[i]) { + return false; + } + } + + curr += width; + index += 1; + } + + return true; + } + return false; +} + bool is_package_name_reserved(String const &name) { if (name == "builtin") { @@ -5263,6 +5302,22 @@ ParseFileError parse_packages(Parser *p, String init_filename) { try_add_import_path(p, init_fullpath, init_fullpath, init_pos, Package_Init); p->init_fullpath = init_fullpath; + for_array(i, build_context.extra_packages) { + String path = build_context.extra_packages[i]; + String fullpath = path_to_full_path(heap_allocator(), path); // LEAK? + if (!path_is_directory(fullpath)) { + String const ext = str_lit(".odin"); + if (!string_ends_with(fullpath, ext)) { + error_line("Expected either a directory or a .odin file, got '%.*s'\n", LIT(fullpath)); + return ParseFile_WrongExtension; + } + } + AstPackage *pkg = try_add_import_path(p, fullpath, fullpath, init_pos, Package_Normal); + if (pkg) { + pkg->is_extra = true; + } + } + thread_pool_start(&parser_thread_pool); thread_pool_wait_to_process(&parser_thread_pool); diff --git a/src/parser.hpp b/src/parser.hpp index 48af0b293..aa288304e 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -150,6 +150,7 @@ struct AstPackage { Scope * scope; DeclInfo *decl_info; bool used; + bool is_extra; }; -- cgit v1.2.3 From b6bbe29c8f8f9223272f69346e729df4910734f4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 4 Dec 2020 16:04:58 +0000 Subject: Remove `const` as a (reserved) keyword --- src/parser.cpp | 5 ++--- src/tokenizer.cpp | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index ec38dca9b..a70627ed9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3259,11 +3259,10 @@ FieldPrefixKind is_token_field_prefix(AstFile *f) { return FieldPrefix_no_alias; } else if (f->curr_token.string == "c_vararg") { return FieldPrefix_c_var_arg; + } else if (f->curr_token.string == "const") { + return FieldPrefix_const; } break; - - case Token_const: - return FieldPrefix_const; } return FieldPrefix_Unknown; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index d89ec43b5..afa6e793a 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -119,7 +119,6 @@ TOKEN_KIND(Token__KeywordBegin, ""), \ TOKEN_KIND(Token_context, "context"), \ TOKEN_KIND(Token_asm, "asm"), \ TOKEN_KIND(Token_macro, "macro"), \ - TOKEN_KIND(Token_const, "const"), \ TOKEN_KIND(Token__KeywordEnd, ""), \ TOKEN_KIND(Token_Count, "") -- cgit v1.2.3 From c4cb7170ee14c6ebcf0d63efe73510aecb4c69d9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 4 Dec 2020 16:13:05 +0000 Subject: Deprecate keyword `opaque` in favour of `#opaque` --- src/parser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index a70627ed9..8a7819abd 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1833,12 +1833,18 @@ Ast *parse_operand(AstFile *f, bool lhs) { case Token_opaque: { Token token = expect_token(f, Token_opaque); + warning(token, "opaque is deprecated, please use #opaque"); Ast *type = parse_type(f); return ast_opaque_type(f, token, type); } case Token_Hash: { Token token = expect_token(f, Token_Hash); + if (allow_token(f, Token_opaque)) { + Ast *type = parse_type(f); + return ast_opaque_type(f, token, type); + } + Token name = expect_token(f, Token_Ident); if (name.string == "type") { return ast_helper_type(f, token, parse_type(f)); -- cgit v1.2.3