From 71e8a3f82ba6bfdca6a163fcc2136c85c0c8c451 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Mon, 16 Oct 2023 13:59:12 +0300 Subject: [PATCH] checker, builder, pref: support `-dump-defines -` to help explore all the available user and system defines for a given program (#19576) --- vlib/v/builder/builder.v | 3 +++ vlib/v/builder/dump_lists.v | 11 +++++++++++ vlib/v/checker/checker.v | 2 ++ vlib/v/checker/comptime.v | 18 ++++++++++++++++++ vlib/v/help/build/build-c.txt | 11 +++++++++++ vlib/v/pref/pref.v | 7 ++++++- 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index c0756d79e..6ddc7bda0 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -149,6 +149,9 @@ pub fn (mut b Builder) middle_stages() ! { if b.pref.show_callgraph { callgraph.show(mut b.table, b.pref, b.parsed_files) } + if b.pref.dump_defines != '' { + b.dump_defines() + } } pub fn (mut b Builder) front_and_middle_stages(v_files []string) ! { diff --git a/vlib/v/builder/dump_lists.v b/vlib/v/builder/dump_lists.v index 26c81568c..c2612a65a 100644 --- a/vlib/v/builder/dump_lists.v +++ b/vlib/v/builder/dump_lists.v @@ -24,3 +24,14 @@ fn dump_list(file_path string, list []string) { } } } + +pub fn (b &Builder) dump_defines() { + mut res := []string{} + for k, v in b.checker.ct_system_defines { + res << 'system,${k},${v}' + } + for k, v in b.checker.ct_user_defines { + res << 'user,${k},${v}' + } + dump_list(b.pref.dump_defines, res) +} diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 65017d922..cf4366ca7 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -93,6 +93,8 @@ pub mut: smartcast_mut_pos token.Pos // match mut foo, if mut foo is Foo smartcast_cond_pos token.Pos // match cond ct_cond_stack []ast.Expr + ct_user_defines map[string]ComptimeBranchSkipState + ct_system_defines map[string]ComptimeBranchSkipState mut: stmt_level int // the nesting level inside each stmts list; // .stmt_level is used to check for `evaluated but not used` ExprStmts like `1 << 1` diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index cefc2c198..fb1a98d1e 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -621,6 +621,18 @@ enum ComptimeBranchSkipState { // comptime_if_branch checks the condition of a compile-time `if` branch. It returns `true` // if that branch's contents should be skipped (targets a different os for example) fn (mut c Checker) comptime_if_branch(mut cond ast.Expr, pos token.Pos) ComptimeBranchSkipState { + mut should_record_ident := false + mut is_user_ident := false + mut ident_name := '' + defer { + if should_record_ident { + if is_user_ident { + c.ct_user_defines[ident_name] = $res() + } else { + c.ct_system_defines[ident_name] = $res() + } + } + } // TODO: better error messages here match mut cond { ast.BoolLiteral { @@ -646,6 +658,9 @@ fn (mut c Checker) comptime_if_branch(mut cond ast.Expr, pos token.Pos) Comptime if cond.op != .question { c.error('invalid \$if postfix operator', cond.pos) } else if mut cond.expr is ast.Ident { + should_record_ident = true + is_user_ident = true + ident_name = cond.expr.name return if cond.expr.name in c.pref.compile_defines_all { .eval } else { .skip } } else { c.error('invalid `\$if` condition', cond.pos) @@ -779,6 +794,9 @@ fn (mut c Checker) comptime_if_branch(mut cond ast.Expr, pos token.Pos) Comptime } ast.Ident { cname := cond.name + should_record_ident = true + is_user_ident = false + ident_name = cname if cname in ast.valid_comptime_if_os { mut is_os_target_equal := true if !c.pref.output_cross_c { diff --git a/vlib/v/help/build/build-c.txt b/vlib/v/help/build/build-c.txt index ad91dda89..858680bf9 100644 --- a/vlib/v/help/build/build-c.txt +++ b/vlib/v/help/build/build-c.txt @@ -278,6 +278,17 @@ see also `v help build`. Write all used V file paths used by the program in `file.txt`, one module per line. If `file.txt` is `-`, write to stdout instead. + -dump-defines file.txt + Write all system and user defines, that V knows about for the current program, one per line. + If `file.txt` is `-`, write to stdout instead. + Example sample of the content of that file: + system,linux,eval + system,amd64,eval + system,solaris,skip + system,solaris,skip + user,gcboehm,eval + user,gg_record_trace,skip + -no-rsp By default, V passes all C compiler options to the backend C compiler in so called "response files" (https://gcc.gnu.org/wiki/Response_Files). diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 82daad5cd..eea92d608 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -151,8 +151,9 @@ pub mut: show_callgraph bool // -show-callgraph, print the program callgraph, in a Graphviz DOT format to stdout show_depgraph bool // -show-depgraph, print the program module dependency graph, in a Graphviz DOT format to stdout dump_c_flags string // `-dump-c-flags file.txt` - let V store all C flags, passed to the backend C compiler in `file.txt`, one C flag/value per line. - dump_modules string // `-dump-modules modules.txt` - let V store all V modules, that were used by the compiled program in `modules.txt`, one module per line. + dump_modules string // `-dump-modules modules.txt` - let V store all V modules, that were used by the compiled program in `modules.txt`, one module per line. dump_files string // `-dump-files files.txt` - let V store all V or .template file paths, that were used by the compiled program in `files.txt`, one path per line. + dump_defines string // `-dump-defines defines.txt` - let V store all the defines that affect the current program and their values, one define per line + `,` + its value. use_cache bool // when set, use cached modules to speed up subsequent compilations, at the cost of slower initial ones (while the modules are cached) retry_compilation bool = true // retry the compilation with another C compiler, if tcc fails. use_os_system_to_run bool // when set, use os.system() to run the produced executable, instead of os.new_process; works around segfaults on macos, that may happen when xcode is updated @@ -671,6 +672,10 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin res.dump_files = cmdline.option(current_args, arg, '-') i++ } + '-dump-defines' { + res.dump_defines = cmdline.option(current_args, arg, '-') + i++ + } '-experimental' { res.experimental = true } -- 2.39.5