Skip to content

v.gen.c

Constants #

const reset_dbg_line = '#line 999999999'

fn fix_reset_dbg_line #

fn fix_reset_dbg_line(src strings.Builder, out_file string) strings.Builder

fn gen #

fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenOutput

fn get_guarded_include_text #

fn get_guarded_include_text(iname string, imessage string) string

get_guarded_include_text returns C preprocessor code that includes iname when available, or emits imessage through a C error otherwise.

fn get_inttypes_or_stdint_include_text #

fn get_inttypes_or_stdint_include_text(imessage string) string

get_inttypes_or_stdint_include_text returns C preprocessor code that includes the best available integer types header, or emits imessage otherwise.

fn AssertMetainfoKind.from #

fn AssertMetainfoKind.from[W](input W) !AssertMetainfoKind

fn CWideIndexKind.from #

fn CWideIndexKind.from[W](input W) !CWideIndexKind

fn SpawnGoMode.from #

fn SpawnGoMode.from[W](input W) !SpawnGoMode

fn SqlExprSide.from #

fn SqlExprSide.from[W](input W) !SqlExprSide

struct Gen #

struct Gen {
	pref                &pref.Preferences = unsafe { nil }
	field_data_type     ast.Type // cache her to avoid map lookups
	enum_data_type      ast.Type // cache her to avoid map lookups
	variant_data_type   ast.Type // cache her to avoid map lookups
	module_built        string
	timers_should_print bool
mut:
	out        strings.Builder
	extern_out strings.Builder // extern declarations for -parallel-cc
	// line_nr                   int
	cheaders                             strings.Builder
	preincludes                          strings.Builder // allows includes to go before `definitions`
	postincludes                         strings.Builder // allows includes to go after all the rest of the code generation
	includes                             strings.Builder // all C #includes required by V modules
	typedefs                             strings.Builder
	enum_typedefs                        strings.Builder // enum types
	definitions                          strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
	type_definitions                     strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
	sort_fn_definitions                  strings.Builder // sort fns
	alias_definitions                    strings.Builder // alias fixed array of non-builtin
	hotcode_definitions                  strings.Builder // -live declarations & functions
	channel_definitions                  strings.Builder // channel related code
	thread_definitions                   strings.Builder // thread defines
	comptime_definitions                 strings.Builder // custom defines, given by -d/-define flags on the CLI
	type_default_vars                    strings.Builder // type_default() var declarations
	cleanup                              strings.Builder
	cleanups                             map[string]strings.Builder // contents of `void _vcleanup(){}`
	gowrappers                           strings.Builder            // all go callsite wrappers
	waiter_fn_definitions                strings.Builder            // waiter fns definitions
	auto_str_funcs                       strings.Builder            // function bodies of all auto generated _str funcs
	dump_funcs                           strings.Builder            // function bodies of all auto generated _str funcs
	pcs_declarations                     strings.Builder            // -prof profile counter declarations for each function
	cov_declarations                     strings.Builder            // -cov coverage
	embedded_data                        strings.Builder            // data to embed in the executable/binary
	shared_types                         strings.Builder            // shared/lock types
	shared_functions                     strings.Builder            // shared constructors
	out_options_forward                  strings.Builder            // forward `option_xxxx` types
	out_options                          strings.Builder            // `option_xxxx` types
	out_results_forward                  strings.Builder            // forward`result_xxxx` types
	out_results                          strings.Builder            // `result_xxxx` types
	json_forward_decls                   strings.Builder            // json type forward decls
	sql_buf                              strings.Builder            // for writing exprs to args via `sqlite3_bind_int()` etc
	global_const_defs                    map[string]GlobalConstDef
	vsafe_arithmetic_ops                 map[string]VSafeArithmeticOp // 'VSAFE_DIV_u8' -> {11, /}, 'VSAFE_MOD_u8' -> {11,%}, 'VSAFE_MOD_i64' -> the same but with 9
	sorted_global_const_names            []string
	file                                 &ast.File  = unsafe { nil }
	table                                &ast.Table = unsafe { nil }
	mods_with_c_includes                 map[string]bool
	styp_cache                           map[ast.Type]string
	no_eq_method_types                   map[ast.Type]bool // types that does not need to call its auto eq methods for optimization
	generic_parts_cache                  []i8              // type idx -> 0 unknown, 1 false, 2 true
	unwrap_generic_cache                 map[u64]ast.Type
	resolved_scope_var_type_cache        map[u64]ast.Type
	unique_file_path_hash                u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`)
	fn_decl                              &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0
	last_fn_c_name                       string
	tmp_count                            int  // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn.
	tmp_count_af                         int  // a separate tmp var counter for autofree fn calls
	tmp_count_declarations               int  // counter for unique tmp names (_d1, _d2 etc); does NOT reset, used for C declarations
	global_tmp_count                     int  // like tmp_count but global and not reset in each function
	discard_or_result                    bool // do not safe last ExprStmt of `or` block in tmp variable to defer ongoing expr usage
	is_direct_array_access               bool // inside a `[direct_array_access fn a() {}` function
	is_assign_lhs                        bool // inside left part of assign expr (for array_set(), etc)
	is_void_expr_stmt                    bool // ExprStmt whose result is discarded
	is_arraymap_set                      bool // map or array set value state
	is_amp                               bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&u8(unsafe { nil })` etc
	is_sql                               bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc)
	is_shared                            bool // for initialization of hidden mutex in `[rw]shared` literals
	is_vlines_enabled                    bool // is it safe to generate #line directives when -g is passed
	is_autofree                          bool // false, inside the bodies of fns marked with [manualfree], otherwise === g.pref.autofree
	is_autofree_tmp                      bool // when generating autofree temporary variables
	is_builtin_mod                       bool
	is_json_fn                           bool // inside json.encode()
	is_js_call                           bool // for handling a special type arg #1 `json.decode(User, ...)`
	is_fn_index_call                     bool
	is_cc_msvc                           bool // g.pref.ccompiler == 'msvc'
	is_option_auto_heap                  bool
	vlines_path                          string            // set to the proper path for generating #line directives
	options_pos_forward                  int               // insertion point to forward
	options_forward                      []string          // to forward
	options                              map[string]string // to avoid duplicates
	results_forward                      []string          // to forward
	results                              map[string]string // to avoid duplicates
	done_options                         shared []string   // to avoid duplicates
	done_results                         shared []string   // to avoid duplicates
	array_typedefs                       []string          // to avoid duplicate array typedefs
	written_array_typedefs               int
	done_typedef_phase                   bool              // set after write_typedef_types() completes
	late_chan_types                      shared []string   // concrete channel cnames discovered during file generation
	emitted_chan_types                   map[string]bool   // concrete channel typedefs/helpers already emitted
	c_extern_signature_types             map[string]bool   // C signature-only type decls already emitted
	chan_pop_options                     map[string]string // types for `x := <-ch or {...}`
	chan_push_options                    map[string]string // types for `ch <- x or {...}`
	mtxs                                 string            // array of mutexes if the `lock` has multiple variables
	tmp_var_ptr                          map[string]bool   // indicates if the tmp var passed to or_block() is a ptr
	labeled_loops                        map[string]&ast.Stmt
	contains_ptr_cache                   map[ast.Type]bool
	boehm_keep_decl                      map[string]bool
	boehm_keep_gen                       map[string]bool
	boehm_keep_busy                      map[string]bool
	inner_loop                           &ast.Stmt = unsafe { nil }
	cur_indexexpr                        []int          // list of nested indexexpr which generates array_set/map_set
	shareds                              map[int]string // types with hidden mutex for which decl has been emitted
	coverage_files                       map[u64]&CoverageInfo
	inside_smartcast                     bool
	inside_ternary                       int  // ?: comma separated statements on a single line
	inside_map_postfix                   bool // inside map++/-- postfix expr
	inside_map_infix                     bool // inside map<</+=/-= infix expr
	inside_left_shift                    bool // generating the left operand of `<<`
	inside_assign                        bool
	inside_map_index                     bool
	inside_array_index                   bool
	inside_array_fixed_struct            bool
	inside_opt_or_res                    bool
	inside_opt_data                      bool
	inside_if_option                     bool
	inside_if_result                     bool
	inside_match_option                  bool
	inside_match_result                  bool
	inside_veb_tmpl                      bool
	inside_return                        bool
	inside_return_tmpl                   bool
	inside_struct_init                   bool
	inside_or_block                      bool
	inside_call                          bool
	inside_curry_call                    bool // inside foo()()!, foo()()?, foo()()
	inside_dump_fn                       bool
	inside_c_extern                      bool // inside `@[c_extern] fn C.somename(param1 int, param2 voidptr, param3 &char) &char`
	active_call_generic_names            []string
	active_call_concrete_types           []ast.Type
	expected_fixed_arr                   bool
	inside_for_c_stmt                    bool
	inside_cast_in_heap                  int // inside cast to interface type in heap (resolve recursive calls)
	inside_cast                          bool
	inside_sumtype_cast                  bool
	inside_selector                      bool
	inside_selector_lhs                  bool
	inside_selector_deref                bool // indicates if the inside selector was already dereferenced
	inside_memset                        bool
	inside_const                         bool
	inside_array_item                    bool
	inside_const_opt_or_res              bool
	inside_lambda                        bool
	inside_cinit                         bool
	inside_global_decl                   bool
	inside_interface_deref               bool
	inside_assign_fn_var                 bool
	outer_tmp_var                        string // tmp var from outer context (e.g. from stmts_with_tmp_var) to be used by nested if/match expressions
	last_tmp_call_var                    []string
	last_if_option_type                  ast.Type // stores the expected if type on nested if expr
	loop_depth                           int
	unsafe_level                         int
	ternary_names                        map[string]string
	ternary_level_names                  map[string][]string
	arraymap_set_pos                     int              // map or array set value position
	stmt_path_pos                        []int            // positions of each statement start, for inserting C statements before the current statement
	skip_stmt_pos                        bool             // for handling if expressions + autofree (since both prepend C statements)
	left_is_opt                          bool             // left hand side on assignment is an option
	right_is_opt                         bool             // right hand side on assignment is an option
	assign_ct_type                       map[int]ast.Type // left hand side resolved comptime type
	indent                               int
	empty_line                           bool
	assign_op                            token.Kind // *=, =, etc (for array_set)
	defer_stmts                          []ast.DeferStmt
	defer_ifdef                          string
	defer_profile_code                   string
	inside_defer_generation              bool
	defer_vars                           []string
	closure_structs                      []string
	str_types                            []StrType       // types that need automatic str() generation
	generated_str_fns                    []StrType       // types that already have a str() function
	str_fn_names                         shared []string // remove duplicate function names
	threaded_fns                         shared []string // for generating unique wrapper types and fns for `go xxx()`
	waiter_fns                           shared []string // functions that wait for `go xxx()` to finish
	needed_equality_fns                  []ast.Type
	generated_eq_fns                     []ast.Type
	needed_map_key_fns                   []ast.Type
	generated_map_key_fns                map[ast.Type]bool
	generated_array_interface_cast_fns   shared map[string]bool
	generated_array_interface_repeat_fns shared map[string]bool
	array_sort_fn                        shared []string
	array_sort_wrappers                  shared []string
	array_contains_types                 []ast.Type
	array_index_types                    []ast.Type
	array_last_index_types               []ast.Type
	array_get_types                      []ast.Type
	auto_fn_definitions                  []string // auto generated functions definition list
	sumtype_casting_fns                  []SumtypeCastingFn
	anon_fn_definitions                  []string        // anon generated functions definition list
	anon_fns                             shared []string // remove duplicate anon generated functions
	sumtype_definitions                  map[string]bool // `_TypeA_to_sumtype_TypeB()` fns that have been generated
	trace_fn_definitions                 []string
	json_types                           []ast.Type // to avoid json gen duplicates
	json_types_pos                       map[ast.Type]token.Pos
	json_gen_pos                         token.Pos
	pcs                                  []ProfileCounterMeta // -prof profile counter fn_names => fn counter name
	hotcode_fn_names                     []string
	hotcode_fpaths                       []string
	embedded_files                       []ast.EmbeddedFile
	sql_i                                int
	sql_stmt_name                        string
	sql_bind_name                        string
	sql_idents                           []string
	sql_idents_types                     []ast.Type
	sql_left_type                        ast.Type
	sql_table_name                       string
	sql_table_typ                        ast.Type // the table type, used for generic types lookup
	sql_fkey                             string
	sql_parent_id                        string
	sql_side                             SqlExprSide // left or right, to distinguish idents in `name == name`
	sql_last_stmt_out_len                int
	strs_to_free0                        []string // strings.Builder
	// strs_to_free          []string // strings.Builder
	// tmp_arg_vars_to_free  []string
	// autofree_pregen       map[string]string
	// autofree_pregen_buf   strings.Builder
	// autofree_tmp_vars     []string // to avoid redefining the same tmp vars in a single function
	// nr_vars_to_free       int
	// doing_autofree_tmp    bool
	type_resolver                    type_resolver.TypeResolver
	comptime                         &type_resolver.ResolverInfo = unsafe { nil }
	prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type
	// used in match multi branch
	// TypeOne, TypeTwo {}
	// where an aggregate (at least two types) is generated
	// sum type deref needs to know which index to deref because unions take care of the correct field
	aggregate_type_idx  int
	arg_no_auto_deref   bool            // smartcast must not be dereferenced
	branch_parent_pos   int             // used in BranchStmt (continue/break) for autofree stop position
	returned_var_names  map[string]bool // to detect that vars doesn't need to be freed since it's being returned
	infix_left_var_name string          // a && if expr
	curr_var_name       []string        // curr var name on assignment
	called_fn_name      string
	timers              &util.Timers = util.get_timers()
	force_main_console  bool // true when @[console] used on fn main()
	uses_power          bool
	uses_power_u64      bool
	as_cast_type_names  map[string]string // table for type name lookup in runtime (for __as_cast)
	obf_table           map[string]string
	referenced_fns      shared map[string]bool // functions that have been referenced
	nr_closures         int
	expected_cast_type  ast.Type // for match expr of sumtypes
	expected_arg_mut    bool     // generating a mutable fn parameter
	or_expr_return_type ast.Type // or { 0, 1 } return type
	anon_fn             &ast.AnonFn
	tests_inited        bool
	has_main            bool
	// main_fn_decl_node  ast.FnDecl
	cur_mod                 ast.Module
	cur_concrete_types      []ast.Type // do not use table.cur_concrete_types because table is global, so should not be accessed by different threads
	cur_fn                  &ast.FnDecl = unsafe { nil } // same here
	cur_lock                ast.LockExpr
	cur_struct_init_typ     ast.Type
	zero_struct_init_stack  []ast.Type
	autofree_methods        map[ast.Type]string
	generated_free_methods  map[ast.Type]bool
	generated_free_fn_names map[string]bool
	autofree_scope_stmts    []string
	use_segfault_handler    bool = true
	test_function_names     []string
	/////////
	// out_parallel []strings.Builder
	// out_idx      int
	out_fn_start_pos     []int  // for generating multiple .c files, stores locations of all fn positions in `out` string builder
	static_modifier      string // for parallel_cc
	static_non_parallel  string // for non -parallel_cc
	has_reflection       bool   // v.reflection has been imported
	has_debugger         bool   // $dbg has been used in the code
	reflection_strings   &map[string]int
	defer_return_tmp_var string
	veb_filter_fn_name   string   // veb__filter, used by $veb.html() for escaping strings in templates
	export_funcs         []string // for .dll export function names
	//
	type_default_impl_level int
	preinclude_nodes        []&ast.HashStmtNode // allows hash stmts to go before `includes`
	include_nodes           []&ast.HashStmtNode // all hash stmts to go `includes`
	definition_nodes        []&ast.HashStmtNode // allows hash stmts to go `definitions`
	postinclude_nodes       []&ast.HashStmtNode // allows hash stmts to go after all the rest of the code generation
	curr_comptime_node      ast.Expr = ast.empty_expr // current `$if` expr
	is_builtin_overflow_mod bool
	do_int_overflow_checks  bool // outside a `@[ignore_overflow] fn abc() {}` or a function in `builtin.overflow`
	//
	tid string // the thread id of the file processor in the thread pool (log it to debug issues in parallel cgen)
	fid int    // the index of ast.File that is currently processed (log it to debug issues in parallel cgen)
}

fn (Gen) contains_ptr #

fn (mut g Gen) contains_ptr(el_typ ast.Type) bool

returns true if t includes any pointer(s) - during garbage collection heap regions that contain no pointers do not have to be scanned

fn (Gen) current_tmp_var #

fn (mut g Gen) current_tmp_var() string

fn (Gen) filter_only_matching_fn_names #

fn (mut g Gen) filter_only_matching_fn_names(fnames []string) []string

fn (Gen) finish #

fn (mut g Gen) finish()

fn (Gen) free_builders #

unsafe
fn (mut g Gen) free_builders()

free_builders should be called only when a Gen would NOT be used anymore it frees the bulk of the memory that is private to the Gen instance (the various string builders)

fn (Gen) gen_c_android_sokol_main #

fn (mut g Gen) gen_c_android_sokol_main()

fn (Gen) gen_c_main #

fn (mut g Gen) gen_c_main()

fn (Gen) gen_c_main_for_tests #

fn (mut g Gen) gen_c_main_for_tests()

fn (Gen) gen_c_main_profile_hook #

fn (mut g Gen) gen_c_main_profile_hook()

fn (Gen) gen_c_main_trace_calls_hook #

fn (mut g Gen) gen_c_main_trace_calls_hook()

fn (Gen) gen_dll_main #

fn (mut g Gen) gen_dll_main()

gen_dll_main create DllMain() for windows .dll.

fn (Gen) gen_failing_error_propagation_for_test_fn #

fn (mut g Gen) gen_failing_error_propagation_for_test_fn(or_block ast.OrExpr, cvar_name string)

fn (Gen) gen_failing_return_error_for_test_fn #

fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return, cvar_name string)

fn (Gen) gen_file #

fn (mut g Gen) gen_file()

fn (Gen) gen_vprint_profile_stats #

fn (mut g Gen) gen_vprint_profile_stats()

fn (Gen) get_array_depth #

fn (mut g Gen) get_array_depth(el_typ ast.Type) int

fn (Gen) get_sumtype_casting_variant_name #

fn (mut g Gen) get_sumtype_casting_variant_name(typ ast.Type, sym ast.TypeSymbol) string

get_sumtype_casting_variant_name returns a helper-safe variant name that keeps pointer-depth distinctions for sumtype cast wrappers.

fn (Gen) get_sumtype_variant_name #

fn (mut g Gen) get_sumtype_variant_name(typ ast.Type, sym ast.TypeSymbol) string

get_sumtype_variant_name returns the variant name according to its type

fn (Gen) get_sumtype_variant_type_name #

fn (mut g Gen) get_sumtype_variant_type_name(typ ast.Type, sym ast.TypeSymbol) string

get_sumtype_variant_type_name returns the variant type name according to its type

fn (Gen) hashes #

fn (g &Gen) hashes() string

fn (Gen) init #

fn (mut g Gen) init()

fn (Gen) new_global_tmp_var #

fn (mut g Gen) new_global_tmp_var() string

fn (Gen) new_tmp_var #

fn (mut g Gen) new_tmp_var() string

fn (Gen) reset_tmp_count #

fn (mut g Gen) reset_tmp_count() int

fn (Gen) ret_styp #

fn (mut g Gen) ret_styp(typ ast.Type) string

ret_type generates proper type name for return type context

fn (Gen) write_alias_typesymbol_declaration #

fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol)

fn (Gen) write_array_fixed_return_types #

fn (mut g Gen) write_array_fixed_return_types()

fn (Gen) write_fn_typesymbol_declaration #

fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol)

fn (Gen) write_interface_typedef #

fn (mut g Gen) write_interface_typedef(sym ast.TypeSymbol)

fn (Gen) write_interface_typesymbol_declaration #

fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol)

fn (Gen) write_multi_return_types #

fn (mut g Gen) write_multi_return_types()

fn (Gen) write_tests_definitions #

fn (mut g Gen) write_tests_definitions()

fn (Gen) write_typedef_types #

fn (mut g Gen) write_typedef_types()

fn (Gen) write_typeof_functions #

fn (mut g Gen) write_typeof_functions()

struct GenOutput #

@[heap]
struct GenOutput {
pub:
	header           string          // produced output for out.h (-parallel-cc)
	res_builder      strings.Builder // produced output (complete)
	out_str          string          // produced output from g.out
	out0_str         string          // helpers output (auto fns, dump fns) for out_0.c (-parallel-cc)
	extern_str       string          // extern chunk for (-parallel-cc)
	out_fn_start_pos []int           // fn decl positions
}

struct ProfileCounterMeta #

struct ProfileCounterMeta {
	fn_name   string
	vpc_name  string
	vpc_calls string
}

struct TraceLastLinesParams #

@[params]
struct TraceLastLinesParams {
pub:
	nlines int = 2
	msg    string
}