checker,cgen: fix `-os cross` support for `$if !solaris { #include <sys/ptrace.h> }`

pull/10932/head
Delyan Angelov 2021-07-23 15:30:51 +03:00
parent c797e1460d
commit 6313ed6a79
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
8 changed files with 68 additions and 10 deletions

View File

@ -874,7 +874,7 @@ pub mut:
scope &Scope scope &Scope
} }
// #include etc // #include, #define etc
pub struct HashStmt { pub struct HashStmt {
pub: pub:
mod string mod string
@ -885,6 +885,8 @@ pub mut:
kind string // : 'include' kind string // : 'include'
main string // : '<openssl/rand.h>' main string // : '<openssl/rand.h>'
msg string // : 'please install openssl' 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
} }
/* /*

View File

@ -78,6 +78,7 @@ pub mut:
inside_ct_attr bool // true inside [if expr] inside_ct_attr bool // true inside [if expr]
skip_flags bool // should `#flag` and `#include` be skipped 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: mut:
files []ast.File files []ast.File
expr_level int // to avoid infinite recursion segfaults due to compiler bugs 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 { if c.skip_flags {
return return
} }
if c.ct_cond_stack.len > 0 {
node.ct_conds = c.ct_cond_stack.clone()
}
if c.pref.backend.is_js() { if c.pref.backend.is_js() {
if !c.file.path.ends_with('.js.v') { if !c.file.path.ends_with('.js.v') {
c.error('hash statements are only allowed in backend specific files such "x.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 // statements, in `-os cross` mode
found_branch = false found_branch = false
c.skip_flags = false c.skip_flags = false
c.ct_cond_stack << branch.cond
} }
if !c.skip_flags { if !c.skip_flags {
c.stmts(branch.stmts) 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.comptime_fields_type.delete(comptime_field_name)
} }
c.skip_flags = cur_skip_flags 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 { } else {
// smartcast sumtypes and interfaces when using `is` // smartcast sumtypes and interfaces when using `is`
c.smartcast_if_conds(branch.cond, mut branch.scope) c.smartcast_if_conds(branch.cond, mut branch.scope)

View File

@ -1358,6 +1358,19 @@ fn (mut g Gen) stmt(node ast.Stmt) {
g.writeln('goto $node.name;') g.writeln('goto $node.name;')
} }
ast.HashStmt { 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 // #include etc
if node.kind == 'include' { if node.kind == 'include' {
mut missing_message := 'Header file $node.main, needed for module `$node.mod` was not found.' 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' guarded_include = '#include $node.main'
} }
if node.main.contains('.m') { 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 // Objective C code import, include it after V types, so that e.g. `string` is
// available there // available there
g.definitions.writeln('// added by module `$node.mod`:') g.definitions.writeln('// added by module `$node.mod`')
g.definitions.writeln(guarded_include) g.definitions.writeln(guarded_include)
if ct_condition.len > 0 {
g.definitions.writeln('#endif // \$if $ct_condition')
}
g.definitions.writeln('\n')
} else { } 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) 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' { } 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') g.includes.writeln('#define $node.main')
if ct_condition.len > 0 {
g.includes.writeln('#endif // \$if $ct_condition')
}
} }
} }
ast.Import {} ast.Import {}

View File

@ -0,0 +1 @@
char *version = "linux";

View File

@ -0,0 +1 @@
char *version = "non-linux";

View File

@ -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)
}