#if defined(GB_SYSTEM_WINDOWS) #pragma warning(push) #pragma warning(disable: 4200) #pragma warning(disable: 4201) #define restrict gb_restrict #endif #include "tilde/tb.h" #define TB_TYPE_F16 TB_DataType{ { TB_INT, 0, 16 } } #define TB_TYPE_I128 TB_DataType{ { TB_INT, 0, 128 } } #define TB_TYPE_INT TB_TYPE_INTN(cast(u16)(8*build_context.int_size)) #define TB_TYPE_INTPTR TB_TYPE_INTN(cast(u16)(8*build_context.ptr_size)) #if defined(GB_SYSTEM_WINDOWS) #pragma warning(pop) #endif #define CG_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime" #define CG_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime" #define CG_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info" #define CG_TYPE_INFO_DATA_NAME "__$type_info_data" #define CG_TYPE_INFO_TYPES_NAME "__$type_info_types_data" #define CG_TYPE_INFO_NAMES_NAME "__$type_info_names_data" #define CG_TYPE_INFO_OFFSETS_NAME "__$type_info_offsets_data" #define CG_TYPE_INFO_USINGS_NAME "__$type_info_usings_data" #define CG_TYPE_INFO_TAGS_NAME "__$type_info_tags_data" struct cgModule; enum cgValueKind : u32 { cgValue_Value, // rvalue cgValue_Addr, // lvalue cgValue_Symbol, // global cgValue_Multi, // multiple values }; struct cgValueMulti; struct cgValue { cgValueKind kind; Type * type; union { // NOTE: any value in this union must be a pointer TB_Symbol * symbol; TB_Node * node; cgValueMulti *multi; }; }; struct cgValueMulti { Slice values; }; enum cgAddrKind { cgAddr_Default, cgAddr_Map, cgAddr_Context, cgAddr_SoaVariable, cgAddr_RelativePointer, cgAddr_RelativeSlice, cgAddr_Swizzle, cgAddr_SwizzleLarge, }; struct cgAddr { cgAddrKind kind; cgValue addr; union { struct { cgValue key; Type *type; Type *result; } map; struct { Selection sel; } ctx; struct { cgValue index; Ast *index_expr; } soa; struct { cgValue index; Ast *node; } index_set; struct { bool deref; } relative; struct { Type *type; u8 count; // 2, 3, or 4 components u8 indices[4]; } swizzle; struct { Type *type; Slice indices; } swizzle_large; }; }; struct cgTargetList { cgTargetList *prev; bool is_block; // control regions TB_Node * break_; TB_Node * continue_; TB_Node * fallthrough_; }; struct cgBranchRegions { Ast * label; TB_Node *break_; TB_Node *continue_; }; enum cgDeferExitKind { cgDeferExit_Default, cgDeferExit_Return, cgDeferExit_Branch, }; enum cgDeferKind { cgDefer_Node, cgDefer_Proc, }; struct cgDefer { cgDeferKind kind; isize scope_index; isize context_stack_count; TB_Node * control_region; union { Ast *stmt; struct { cgValue deferred; Slice result_as_args; } proc; }; }; struct cgContextData { cgAddr ctx; isize scope_index; isize uses; }; struct cgControlRegion { TB_Node *control_region; isize scope_index; }; struct cgProcedure { u32 flags; u16 state_flags; cgProcedure *parent; Array children; TB_Function *func; TB_FunctionPrototype *proto; TB_Symbol *symbol; Entity * entity; cgModule *module; String name; Type * type; Ast * type_expr; Ast * body; u64 tags; ProcInlining inlining; bool is_foreign; bool is_export; bool is_entry_point; bool is_startup; TB_DebugType *debug_type; cgValue value; Ast *curr_stmt; cgTargetList * target_list; Array defer_stack; Array scope_stack; Array context_stack; Array control_regions; Array branch_regions; Scope *curr_scope; i32 scope_index; bool in_multi_assignment; isize split_returns_index; bool return_by_ptr; PtrMap variable_map; }; struct cgModule { TB_Module * mod; Checker * checker; CheckerInfo *info; LinkerData * linker_data; RwMutex values_mutex; PtrMap values; StringMap members; StringMap procedures; PtrMap procedure_values; Array procedures_to_generate; RecursiveMutex debug_type_mutex; PtrMap debug_type_map; PtrMap proc_debug_type_map; // not pointer to RecursiveMutex proc_proto_mutex; PtrMap proc_proto_map; PtrMap file_id_map; // Key: AstFile.id (i32 cast to uintptr) std::atomic nested_type_name_guid; std::atomic const_nil_guid; }; #ifndef ABI_PKG_NAME_SEPARATOR #define ABI_PKG_NAME_SEPARATOR "@" #endif gb_global Entity *cg_global_type_info_data_entity = {}; gb_global cgAddr cg_global_type_info_member_types = {}; gb_global cgAddr cg_global_type_info_member_names = {}; gb_global cgAddr cg_global_type_info_member_offsets = {}; gb_global cgAddr cg_global_type_info_member_usings = {}; gb_global cgAddr cg_global_type_info_member_tags = {}; gb_global isize cg_global_type_info_data_index = 0; gb_global isize cg_global_type_info_member_types_index = 0; gb_global isize cg_global_type_info_member_names_index = 0; gb_global isize cg_global_type_info_member_offsets_index = 0; gb_global isize cg_global_type_info_member_usings_index = 0; gb_global isize cg_global_type_info_member_tags_index = 0; gb_internal TB_Arena *cg_arena(void); gb_internal cgValue cg_value(TB_Global * g, Type *type); gb_internal cgValue cg_value(TB_External *e, Type *type); gb_internal cgValue cg_value(TB_Function *f, Type *type); gb_internal cgValue cg_value(TB_Symbol * s, Type *type); gb_internal cgValue cg_value(TB_Node * node, Type *type); gb_internal cgAddr cg_addr(cgValue const &value); gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const &value); gb_internal cgValue cg_const_nil(cgProcedure *p, Type *type); gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value); gb_internal void cg_build_stmt(cgProcedure *p, Ast *stmt); gb_internal void cg_build_stmt_list(cgProcedure *p, Slice const &stmts); gb_internal void cg_build_when_stmt(cgProcedure *p, AstWhenStmt *ws); gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr); gb_internal cgAddr cg_build_addr(cgProcedure *p, Ast *expr); gb_internal cgValue cg_build_addr_ptr(cgProcedure *p, Ast *expr); gb_internal cgValue cg_build_cond(cgProcedure *p, Ast *cond, TB_Node *true_block, TB_Node *false_block); gb_internal Type * cg_addr_type(cgAddr const &addr); gb_internal cgValue cg_addr_load(cgProcedure *p, cgAddr addr); gb_internal void cg_addr_store(cgProcedure *p, cgAddr addr, cgValue value); gb_internal cgValue cg_addr_get_ptr(cgProcedure *p, cgAddr const &addr); gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_volatile=false); gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue src, bool is_volatile=false); gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero_init); gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgValue value); gb_internal cgValue cg_copy_value_to_ptr(cgProcedure *p, cgValue value, Type *original_type, isize min_alignment); gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr); gb_internal void cg_build_return_stmt(cgProcedure *p, Slice const &return_results); gb_internal void cg_build_return_stmt_internal(cgProcedure *p, Slice const &results); gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e); gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type); gb_internal String cg_get_entity_name(cgModule *m, Entity *e); gb_internal cgValue cg_typeid(cgProcedure *m, Type *t); gb_internal cgValue cg_emit_ptr_offset(cgProcedure *p, cgValue ptr, cgValue index); gb_internal cgValue cg_emit_array_ep(cgProcedure *p, cgValue s, cgValue index); gb_internal cgValue cg_emit_array_epi(cgProcedure *p, cgValue s, i64 index); gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index); gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection const &sel); gb_internal cgValue cg_emit_struct_ev(cgProcedure *p, cgValue s, i64 index); gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *t); gb_internal cgValue cg_emit_comp_against_nil(cgProcedure *p, TokenKind op_kind, cgValue x); gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left, cgValue right); gb_internal cgValue cg_emit_arith(cgProcedure *p, TokenKind op, cgValue lhs, cgValue rhs, Type *type); gb_internal bool cg_emit_goto(cgProcedure *p, TB_Node *control_region); gb_internal TB_Node *cg_control_region(cgProcedure *p, char const *name); gb_internal isize cg_append_tuple_values(cgProcedure *p, Array *dst_values, cgValue src_value); gb_internal cgValue cg_handle_param_value(cgProcedure *p, Type *parameter_type, ParameterValue const ¶m_value, TokenPos const &pos); gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value); gb_internal cgValue cg_builtin_raw_data(cgProcedure *p, cgValue const &x);