checker,cgen: fix `-os cross` support for `$if !solaris { #include <sys/ptrace.h> }`
parent
c797e1460d
commit
6313ed6a79
|
@ -874,17 +874,19 @@ pub mut:
|
|||
scope &Scope
|
||||
}
|
||||
|
||||
// #include etc
|
||||
// #include, #define etc
|
||||
pub struct HashStmt {
|
||||
pub:
|
||||
mod string
|
||||
pos token.Position
|
||||
source_file string
|
||||
pub mut:
|
||||
val string // example: 'include <openssl/rand.h> # please install openssl // comment'
|
||||
kind string // : 'include'
|
||||
main string // : '<openssl/rand.h>'
|
||||
msg string // : 'please install openssl'
|
||||
val string // example: 'include <openssl/rand.h> # please install openssl // comment'
|
||||
kind string // : 'include'
|
||||
main string // : '<openssl/rand.h>'
|
||||
msg string // : 'please install openssl'
|
||||
ct_conds []Expr // *all* comptime conditions, that must be true, for the hash to be processed
|
||||
// ct_conds is filled by the checker, based on the current nesting of `$if cond1 {}` blocks
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -77,7 +77,8 @@ pub mut:
|
|||
inside_fn_arg bool // `a`, `b` in `a.f(b)`
|
||||
inside_ct_attr bool // true inside [if expr]
|
||||
skip_flags bool // should `#flag` and `#include` be skipped
|
||||
fn_level int // 0 for the top level, 1 for `fn abc() {}`, 2 for a nested fn, etc
|
||||
fn_level int // 0 for the top level, 1 for `fn abc() {}`, 2 for a nested fn, etc
|
||||
ct_cond_stack []ast.Expr
|
||||
mut:
|
||||
files []ast.File
|
||||
expr_level int // to avoid infinite recursion segfaults due to compiler bugs
|
||||
|
@ -4908,6 +4909,9 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
|||
if c.skip_flags {
|
||||
return
|
||||
}
|
||||
if c.ct_cond_stack.len > 0 {
|
||||
node.ct_conds = c.ct_cond_stack.clone()
|
||||
}
|
||||
if c.pref.backend.is_js() {
|
||||
if !c.file.path.ends_with('.js.v') {
|
||||
c.error('hash statements are only allowed in backend specific files such "x.js.v"',
|
||||
|
@ -6551,6 +6555,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
|||
// statements, in `-os cross` mode
|
||||
found_branch = false
|
||||
c.skip_flags = false
|
||||
c.ct_cond_stack << branch.cond
|
||||
}
|
||||
if !c.skip_flags {
|
||||
c.stmts(branch.stmts)
|
||||
|
@ -6573,6 +6578,9 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
|||
c.comptime_fields_type.delete(comptime_field_name)
|
||||
}
|
||||
c.skip_flags = cur_skip_flags
|
||||
if c.fn_level == 0 && c.pref.output_cross_c && c.ct_cond_stack.len > 0 {
|
||||
c.ct_cond_stack.pop()
|
||||
}
|
||||
} else {
|
||||
// smartcast sumtypes and interfaces when using `is`
|
||||
c.smartcast_if_conds(branch.cond, mut branch.scope)
|
||||
|
|
|
@ -1358,6 +1358,19 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
g.writeln('goto $node.name;')
|
||||
}
|
||||
ast.HashStmt {
|
||||
mut ct_condition := ''
|
||||
if node.ct_conds.len > 0 {
|
||||
ct_condition_start := g.out.len
|
||||
for idx, ct_expr in node.ct_conds {
|
||||
g.comp_if_cond(ct_expr, false)
|
||||
if idx < node.ct_conds.len - 1 {
|
||||
g.write(' && ')
|
||||
}
|
||||
}
|
||||
ct_condition = g.out.cut_to(ct_condition_start).trim_space()
|
||||
// dump(node)
|
||||
// dump(ct_condition)
|
||||
}
|
||||
// #include etc
|
||||
if node.kind == 'include' {
|
||||
mut missing_message := 'Header file $node.main, needed for module `$node.mod` was not found.'
|
||||
|
@ -1372,17 +1385,39 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
guarded_include = '#include $node.main'
|
||||
}
|
||||
if node.main.contains('.m') {
|
||||
g.definitions.writeln('\n')
|
||||
if ct_condition.len > 0 {
|
||||
g.definitions.writeln('#if $ct_condition')
|
||||
}
|
||||
// Objective C code import, include it after V types, so that e.g. `string` is
|
||||
// available there
|
||||
g.definitions.writeln('// added by module `$node.mod`:')
|
||||
g.definitions.writeln('// added by module `$node.mod`')
|
||||
g.definitions.writeln(guarded_include)
|
||||
if ct_condition.len > 0 {
|
||||
g.definitions.writeln('#endif // \$if $ct_condition')
|
||||
}
|
||||
g.definitions.writeln('\n')
|
||||
} else {
|
||||
g.includes.writeln('// added by module `$node.mod`:')
|
||||
g.includes.writeln('\n')
|
||||
if ct_condition.len > 0 {
|
||||
g.includes.writeln('#if $ct_condition')
|
||||
}
|
||||
g.includes.writeln('// added by module `$node.mod`')
|
||||
g.includes.writeln(guarded_include)
|
||||
if ct_condition.len > 0 {
|
||||
g.includes.writeln('#endif // \$if $ct_condition')
|
||||
}
|
||||
g.includes.writeln('\n')
|
||||
}
|
||||
} else if node.kind == 'define' {
|
||||
g.includes.writeln('// defined by module `$node.mod` in file `$node.source_file`:')
|
||||
if ct_condition.len > 0 {
|
||||
g.includes.writeln('#if $ct_condition')
|
||||
}
|
||||
g.includes.writeln('// defined by module `$node.mod`')
|
||||
g.includes.writeln('#define $node.main')
|
||||
if ct_condition.len > 0 {
|
||||
g.includes.writeln('#endif // \$if $ct_condition')
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.Import {}
|
||||
|
|
|
@ -154,7 +154,7 @@ pub mut:
|
|||
custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files
|
||||
lookup_path []string
|
||||
bare_builtin_dir string // Path to implementation of malloc, memset, etc. Only used if is_bare is true
|
||||
output_cross_c bool // true, when the user passed `-os cross`
|
||||
output_cross_c bool // true, when the user passed `-os cross`
|
||||
prealloc bool
|
||||
vroot string
|
||||
out_name_c string // full os.real_path to the generated .tmp.c file; set by builder.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
char *version = "linux";
|
|
@ -0,0 +1 @@
|
|||
char *version = "non-linux";
|
|
@ -0,0 +1,11 @@
|
|||
$if linux {
|
||||
#include "@VMODROOT/a_linux.h"
|
||||
}
|
||||
|
||||
$if !linux {
|
||||
#include "@VMODROOT/a_nonlinux.h"
|
||||
}
|
||||
|
||||
fn main() {
|
||||
C.printf(c'a: %s\n', C.version)
|
||||
}
|
Loading…
Reference in New Issue