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

fn get_inttypes_or_stdint_include_text #

fn get_inttypes_or_stdint_include_text(imessage string) string

fn AssertMetainfoKind.from #

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

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 }
	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
	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
	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
	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_vweb_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
	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
	generated_array_interface_cast_fns shared map[string]bool
	array_sort_fn                      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[u32]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()
	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
	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
	vweb_filter_fn_name  string   // vweb__filter or x__vweb__filter, used by $vweb.html() for escaping strings in the templates, depending on which `vweb` import is used
	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_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
}