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

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`
	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
	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(0)` 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_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
	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
	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<
	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`
	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_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
	last_tmp_call_var         []string
	loop_depth                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            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
	array_sort_fn             shared []string
	array_contains_types      []ast.Type
	array_index_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[int]bool    // `_TypeA_to_sumtype_TypeB()` fns that have been generated
	trace_fn_definitions      []string
	json_types                []ast.Type           // to avoid json gen duplicates
	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_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
	comptime_info_stack              []comptime.ComptimeInfo // stores the values from the above on each $for loop, to make nesting them easier
	comptime                         comptime.ComptimeInfo
	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_name   string   // to detect that a var 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
	or_expr_return_type ast.Type // or { 0, 1 } return type
	anon_fn             bool
	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
	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
}

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_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_declaration_name #

fn (mut g Gen) new_tmp_declaration_name() 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()

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
}